GUI解决方程式项目

时间:2014-05-18 18:09:20

标签: matlab user-interface

我有一个Matlab项目,我需要在其中创建一个从用户接收两个数学函数的GUI。然后我需要找到它们的交点,然后绘制两个函数。

所以,我有几个问题:

  1. 您知道我可以使用哪种算法来查找交叉点吗?当然我更喜欢我已经可以在互联网上找到一个Matlab代码。而且,我更喜欢它不会是Newton-Raphson方法。 我应该指出我不允许使用内置的Matlab函数。

  2. 我无法绘制功能。我基本上做的是:

    fun_f = get(handles.Function_f,'string');    
    fun_g = get(handles.Function_g,'string');    
    cla % To clear axes when plotting new functions    
    ezplot(fun_f);    
    hold on    
    ezplot(fun_g);    
    axis ([-20 20 -10 10]);
    
  3. 问题在于,有时,轴限制不允许我看到其他功能。这将发生,例如,如果我将一个函数设为log10(x)而另一个函数设为y=1,则y=1将不会显示。 我已经尝试过使用所有轴命令,但无济于事。如果我自己设置限制,则功能仅存在于某些限制内。我不明白为什么。

    3。如何在静态文本中显示数字?或者更好的是,用数字串? 我希望显示类似x0 = [root1]; x1 = [root2]的内容。我发现的唯一解决方案是将我发现的根变成字符串,但我不愿意。

    至于方程求解器,这是我到目前为止的代码。我知道这是非常业余的,但它似乎是最直接的"办法。另外请记住,它还没有完成(例如,它只会向我显示两个解决方案,我不太确定如何在一个静态文本中显示多个根,因为它们是字符串,因此问题#3)。

    function [Sol] = SolveEquation(handles)
    fun_f = get(handles.Function_f,'string');
    fun_g = get(handles.Function_g,'string');
    f = inline(fun_f);
    g = inline(fun_g);
    
    i = 1;
    Sol = 0;
    
    for x = -10:0.1:10;
            if (g(x) - f(x)) >= 0 && (g(x) - f(x)) < 0.01
                Sol(i) = x;
                i = i + 1;
            end
    end
    
    solution1 = num2str(Sol(1));
    solution2 = num2str(Sol(2));
    
    set(handles.roots1,'string',solution1);
    set(handles.roots2,'string',solution2);
    

    if条件是因为减法永远不会给我一个绝对零,这似乎有点解决它,虽然它真的不完美,有时它会给我两个以上非常相似解决方案(例如1.9和2)。 x的范围是任意的,由我选择。

    我知道这是一个很长的问题,所以我非常感谢你的耐心等待。 非常感谢你提前!

1 个答案:

答案 0 :(得分:1)

问题1

我认为这是一种更强大的方法,用于在离散点处查找给定数据的根。寻找函数之间的差异何时改变符号,这对应于它们越过。

S=sign(g(x)-f(x));
h=find(diff(S)~=0)
Sol=x(h);

如果您可以根据需要评估功能,可以使用更多方法,但这取决于域的大小以及您想要的最佳效果。例如,如果您不需要很高的准确度,那么您的fg功能很容易计算,而且您无法或不想要使用衍生物,您可以使用与第一个代码片段相同的想法获得更准确的根,但是迭代地执行:

G=inline('sin(x)');
F=inline('1');
g=vectorize(G);
f=vectorize(F);
tol=1e-9;
tic()
x = -2*pi:.001:pi;
S=sign(g(x)-f(x));
h=find(diff(S)~=0); % Find where two lines cross over
Sol=zeros(size(h));
Err=zeros(size(h));
if ~isempty(h) % There are some cross-over points
    for i=1:length(h) % For each point, improve the approximation
        xN=x(h(i):h(i)+1);
        err=1;
        while(abs(err)>tol) % Iteratively improve aproximation
            S=sign(g(xN)-f(xN));
            hF=find(diff(S)~=0);
            xN=xN(hF:hF+1);
            [~,I]=min(abs(f(xN)-g(xN)));
            xG=xN(I);
            err=f(xG)-g(xG);
            xN=linspace(xN(1),xN(2),15);
        end
        Sol(i)=xG;
        Err(i)=f(xG)-g(xG);
    end
else % No crossover points - lines could meet at tangents
    [h,I]=findpeaks(-abs(g(x)-f(x)));
    Sol=x(I(abs(f(x(I))-g(x(I)))<1e-5));
    Err=f(Sol)-g(Sol)
end
% We also have to check each endpoint
if abs(f(x(end))-g(x(end)))<tol && abs(Sol(end)-x(end))>1e-12
    Sol=[Sol x(end)];
    Err=[Err g(x(end))-f(x(end))];
end
if abs(f(x(1))-g(x(1)))<tol && abs(Sol(1)-x(1))>1e-12
    Sol=[x(1) Sol];
    Err=[g(x(1))-f(x(1)) Err];
end
toc()
Sol
Err

这将&#34; zoom&#34;进入每个疑似根周围的区域,并反复提高准确性。您可以调整参数以查看它们是否提供更好的行为(容差tol,15,要生成的新点数,可能更高)。

问题2

您可能最好避免ezplot,并使用plot,这可以让您获得更好的控制权。您可以使用内联函数进行矢量化,以便像匿名函数一样对它们进行评估,就像我在前面的代码片段中所做的那样,使用

f=inline('x^2')
F=vectorize(f)
F(1:5)

这应该使绘图更容易:

plot(x,f(x),'b',Sol,f(Sol),'ro',x,g(x),'k',Sol,G(Sol),'ro')

问题3

我不确定你为什么不想把你的根源显示为字符串,这有什么不对:

text(xPos,yPos,['x0=' num2str(Sol(1))]);