固定点迭代

时间:2013-09-11 23:26:49

标签: matlab optimization

我是Matlab的新手,我必须使用定点迭代来查找xy = x之间交叉点的y = sqrt(10/x+4)值,在绘制它之后,它看起来像是在1.4。我正在使用x1 = 0的初始猜测。这是我目前的Matlab代码:

f = @(x)sqrt(10./(x+4));
x1 = 0; 
xArray(10) = [];
for i = 1:10
    x2 = f(x1);
    xArray(i) = x2;
    x1 = x1 + 1;
end
plot(xArray);
fprintf('%15.8e\n',xArray);

现在,当我运行时,我的x似乎接近0.8。谁能告诉我我做错了什么?

3 个答案:

答案 0 :(得分:2)

做得好。你在这方面做得不错。

让我们看看图形解决方案。顺便说一句,这就是我完成图形部分的方式:

ezplot(@(x) x,[-1 3])
hold on
ezplot(@(x) sqrt(10./(x+4)),[-1 3])
grid on

enter image description here

或者,我可以减去这两个函数,然后寻找差值的零,所以它与x轴交叉。

这就是定点迭代无论如何都要做的,试图解决x,这样

x = sqrt(10/(x+4))

那么如何更改代码来修复它?首先,我想为变量使用更多描述性名称。你不会被这个角色收费,让你的代码更易于阅读和阅读。以后会为你带来很大回报。

有几个代码问题。要初始化矢量,请使用以下形式之一的表单:

xArray = zeros(1,10);
xArray(1,10) = 0;

请注意,如果xArray已定义为ALREADY,因为您一直在处理此问题,则后一种形式只会将该单个元素清零。所以第一种形式是最好的。它肯定会创建一个数组,或者覆盖现有数组(如果它已经存在于您的工作区中)。

最后,我喜欢使用特殊的东西初始化这样的数组,而不是零,所以我们可以看到元素被覆盖的时间。 NaNs对此有好处。

接下来,无需在代码中向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

顺便说一句,知道循环终止的原因是个好主意。它是否因迭代不足而停止?

我在这里的回答是不要做你的功课,因为你无论如何都要接近正确。关键是要考虑如何改进代码以便将来工作。

答案 1 :(得分:1)

无需向x1添加1。每次迭代的输出都输入下一次迭代。因此,x2输出中的f(x1)应该是新的x1。更正的代码将是

for i = 1:10
    x2 = f(x1);
    xArray(i) = x2;
    x1 = x2;
end

答案 2 :(得分:0)

f(x)x^3+4*x^2-10中的{p> [1,2]找到了一个近似的根