R语言马尔可夫链近似控制代码报错if(temp<vmin)参数长度为零求助
报错原因
你遇到的argument is of length zero报错核心根源出现在vInt的求和循环中:
R 语言数组索引从 1 开始,你当前的循环为 for(it in 1:(min(i,j)+1)),当 it 取到最大值 min(i,j)+1 时,i-it+1 或 j-it+1 会等于 0,索引为 0 时会返回长度为 0 的空值,导致vInt变为空值,后续计算的temp也随之变为空值。当uit==1时vmin被赋值为空的temp,后续else if(temp<vmin)判断时两个变量都是长度为 0 的值,直接触发报错。
修复方法
- 第一优先级修复
vInt的循环上限,将for(it in 1:(min(i,j)+1))改为for(it in 1:min(i,j)),确保索引始终≥1,不会出现空值:
# 原代码 # for(it in 1:(min(i,j)+1)){ # 修复后代码 for(it in 1:min(i,j)){ vInt=vInt+Vold[i-it+1,j-it+1,r]*0.1*exp(-0.1*(it-1)*h)*h }
- 修正迭代逻辑错误:你当前的误差计算和
Vold更新放在了r循环内部,会导致计算r=2时用的是已经更新过的r=1的Vold,不符合值迭代的逻辑,需要把这部分移到r循环外部:
for(n in 1:maxitr){ for(r in 1:Ns){ for(i in 2:Nx){ for(j in 2:Nx){ # 原有计算Vnew[i,j,r]的逻辑不变 } } } # 把误差计算、Vold更新移到这里,所有r计算完成后再统一更新 errormax=max(abs(Vold-Vnew)) print(n) print(errormax) Vold=Vnew if(errormax<tol){ break } }
- 补充边界条件赋值:你当前代码只处理了
i=2:Nx、j=2:Nx的内部网格点,边界点的Vnew始终为初始值0,需要根据你的控制问题的边界约束,补充边界点的Vnew赋值逻辑,否则最终计算结果会出错。
可选优化
你当前遍历uit找最小值的逻辑可以简化,避免初始化vmin带来的潜在问题:
# 预分配向量存储所有uit对应的temp和u temp_vec = numeric(Nu) u_vec = numeric(Nu) for(uit in 1:Nu){ # 原有计算temp、u的逻辑不变 temp_vec[uit] = temp u_vec[uit] = u } # 直接取最小值对应的结果 vmin = min(temp_vec) umin = u_vec[which.min(temp_vec)] Vnew[i,j,r]=vmin Uopt[i,j,r]=umin
内容的提问来源于stack exchange,提问作者Hongjiang Qian
相关产品推荐
相关产品推荐

