下标越界,有界随机游走的迭代

问题描述

我正在尝试编写一个函数,该函数生成由单位球体约束的随机游走,从而产生由向量给出的随机游走的最后一个位置。在试图找出我的函数在哪里中断时,我尝试像这样拼凑:

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)))
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

我收到错误:new_loc[i,] 中的错误:下标越界

但是,当我在 for 循环之外手动迭代代码时,一切正常。我认为这与 R 的范围规则有关,并且我尝试将 rbind 的结果分配给全局环境,但这不起作用。

最初,我尝试编写这样的函数

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
}

但是当我这样做时,while 循环似乎不起作用,我只是从均匀分布而不是从随机游走中获取初始 new_loc 坐标。我意识到使用 rbind 可能是一种更正确的方法,但我有兴趣了解为什么这种方法不起作用。

解决方法

一些想法:

  • 当您使用 for (i in n)“修复”问题时,规范(更常见)方法通常是将 n 保持为单长度计数,并使用 {{1} } 或 seq_len(n) 调用中的类似内容,例如 for

  • n <- 10; for (i in seq_len(n)) 在正式的 return 声明之外的任何内容中都是不正确的;如果您想停止 function(.){..},请使用 repeat。如此处所示,重新分配的范围不正确,因此 break 从未真正与所有迭代结果重新分配。

最终,一旦您停止尝试从非函数中 new_loc,它就会起作用。

return