我有两个不同的问题,但它们是一起发布的,因为我认为解决方案是相关的。我正在测试牛顿和割线方法(每个方法都是用循环实现的),并在同一轴上绘制结果与计算时间的关系来比较它们。我希望(离散)牛顿方法结果用蓝线连接,割线方法用红线表示。反过来,这些线由相应的图例注释。这种情况不会发生,因为情节中的每个点似乎都被考虑在单个对象上,因为它们是单独创建的。并且legend
命令会显示两个蓝色星号而不是蓝色星号和一个红色星号(我希望我可以在此处发布我的情节,但我还没有图像权限。)
这是我的缩写代码:
f = (x) % define function
figure
hold on
%% Newton
tic
while % terminating condition
% [Newtons method]
t = toc;
plot(t,log(abs(f(z)),'b*-')
end
%% Secant
tic
while % terminating condition
% [secant method]
t = toc;
plot(t,log(abs(f(z)),'r*-')
end
legend('Newton''s','Secant')
无论如何,'-'
中的linespec
都没有做任何事情,因为只绘制了一个点,而不是一条线。我知道我可以用plot([t_old t],[log(abs(f(z_old) log(abs(f(z)])
之类的每次迭代制作一个线图,但这并不理想,尤其是因为log(abs(f(z_old)))
每次都必须重新评估。此外,这不会解决传说中的问题。
我认为如果我能让MATLAB了解我正在尝试在轴上创建两个对象,一条蓝线和一条红线,这两个问题都将得到解决。谢谢。
答案 0 :(得分:1)
如果您不想将x / y数据存储在矢量中,然后重新绘制整个矢量,您可以使用以下代码添加到绘图线:
hNewton = [];
while % terminating condition
% [Newtons method]
t = toc;
if isempty(hNewton)
hNewton = plot(t,log(abs(f(z))),'b*-'); % First time through plot and save the line handle
else
% On all subsequent passes, just add to the lines X/Y data
set(hNewton,'XData',[get(hNewton,'XData') t]);
set(hNewton,'YData',[get(hNewton,'YData') log(abs(f(z)))]);
end
end
由于现在只有2行,所以图例按预期工作。
或者,您可以将代码添加到函数
中的现有行function hLineHandle = AddToLine( hLineHandle, xData, yData, lineStyle )
% AddToLine - Add data to a plotted line
if isempty(hLineHandle)
hLineHandle = plot(xData,yData, lineStyle);
else
set(hLineHandle,'XData',[get(hLineHandle,'XData') xData]);
set(hLineHandle,'YData',[get(hLineHandle,'YData') yData]);
end
end
这使得主脚本/函数中的代码更加清晰。
hNewton = [];
while % terminating condition
% [Newtons method]
t = toc;
hNewton = AddToLine(hNewton,t, log(abs(f(z))),'b*-' );
end
答案 1 :(得分:1)
您可以使用line
对象,例如:
f = (x) % define function
figure
hold on
lHandle1 = line(nan, nan); %# Generate a blank line and return the line handle
lHandle2 = line(nan, nan); %# Generate a blank line and return the line handle
%% Newton
tic
while % terminating condition
% [Newtons method]
t = get(lHandle1, 'XData');
Y1 = get(lHandle1, 'YData');
t = toc;
Y1 = [Y1 log(abs(f(z)];
set(lHandle1, 'XData', t, 'YData', Y1, 'LineWidth', 2 ,'Color' , [0 1 0]);
end
%% Secant
tic
while % terminating condition
% [secant method]
t = get(lHandle2, 'XData');
Y2 = get(lHandle2, 'YData');
t = toc;
Y2 = [Y2 log(abs(f(z)];
set(lHandle2, 'XData', t, 'YData', Y2, 'LineWidth', 2 ,'Color' , [1 0 0]);
end
legend('Newton''s','Secant')
答案 2 :(得分:1)
仅显示代码的相关部分以提出问题的良好示例。其他人已经解释了让传奇按照你的意愿行事的技巧。我会采用不同的解决方案,将测量值保存在矢量中并在循环后执行绘图。这有两个优点:您不必使用图例来处理这些技巧,但更重要的是,您没有在循环中执行绘图,可能需要花费大量时间。我猜你的时间由绘图控制,所以算法的影响很难显示在结果中。因此,将代码更改为此类(未经测试):
f = (x) % define function
% preallocate plenty of space
[t_newton, t_secant, f_newton, f_secant] = deal(nan(1, 1000));
%% Newton
tic;
i = 1;
while % terminating condition
% [Newtons method]
f_newton(i) = current_result;
t_newton(i) = toc;
i = i + 1;
end
%% Secant
tic;
i = 1;
while % terminating condition
% [secant method]
f_secant(i) = current_result;
t_secant(i) = toc;
i = i + 1;
end
% trim NaNs (not really needed, not plotted anyhow)
t_newton = t_newton(isfinite(t_newton));
f_newton = f_newton(isfinite(f_newton));
t_secant = t_secant(isfinite(t_secant));
f_secant = f_secant(isfinite(f_secant));
% do the plot
semilogy(t_newton, abs(f_newton), t_secant, abs(f_secant))
legend('Newton''s','Secant')