为什么FindRoot以0为初值时解不了x == 10^6啊!
mathematica吧
全部回复
仅看楼主
吧务
level 15
xzcyr 楼主
在知乎偶然看到个帖子:《为什么这个一次方程用卡西欧解出来是无解?》(编号 1935290008736104477 ),便想着 FindRoot 会不会有类似的问题,结果一试,还真有:
FindRoot[x == 10^6, {x, 0}]
(*
FindRoot::lstol: 线搜索把步长降低到由 AccuracyGoal 和 PrecisionGoal 指定的容差范围内,但是无法使优化目标函数的值减小得足够多. 您可能需要多于 MachinePrecision 位的工作精度以满足这些容差.
*)
(* {x -> 1.77636*10^-15} *)
试了一下,发现这个问题似乎跟默认的线搜索方法(牛顿法的步长控制方法)有关系。截止目前,在不改变“以0为初值”这个条件的前提下,发现了4种避免此问题的方法。
1. 把步长控制关掉:
FindRoot[x == 10^6, {x, 0},
Method -> {"Newton", "StepControl" -> None}]
2. 把线搜索方法的子方法改成布伦特法:
FindRoot[x == 10^6, {x, 0},
Method -> {"Newton",
"StepControl" -> {"LineSearch", Method -> "Brent"}}]
3. 把步长控制方法改成信赖域法:
FindRoot[x == 10^6, {x, 0},
Method -> {"Newton", "StepControl" -> "TrustRegion"}]
4. 改用另一种单初值算法 AffineCovariantNewton(顺带一提这个方法是随非线性有限元法一并引入的)。
FindRoot[x == 10^6, {x, 0}, Method -> "AffineCovariantNewton"]
不过Casio计算器的出错机制是不是这个就不知道了。
2025年09月10日 06点09分 1
吧务
level 15
xzcyr 楼主
顺便,如果把方程参数搞得更极端些,再把雅可比阵的计算方法改成有限差分,我们将会看到:
FindRoot[x == 10^9, {x, 0}, Jacobian -> "FiniteDifference",
Method -> {"Newton", "StepControl" -> None}]
(* FindRoot::jsing: 在点 {x} = {0.} 碰到奇异雅克比. 尝试扰动初始点. *)
(* {x -> 0.} *)
试探后发现,此问题可以通过调高差分阶数解决:
FindRoot[x == 10^9, {x, 0},
Jacobian -> {"FiniteDifference", "DifferenceOrder" -> 2},
Method -> {"Newton", "StepControl" -> None}]
(* {x -> 1.*10^9} *)
但是为什么会出现这个问题就不知道了。(Jacobian的文档很简略,连独立页面都没。)
2025年09月10日 07点09分 2
1