做得好。你在这方面取得了不错的开端。
让我们看一下图形解决方案。顺便说一句,这就是我完成图形部分的方式:
ezplot(@(x) x,[-1 3])
hold on
ezplot(@(x) sqrt(10./(x+4)),[-1 3])
grid on
或者,我可能会减去这两个函数,然后寻找差异的零,因此它与 x 轴相交。
无论如何,这就是定点迭代所做的,试图求解 x,这样
x = sqrt(10/(x+4))
那么我将如何更改您的代码来修复它?首先,我想为变量使用更具描述性的名称。您不会被角色收费,并且使您的代码更易于阅读和遵循将在未来为您带来巨大的回报。
有几个代码问题。要初始化向量,请使用如下形式之一:
xArray = zeros(1,10);
xArray(1,10) = 0;
请注意,如果由于您一直在解决此问题而已经定义了 xArray,则后一种形式只会将该单个元素归零。所以第一种形式在很大程度上是最好的。它肯定会创建一个数组,或者如果现有数组已经存在于您的工作区中,它会覆盖它。
最后,我喜欢用一些特殊的东西来初始化这样的数组,而不是零,这样我们就可以看到元素何时被覆盖。NaN 对此有好处。
接下来,无需在您的代码中为 x1 添加一个。同样,我强烈建议使用更好的变量名。使用注释也是一个好主意。自由。
我建议考虑收敛容差。您还可以有一个迭代计数器。
f = @(x)sqrt(10./(x+4));
% starting value
xcurrent = 0;
% count the iterations, setting a maximum in maxiter, here 25
iter = 0;
maxiter = 25;
% initialize the array to store our iterations
xArray = NaN(1,maxiter);
% convergence tolerance
xtol = 1e-8;
% before we start, the error is set to be BIG. this
% just lets our while loop get through that first iteration
xerr = inf;
% the while will stop if either criterion fails
while (iter < maxiter) && (xerr > xtol)
iter = iter + 1;
xnew = f(xcurrent);
% save each iteration
xArray(iter) = xnew;
% compute the difference between successive iterations
xerr = abs(xnew - xcurrent);
xcurrent = xnew;
end
% retain only the elements of xArray that we actually generated
xArray = xArray(1:iter);
plot(xArray);
fprintf('%15.8e\n',xArray);
结果如何?
1.58113883e+00
1.33856229e+00
1.36863563e+00
1.36479692e+00
1.36528512e+00
1.36522300e+00
1.36523091e+00
1.36522990e+00
1.36523003e+00
1.36523001e+00
1.36523001e+00
为了更准确地了解我们的表现如何......
format long g
xcurrent
xcurrent =
1.36523001364783
f(xcurrent)
ans =
1.36523001338436
顺便说一句,了解循环终止的原因是个好主意。它是否因迭代不足而停止?
我在这里回复的重点不是做你的功课,因为无论如何你都快做对了。重点是展示一些关于如何改进代码以供将来工作的注意事项。