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]
但是getDivide::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]
但是getDivide::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
。