使用Matlab的非线性方程的根

时间:2014-12-02 07:54:26

标签: matlab equation equation-solving nonlinear-functions

我正在使用Matlab来查找非线性函数的根。方程很长,我用另一个.m来保存函数,代码就像

function x_c = f_x_c(s,H,VA,Lo,qc,EA,NF,Sj,Fj)

if (s < 0) || (s > Lo);
    disp('The value of s is invalid')
    disp(['s = ' num2str(s)]);
    return
end

C1 = H/qc;
if NF == 0
    n = 0;
    sn = 0;
    sum_Fj = 0;
end
if NF >= 1
    Sj_Q = [0; Sj; Lo];
    %Determine n and sn if 0 <= s < Lo:
    if s < Lo
    STOP = 0;
    k = 0;
        while STOP == 0
        k = k + 1;
            if (s >= Sj_Q(k,1)) && (s < Sj_Q((k + 1),1))
            STOP = 1;
            end
        end
    n = k - 1;
    sn = Sj_Q(k,1);
    end

    %Determine n and sn if s = Lo:
    if s == Lo
        n = NF;
        sn = Sj(NF,1);
    end

sum_Fj = sum(Fj(1:n,1));
end


x_c = (H/EA)*s;
x_c = x_c + C1*asinh((qc*s - VA + sum_Fj)/H) + ...
- C1*asinh((qc*sn - VA + sum_Fj)/H);

for j = 1:n
    sk = Sj_Q((j + 1),1);
    sk_1 = Sj_Q(j,1);
    sum_Fj = sum(Fj(1:(j - 1)));
    x_c = x_c + ...
    + C1*asinh((qc*sk - VA + sum_Fj)/H) + ...
    - C1*asinh((qc*sk_1 - VA + sum_Fj)/H);
end

这里的变量是H。代码没有问题,因为当我在主文件中键入以下内容时,它会返回我那个冗长的等式。

syms x
equation = -(XB - XA) + f_x_c(s,x,VA,Lo,qc,EA,NF,Sj,Fj);  %Replaced H with variable H and all other arguments are pre-defined

现在,我想在H0附近解决这个等式。当我放fzero(@(x)equation, H0)时,它会给我一个类似

的错误
Undefined function 'isfinite' for input arguments of type 'sym'.

Error in fzero (line 308)
    elseif ~isfinite(fx) || ~isreal(fx)

Error in main (line 50)
fzero(@(x)equation, H0)

我该如何解决这个问题?

修改

该等式至少有一个根,因为如果我使用ezplot绘制函数,我会得到下图。enter image description here

2 个答案:

答案 0 :(得分:0)

我不知道是什么导致了这个问题因为我不熟悉Matlab中的符号包。

但是你应该能够使用一些数值求解器相当容易地解决它。从我能读到的代码中你想要解决上面等于零的等式,这正是牛顿Rhapson所做的。您可以在此处查找方法:http://en.wikipedia.org/wiki/Newton's_method

由于您可能不知道函数的精确导数,您可以使用一阶近似估计它,您只需使用差分的定义但是因为我们不能让h转到0,我们选择h非常小,在matlab中我通常使用sqrt(eps)。因此近似变为:f'(x)=(f(x + sqrt(eps)) - f(x))/ sqrt(eps)。

否则您可以使用我的方法,该方法适用于1维,您可以在此处找到它:http://imada.sdu.dk/~nmatt11/MM533-2014/ 你必须下载fpisimple.m和mynewton.m,因为newtons方法只是一个修复点迭代的应用程序,它建立在它之上。

答案 1 :(得分:0)

我知道,我到达了与你几乎相同的位置,但是,我到了第309行,因为显然在isfinite上使用sym并不会导致matlab 2014b崩溃。但是,isfinite返回false,仍然出错。但到了这一点:fzero似乎不应该用于符号。你确定这里有必要的符号吗?看看函数调用它似乎不是必要的,因为输出看起来好像它应该是一个数字。你也可以争辩说

syms x; fzero(@(x) x^2-1,1)

有效,但是@(x)中的x具有更高的优先级而不是符号(在编程中我们说变量具有不同的范围)。

如果xsym很重要,则应使用等式求解器solve代替符号输出。

syms x;
equation = x^2-3;
solve(equation,'x')

然而,这可能会失败或者为复杂的函数提供令人难以置信的长答案(并且对于没有很好的小数答案的表达式尝试syms x; equation = x^3-3.17+1.37*x;)。它也较慢,因此如果表达式中没有仲裁常数,则不推荐使用(例如,f = x ^ 2-a&lt; =&gt; x = + - a ^(1/2),其中a是稍后定义,或者你想对a)的多个值的解决方案做些什么。