## ----include = FALSE----------------------------------------------------------
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  fig.width = 7,
  fig.height = 5
)

## ----setup, echo=FALSE, message=FALSE-----------------------------------------
library(RandomWalker)
library(dplyr)
library(ggplot2)

## ----basic_syntax-------------------------------------------------------------

# 1D walk (default)
walk_1d <- random_normal_walk(.num_walks = 5, .n = 100, .dimensions = 1)

# 2D walk
walk_2d <- random_normal_walk(.num_walks = 5, .n = 100, .dimensions = 2)

# 3D walk
walk_3d <- random_normal_walk(.num_walks = 5, .n = 100, .dimensions = 3)

## ----distribution_examples, eval=FALSE----------------------------------------
# # 2D Brownian motion
# brownian_motion(.num_walks = 10, .n = 500, .dimensions = 2)
# 
# # 3D geometric Brownian motion
# geometric_brownian_motion(
#   .num_walks = 10,
#   .n = 500,
#   .initial_value = 100,
#   .dimensions = 3
# )
# 
# # 2D Cauchy walk (heavy tails)
# random_cauchy_walk(.num_walks = 10, .n = 200, .dimensions = 2)
# 
# # 3D exponential walk
# random_exponential_walk(.num_walks = 5, .n = 300, .dimensions = 3)

## ----inspect_data-------------------------------------------------------------
# 2D walk
walk_2d <- random_normal_walk(.num_walks = 3, .n = 100, .dimensions = 2)

# View structure
head(walk_2d, 10)
names(walk_2d)

# 3D walk
walk_3d <- random_normal_walk(.num_walks = 3, .n = 100, .dimensions = 3)

# View structure
head(walk_3d, 10)
names(walk_3d)

## ----basic_2d_plot, fig.alt="2D random walk trajectories showing multiple walks with start points marked as white circles and end points as red triangles"----

# Generate 2D walk
walk_2d <- random_normal_walk(.num_walks = 10, .n = 200, .dimensions = 2)

# Plot trajectories
ggplot(walk_2d, aes(x = cum_sum_x, y = cum_sum_y, color = walk_number)) +
  geom_path(alpha = 0.6, linewidth = 0.5) +
  geom_point(data = walk_2d %>% filter(step_number == 1),
             size = 3, shape = 21, fill = "white") +  # Start points
  geom_point(data = walk_2d %>% group_by(walk_number) %>% slice_max(step_number),
             size = 3, shape = 24, fill = "red") +  # End points
  coord_equal() +
  theme_minimal() +
  labs(
    title = "2D Random Walk Trajectories",
    x = "X Position",
    y = "Y Position",
    color = "Walk"
  )

## ----step_numbers_2d, fig.alt="Single 2D random walk with step numbers labeled at intervals of 10 steps, colored by step progression"----
# Generate single walk
walk_2d <- random_normal_walk(.num_walks = 1, .n = 100, .dimensions = 2)

# Plot with step labels at intervals
walk_2d_labeled <- walk_2d %>%
  filter(step_number %% 10 == 0 | step_number == 1)

ggplot(walk_2d, aes(x = cum_sum_x, y = cum_sum_y)) +
  geom_path(color = "steelblue", linewidth = 1) +
  geom_point(data = walk_2d_labeled, aes(color = step_number), size = 3) +
  geom_text(data = walk_2d_labeled, aes(label = step_number),
            hjust = -0.3, vjust = -0.3, size = 3) +
  scale_color_viridis_c() +
  coord_equal() +
  theme_minimal() +
  labs(
    title = "2D Random Walk with Step Numbers",
    x = "X Position",
    y = "Y Position",
    color = "Step"
  )

## ----heatmap_2d, fig.alt="Heat map showing the density of 100 random walks with 500 steps each, using a plasma color scale to indicate visit frequency"----
library(ggplot2)

# Generate many walks
walk_2d <- random_normal_walk(.num_walks = 100, .n = 500, .dimensions = 2)

# Create density heat map
ggplot(walk_2d, aes(x = cum_sum_x, y = cum_sum_y)) +
  geom_bin2d(bins = 50) +
  scale_fill_viridis_c(option = "plasma") +
  coord_equal() +
  theme_minimal() +
  labs(
    title = "2D Random Walk Density Heat Map",
    subtitle = "100 walks, 500 steps each",
    x = "X Position",
    y = "Y Position",
    fill = "Count"
  )

## ----animated_2d, eval=FALSE--------------------------------------------------
# library(ggplot2)
# library(gganimate)
# 
# # Generate walk
# walk_2d <- random_normal_walk(.num_walks = 5, .n = 100, .dimensions = 2)
# 
# # Create animation
# p <- ggplot(walk_2d, aes(x = cum_sum_x, y = cum_sum_y, color = walk_number)) +
#   geom_path(aes(group = walk_number), alpha = 0.5) +
#   geom_point(size = 3) +
#   coord_equal() +
#   theme_minimal() +
#   labs(title = "Step: {frame_along}", x = "X", y = "Y") +
#   transition_reveal(step_number)
# 
# # Render
# animate(p, nframes = 100, fps = 10)

## ----3d_scatter, eval=FALSE---------------------------------------------------
# library(plotly)
# 
# # Generate 3D walk
# walk_3d <- random_normal_walk(.num_walks = 5, .n = 200, .dimensions = 3)
# 
# # Create 3D plot
# plot_ly(
#   data = walk_3d,
#   x = ~cum_sum_x,
#   y = ~cum_sum_y,
#   z = ~cum_sum_z,
#   color = ~walk_number,
#   type = "scatter3d",
#   mode = "lines",
#   line = list(width = 2)
# ) %>%
#   layout(
#     title = "3D Random Walk Trajectories",
#     scene = list(
#       xaxis = list(title = "X Position"),
#       yaxis = list(title = "Y Position"),
#       zaxis = list(title = "Z Position")
#     )
#   )

## ----3d_markers, eval=FALSE---------------------------------------------------
# library(plotly)
# library(dplyr)
# 
# # Generate 3D walk
# walk_3d <- random_normal_walk(.num_walks = 3, .n = 100, .dimensions = 3)
# 
# # Mark start and end points
# walk_with_markers <- walk_3d %>%
#   mutate(
#     point_type = case_when(
#       step_number == 1 ~ "Start",
#       step_number == max(step_number) ~ "End",
#       TRUE ~ "Path"
#     )
#   )
# 
# # Create plot
# plot_ly(data = walk_with_markers) %>%
#   # Add paths
#   add_trace(
#     data = walk_with_markers %>% filter(point_type == "Path"),
#     x = ~cum_sum_x, y = ~cum_sum_y, z = ~cum_sum_z,
#     color = ~walk_number,
#     type = "scatter3d",
#     mode = "lines",
#     line = list(width = 2),
#     showlegend = FALSE
#   ) %>%
#   # Add start points
#   add_trace(
#     data = walk_with_markers %>% filter(point_type == "Start"),
#     x = ~cum_sum_x, y = ~cum_sum_y, z = ~cum_sum_z,
#     type = "scatter3d",
#     mode = "markers",
#     marker = list(size = 8, color = "green", symbol = "circle"),
#     name = "Start"
#   ) %>%
#   # Add end points
#   add_trace(
#     data = walk_with_markers %>% filter(point_type == "End"),
#     x = ~cum_sum_x, y = ~cum_sum_y, z = ~cum_sum_z,
#     type = "scatter3d",
#     mode = "markers",
#     marker = list(size = 8, color = "red", symbol = "diamond"),
#     name = "End"
#   ) %>%
#   layout(
#     title = "3D Random Walk with Start/End Markers",
#     scene = list(
#       xaxis = list(title = "X"),
#       yaxis = list(title = "Y"),
#       zaxis = list(title = "Z")
#     )
#   )

## ----3d_projections, fig.width=10, fig.height=8, fig.alt="Three projection plots showing X-Y, X-Z, and Y-Z views of 3D random walks, arranged with X-Y on top and X-Z and Y-Z side by side below"----
library(ggplot2)
library(patchwork)

# Generate 3D walk
walk_3d <- random_normal_walk(.num_walks = 5, .n = 200, .dimensions = 3)

# X-Y projection
p_xy <- ggplot(walk_3d, aes(x = cum_sum_x, y = cum_sum_y, color = walk_number)) +
  geom_path(alpha = 0.6) +
  coord_equal() +
  theme_minimal() +
  labs(title = "X-Y Projection")

# X-Z projection
p_xz <- ggplot(walk_3d, aes(x = cum_sum_x, y = cum_sum_z, color = walk_number)) +
  geom_path(alpha = 0.6) +
  coord_equal() +
  theme_minimal() +
  labs(title = "X-Z Projection")

# Y-Z projection
p_yz <- ggplot(walk_3d, aes(x = cum_sum_y, y = cum_sum_z, color = walk_number)) +
  geom_path(alpha = 0.6) +
  coord_equal() +
  theme_minimal() +
  labs(title = "Y-Z Projection")

# Combine
p_xy / (p_xz | p_yz) +
  plot_layout(guides = "collect") +
  plot_annotation(title = "3D Random Walk - All Projections")

## ----distance_2d, eval=FALSE, fig.alt="Line plot showing distance from origin over time for 10 random walks in 2D, with a dashed black line showing the theoretical expectation"----
# library(dplyr)
# 
# # 2D walk
# walk_2d <- random_normal_walk(.num_walks = 10, .n = 500, .dimensions = 2)
# 
# # Calculate distance
# walk_with_distance <- walk_2d %>%
#   euclidean_distance(.x = x, .y = y)
# 
# # Visualize distance over time
# library(ggplot2)
# 
# ggplot(walk_with_distance, aes(x = step_number, y = distance, color = walk_number)) +
#   geom_line(alpha = 0.7) +
#   # Add theoretical expectation
#   geom_line(aes(y = sqrt(2 * step_number)), color = "black", linetype = "dashed", linewidth = 1) +
#   theme_minimal() +
#   labs(
#     title = "Distance from Origin in 2D Random Walk",
#     subtitle = "Dashed line shows theoretical E[distance] = sqrt(2n)",
#     x = "Step",
#     y = "Euclidean Distance"
#   )

## ----distance_3d, eval=FALSE--------------------------------------------------
# # 3D walk
# walk_3d <- random_normal_walk(.num_walks = 100, .n = 1000, .dimensions = 3)
# 
# # Calculate distance
# walk_with_distance <- walk_3d %>%
#   euclidean_distance(.x = x, .y = z)
# 
# # Analyze distance distribution at specific steps
# library(dplyr)
# 
# distance_at_steps <- walk_with_distance %>%
#   filter(step_number %in% c(100, 250, 500, 1000)) %>%
#   group_by(step_number) %>%
#   reframe(
#     mean_dist = mean(distance),
#     sd_dist = sd(distance),
#     theoretical_mean = sqrt(3 * step_number)
#   )
# 
# print(distance_at_steps)

## ----radial_dist, eval=FALSE, fig.alt="Histogram with density overlay showing the radial distribution of final positions for 500 random walks"----
# library(dplyr)
# library(ggplot2)
# 
# # Generate many 2D walks
# walk_2d <- random_normal_walk(.num_walks = 500, .n = 200, .dimensions = 2)
# 
# # Get final positions
# final_positions <- walk_2d %>%
#   group_by(walk_number) %>%
#   slice_max(step_number) %>%
#   euclidean_distance(.x = x, .y = y)
# 
# # Plot radial distribution
# ggplot(final_positions, aes(x = distance)) +
#   geom_histogram(aes(y = after_stat(density)), bins = 50, fill = "steelblue", alpha = 0.7) +
#   geom_density(color = "darkblue", linewidth = 1) +
#   theme_minimal() +
#   labs(
#     title = "Radial Distribution of Final Positions (2D)",
#     subtitle = "500 walks, 200 steps each",
#     x = "Distance from Origin",
#     y = "Density"
#   )

## ----convex_hull, eval=FALSE, fig.alt="2D random walk paths with a black polygon showing the convex hull of all final positions"----
# library(dplyr)
# library(ggplot2)
# 
# # Generate 2D walks
# walk_2d <- random_normal_walk(.num_walks = 20, .n = 200, .dimensions = 2)
# 
# # Get final positions
# final_positions <- walk_2d %>%
#   group_by(walk_number) %>%
#   slice_max(step_number)
# 
# # Calculate convex hull
# hull <- chull(final_positions$cum_sum_x, final_positions$cum_sum_y)
# hull_points <- final_positions[c(hull, hull[1]), ]  # Close the polygon
# 
# # Plot
# ggplot(walk_2d, aes(x = cum_sum_x, y = cum_sum_y, color = walk_number)) +
#   geom_path(alpha = 0.3) +
#   geom_point(data = final_positions, size = 3) +
#   geom_polygon(data = hull_points, aes(x = cum_sum_x, y = cum_sum_y),
#                fill = NA, color = "black", linewidth = 1) +
#   coord_equal() +
#   theme_minimal() +
#   labs(
#     title = "2D Random Walks with Convex Hull",
#     subtitle = "Black polygon shows convex hull of final positions",
#     x = "X Position",
#     y = "Y Position"
#   )

## ----particle_diffusion, eval=FALSE, fig.alt="Line plot showing particle diffusion distance from origin over time, with individual particle paths in light colors and mean distance in bold red"----
# # Simulate particle diffusion in a petri dish
# particles <- brownian_motion(
#   .num_walks = 50,
#   .n = 1000,
#   .delta_time = 0.1,
#   .dimensions = 2
# )
# 
# # Visualize
# particles %>%
#   euclidean_distance(.x = x, .y = y) %>%
#   ggplot(aes(x = step_number, y = distance, color = walk_number)) +
#   geom_line(alpha = 0.3) +
#   stat_summary(aes(group = 1), fun = mean, geom = "line",
#                color = "red", linewidth = 1.5) +
#   theme_minimal() +
#   labs(
#     title = "Particle Diffusion in 2D",
#     subtitle = "Red line shows mean distance",
#     x = "Time Step",
#     y = "Distance from Origin"
#   )

## ----drone_path, eval=FALSE---------------------------------------------------
# # Simulate drone wandering in 3D space
# drone_path <- brownian_motion(
#   .num_walks = 1,
#   .n = 500,
#   .delta_time = 0.5,
#   .initial_value = 100,  # Start at 100m altitude
#   .dimensions = 3
# )
# 
# # 3D visualization
# library(plotly)
# 
# plot_ly(
#   data = drone_path,
#   x = ~cum_sum_x,
#   y = ~cum_sum_y,
#   z = ~cum_sum_z,
#   type = "scatter3d",
#   mode = "lines+markers",
#   marker = list(
#     size = 2,
#     color = ~step_number,
#     colorscale = "Viridis",
#     showscale = TRUE
#   ),
#   line = list(width = 2, color = "steelblue")
# ) %>%
#   layout(
#     title = "Drone Flight Path (3D Random Walk)",
#     scene = list(
#       xaxis = list(title = "X (meters)"),
#       yaxis = list(title = "Y (meters)"),
#       zaxis = list(title = "Altitude (meters)")
#     )
#   )

## ----animal_movement, eval=FALSE, fig.alt="2D random walk showing animal foraging behavior with path colored by distance from home, and a red triangle marking the home location"----
# # Simulate animal foraging behavior
# # Using Cauchy walk for heavy tails (occasional long jumps)
# animal_movement <- random_cauchy_walk(
#   .num_walks = 1,
#   .n = 200,
#   .scale = 1,
#   .dimensions = 2
# )
# 
# # Add "home" location
# animal_movement <- animal_movement %>%
#   mutate(
#     distance_from_home = sqrt(cum_sum_x^2 + cum_sum_y^2)
#   )
# 
# # Plot
# ggplot(animal_movement, aes(x = cum_sum_x, y = cum_sum_y)) +
#   geom_path(color = "darkgreen", linewidth = 0.8, alpha = 0.6) +
#   geom_point(aes(color = distance_from_home), size = 2) +
#   geom_point(x = 0, y = 0, size = 5, color = "red", shape = 17) +  # Home
#   scale_color_viridis_c(option = "magma") +
#   coord_equal() +
#   theme_minimal() +
#   labs(
#     title = "Animal Foraging Path (2D Cauchy Walk)",
#     subtitle = "Red triangle marks home location",
#     x = "X Position",
#     y = "Y Position",
#     color = "Distance\nfrom Home"
#   )

## ----performance, eval=FALSE--------------------------------------------------
# # Reduce number of dimensions if not needed
# walk_2d <- random_normal_walk(.num_walks = 100, .n = 1000, .dimensions = 2)
# 
# # Instead of
# # walk_3d <- random_normal_walk(.num_walks = 100, .n = 1000, .dimensions = 3)

## ----viz_perf, eval=FALSE-----------------------------------------------------
# # Sample walks or steps for large datasets
# walk_large <- random_normal_walk(.num_walks = 1000, .n = 1000, .dimensions = 2)
# 
# # Sample walks
# walk_sample <- walk_large %>%
#   filter(walk_number %in% sample(levels(walk_number), 50))
# 
# # Or downsample steps
# walk_downsample <- walk_large %>%
#   filter(step_number %% 10 == 0)

## ----coord_systems, eval=FALSE------------------------------------------------
# # Good - maintains true spatial relationships
# ggplot(walk_2d, aes(x = cum_sum_x, y = cum_sum_y)) +
#   geom_path() +
#   coord_equal()  # Important!
# 
# # Bad - distorts spatial relationships
# ggplot(walk_2d, aes(x = cum_sum_x, y = cum_sum_y)) +
#   geom_path()  # No coord_equal()

## ----boundaries, eval=FALSE, fig.alt="2D random walk with reflecting boundaries shown by a black rectangle, demonstrating how walks bounce back when reaching the boundary"----
# # Reflecting boundary (bounce back)
# walk_2d <- random_normal_walk(.num_walks = 10, .n = 500, .dimensions = 2)
# 
# walk_bounded <- walk_2d %>%
#   mutate(
#     cum_sum_x = pmin(pmax(cum_sum_x, -50), 50),  # Bound between -50 and 50
#     cum_sum_y = pmin(pmax(cum_sum_y, -50), 50)
#   )
# 
# # Visualize
# ggplot(walk_bounded, aes(x = cum_sum_x, y = cum_sum_y, color = walk_number)) +
#   geom_path(alpha = 0.6) +
#   geom_rect(xmin = -50, xmax = 50, ymin = -50, ymax = 50,
#             fill = NA, color = "black", linewidth = 1) +
#   coord_equal() +
#   theme_minimal() +
#   labs(title = "2D Walk with Reflecting Boundaries")

