我开始学习如何在MatLab中进行编程,并且试图了解牛顿方法收敛的速度。我当前要绘制绝对误差| xn−x | xn的迭代,其中x = sqrt(10)是真正的解决方案。由于该方法确实收敛,所以误差应该为零,但是当我绘制它时,没有点出现。谁能帮我解决这个问题?
f = @(x) (x).^2 - 10;
f_deriv = @(x) 2*x;
x0 = 1;
x_true = sqrt(10);
x_save = (x0);
for jj = 1:20
plot(jj,abs(x_save(jj)-x_true),'k.');
x_new = x0 - f(x0)/f_deriv(x0);
x_save(1+jj,1) = x_new;
x0 = x_new;
end
xlim([0 20]);
ylim([0 2.5]);
xticks(0:20);
yticks(0:0.1:2.5);
答案 0 :(得分:1)
您只需要hold on
,以便将每个图都添加到之前的图。默认情况下,每个新图都替换前一个图。
此外,我将标记从'.'
修改为'o'
,以提高可见度。
您可能还想在每个drawnow
之后加上pause
(也许还有一个合适的plot
),以便立即更新图形。如果您想查看标记“增长”所描绘的线,这将很有用。
f = @(x) (x).^2 - 10;
f_deriv = @(x) 2*x;
x0 = 1;
x_true = sqrt(10);
x_save = (x0);
hold on %%% New line
for jj = 1:20
plot(jj,abs(x_save(jj)-x_true),'ko'); %%% Modified line
x_new = x0 - f(x0)/f_deriv(x0);
x_save(1+jj,1) = x_new;
x0 = x_new;
end
xlim([0 20]);
ylim([0 2.5]);
xticks(0:20);
yticks(0:0.1:2.5);
答案 1 :(得分:1)
正如您所说,牛顿方法部分按预期工作。问题出在您的绘图部分。
在您的实现中,您在for循环中每次迭代生成1个图。 结果是20个图,每个图1个点,这不是您想要的结果。
下面是生成21个点的1个图的代码。
f = @(x) (x).^2 - 10;
f_deriv = @(x) 2*x;
x0 = 1;
x_true = sqrt(10);
x_save = (x0);
for jj = 1:20
% Don't plot here. Wait until all data is collected.
x_new = x0 - f(x0)/f_deriv(x0);
x_save(1+jj,1) = x_new;
x0 = x_new;
end
% Plot here. All data has been collected.
plot(0:20',abs(x_save-x_true),'kx');
xlim([0 20]);
ylim([0 2.5]);
xticks(0:20);
yticks(0:0.1:2.5);
编辑:使用semilogy
而不是plot
解决遗漏点的问题。
semilogy
计算值的对数。 log(0) = -Inf
下面是更改坐标以避免两个大数相减的示例。
% Original problem parameters
x0 = 1;
x_true = sqrt(10);
% Change of co-ordinates
% u = x - sqrt(10);
% f(x) = g(u(x))
g = @(u) u^2 + 2*x_true*u;
g_deriv = @(u) 2*u + 2*x_true;
u0 = x0 - x_true;
u_save = u0;
for jj = 1:20
u_new = u0 - g(u0)/g_deriv(u0);
u_save = [u_save u_new];
u0 = u_new;
end
semilogy(0:20, abs(u_save - 0), 'kx')
xlim([0 20]);
您会注意到,超过6次迭代的点仍然消失,因为误差仍然小于机器精度(〜1e-15)。但是,错误不会再增加。
如果要提高计算精度,则可能需要研究vpa
函数。
https://www.mathworks.com/help/symbolic/increase-precision-of-numeric-calculations.html