我正在使用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
绘制函数,我会得到下图。
答案 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具有更高的优先级而不是符号(在编程中我们说变量具有不同的范围)。
如果x
是sym
很重要,则应使用等式求解器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)的多个值的解决方案做些什么。