You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言牛顿法求根时while循环出现缺失值错误的求助

问题分析与修复方案

核心问题拆解

  1. 报错直接诱因:你运行的代码中while循环包含iter < max_iter判断,但未定义max_iter变量/参数,导致该比较返回NA,整个循环条件因混合TRUE/FALSE与NA触发"missing value where TRUE/FALSE needed"错误。
  2. 算法本质缺陷:目标函数g(x) = x/sqrt(1+x²)的牛顿迭代公式可简化为x_{n+1} = -x_n³:
    • 当|x₀| < 1时,迭代值会向0收敛;
    • 当|x₀| = 1时,迭代会在1和-1之间无限震荡;
    • 当|x₀| > 1时,迭代值绝对值会指数级增大(如x₀=2→x₁=-8→x₂=512→...),完全发散,永远无法满足收敛条件。

修复后的完整代码

g_x <- function(x){
  return(x/(1+x^2)^(1/2))
}

dg_x <- function(x){
  # 目标函数的导数计算
  return(1/(x^2+1)^(3/2))
}

newton <- function(x_0, k, max_iter = 100){
  # 参数说明:
  # x_0: 初始猜测值
  # k: 容差参数,容差为10^(-k)
  # max_iter: 最大迭代次数,默认100
  
  tol <- 10^(-k)
  # 替换dplyr::between为原生逻辑判断,摆脱包依赖
  if(g_x(x_0) >= -tol/2 && g_x(x_0) <= tol/2){
    return(c(x_0, 0))
  }
  
  iter <- 1
  x_prev_prev <- x_0  # 记录前前次迭代值,用于检测震荡
  x_1 <- x_0 - (g_x(x_0)/dg_x(x_0))
  
  while(abs(x_1 - x_0) > tol && iter < max_iter){
    # 检测发散:迭代值超出合理范围时提前终止
    if(abs(x_1) > 1e10){
      warning("迭代发散,无法收敛到根")
      return(c(NA, iter))
    }
    
    # 检测震荡:针对当前函数的特殊迭代规律(1↔-1循环)
    if(abs(x_1 + x_prev_prev) < tol){
      warning("迭代进入震荡循环,无法收敛到根")
      return(c(NA, iter))
    }
    
    x_prev_prev <- x_0
    x_0 <- x_1
    x_1 <- x_0 - (g_x(x_0)/dg_x(x_0))
    iter <- iter + 1
  }
  
  # 判断终止原因:收敛/达到最大迭代次数
  if(iter >= max_iter){
    warning("达到最大迭代次数,未收敛")
    return(c((x_1+x_0)/2, iter))
  }
  
  return(c((x_1+x_0)/2, iter))
}

关键修复点说明

  1. 补全迭代次数控制:新增max_iter参数并设置默认值,避免未定义变量导致的NA判断;
  2. 移除外部包依赖:用原生逻辑判断替换between函数,避免因未加载dplyr包产生的隐性错误;
  3. 添加发散与震荡检测:提前识别无法收敛的情况,避免无限循环或数值溢出;
  4. 明确终止原因:通过警告信息区分"发散"、"震荡"、"达到最大迭代次数"三种非收敛场景,提升调试效率。

内容的提问来源于stack exchange,提问作者Chance Law

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 16:55:27