I am trying to write a function that generates a random walk bound by the unit sphere, resulting in the last location of the random walk given by a vector. In trying to figure out where my function is breaking, I have tried piecing it out like this:
norm_vec <- function(x) sqrt(sum(x^2))
sphere_start_checker <- function() {
repeat {
start_loc <- runif(3, min = -1, max = 1)
if (norm_vec(start_loc) < 1) return(start_loc)
}
}
n <- 10
set.seed(1)
new_loc <- as.matrix(t(sphere_start_checker()))
temp_loc <- as.matrix(t(c(0, 0, 0)))
for(i in n) {
repeat {
temp_loc <- new_loc[i, ] + runif(3, min = -.01, max = .01)
if (norm_vec(temp_loc) < 1) {
return(new_loc <- rbind(new_loc, temp_loc))
}
}
}
new_loc
I get the error: Error in new_loc[i, ] : subscript out of bounds
However, when I manually iterate the code outside of the for loop, everything works fine. I assume this has something to do with R's scoping rules, and I have tried messing with assigning the result of the rbind to the global environment, but that does not work.
Initially, I tried writing the function like this:
randomwalk_sphere <- function(n, radius, stepmax) {
# initialize sphere bounds
sphere_radius <- as.double(radius)
# initialize random starting vector
# while loop that adds a random vector to our start_loc n times, repeating once boundary condition is met
loop <- 0
new_loc <- sphere_start_checker()
while(loop <= n) {
repeat {
temp_loc <- new_loc + runif(3, min = -stepmax, max = stepmax)
if (norm_vec(temp_loc) < sphere_radius) {
return(assign("new_loc", temp_loc, env = .GlobalEnv))
}
}
loop <- loop + 1
}
new_loc
}
but when I do it this way, the while loop does not seem to work and I just get the initial new_loc coordinate from the uniform distribution rather than from a random walk. I realize that using rbind is probably a more correct way of doing this, but I am interested in learning why this approach does not work.