Methods Mathematica中的Muller方法

Methods Mathematica中的Muller方法,methods,wolfram-mathematica,Methods,Wolfram Mathematica,我想写一个函数,其中有一个循环,用于执行执行所需的操作 但是我得到了无限循环…穆勒的方法(总是比维基百科好): 感谢海克在下面的评论中指出了一些错误 h[x_] := HermiteH[24, x]; i = Length@CoefficientList[h[x], x] - 1; f[i, x_] := h[x]; roots = {}; While[ i > 1, x0 = -2; x1 = -1; x2 = -.5; k = 1; While[Abs[k] > .001

我想写一个函数,其中有一个循环,用于执行执行所需的操作

但是我得到了无限循环…

穆勒的方法(总是比维基百科好): 感谢海克在下面的评论中指出了一些错误

h[x_] := HermiteH[24, x];
i = Length@CoefficientList[h[x], x] - 1;
f[i, x_] := h[x];
roots = {};
While[ i > 1,
  x0 = -2; x1 = -1; x2 = -.5; k = 1;
  While[Abs[k] > .001,
   q = (x0 - x1)/(x1 - x2);
   a = q f[i, x0] - q (1 + q) f[i, x1] + q^2 f[i, x2];
   b = (2 q + 1) f[i, x0] - (1 + q)^2 f[i, x1] + q^2 f[i, x2];
   c = (1 + q) f[i, x0];
   p = Sqrt[b b - 4 a c];
   xp = x0 - (x0 - x1) 2 c /(k = If[Abs[b + p] > Abs[b - p], b + p, b - p]);
   {x2, x1, x0} = {x1, x0, xp};
   ];
  AppendTo[roots, xp];
  i--;
  f[i, x_] = f[i + 1, x]/(x - xp);
  ];
Show[
 Plot[h[x], {x, -2, 2}],
 Graphics[{PointSize[Large], Point[{#, 0} & /@ roots]}]]
穆勒的方法(总是比维基百科好): 感谢海克在下面的评论中指出了一些错误

h[x_] := HermiteH[24, x];
i = Length@CoefficientList[h[x], x] - 1;
f[i, x_] := h[x];
roots = {};
While[ i > 1,
  x0 = -2; x1 = -1; x2 = -.5; k = 1;
  While[Abs[k] > .001,
   q = (x0 - x1)/(x1 - x2);
   a = q f[i, x0] - q (1 + q) f[i, x1] + q^2 f[i, x2];
   b = (2 q + 1) f[i, x0] - (1 + q)^2 f[i, x1] + q^2 f[i, x2];
   c = (1 + q) f[i, x0];
   p = Sqrt[b b - 4 a c];
   xp = x0 - (x0 - x1) 2 c /(k = If[Abs[b + p] > Abs[b - p], b + p, b - p]);
   {x2, x1, x0} = {x1, x0, xp};
   ];
  AppendTo[roots, xp];
  i--;
  f[i, x_] = f[i + 1, x]/(x - xp);
  ];
Show[
 Plot[h[x], {x, -2, 2}],
 Graphics[{PointSize[Large], Point[{#, 0} & /@ roots]}]]

请记住,该方法需要对收敛的三个初始点进行很好的猜测。我认为您对
k
的定义不正确。如果我正确解释维基百科页面和数学世界页面,
k
应该是类似于
k=If[Abs[b+p]>Abs[b-p],b+p,b-p]
。我做了你的建议
If[Abs[b+p]>Abs[b-p],k=b+p,k=b-p]
但是get
Divide::infy:遇到无限表达式1/(0.*10^931+0.*10^931 I)。>>
@cMinor:那是因为在
xp
的定义中也有一个
+
,其中应该有一个
-
,即
xp
应该是
xp=x0-(x0-x1)2c/k
,其中
k
和我前面的评论一样。使用与belisarius代码中相同的值,该算法随后收敛到
-0.756909
。请注意,
k
正如我前面所说,
xp
可能会变得复杂,具体取决于
b^2-4 a c
的符号。这允许您找到函数的复数根(例如,尝试
f[x_3;]:=x^4+1
)。@Heike当然您在这两种情况下都是正确的。我没有意识到有问题,因为它在我测试的几个案例中很好地收敛。哈现在我修改了外观以查找所有根。谢谢!请记住,该方法需要对收敛的三个初始点进行很好的猜测。我认为您对
k
的定义不正确。如果我正确解释维基百科页面和数学世界页面,
k
应该是类似于
k=If[Abs[b+p]>Abs[b-p],b+p,b-p]
。我做了你的建议
If[Abs[b+p]>Abs[b-p],k=b+p,k=b-p]
但是get
Divide::infy:遇到无限表达式1/(0.*10^931+0.*10^931 I)。>>
@cMinor:那是因为在
xp
的定义中也有一个
+
,其中应该有一个
-
,即
xp
应该是
xp=x0-(x0-x1)2c/k
,其中
k
和我前面的评论一样。使用与belisarius代码中相同的值,该算法随后收敛到
-0.756909
。请注意,
k
正如我前面所说,
xp
可能会变得复杂,具体取决于
b^2-4 a c
的符号。这允许您找到函数的复数根(例如,尝试
f[x_3;]:=x^4+1
)。@Heike当然您在这两种情况下都是正确的。我没有意识到有问题,因为它在我测试的几个案例中很好地收敛。哈现在我修改了外观以查找所有根。谢谢!我认为
x3
应该是
x3=x2-2*Cx/dens
。我认为
x3
应该是
x3=x2-2*Cx/dens