牛顿法的MATLAB实现

时间:2019-05-09 09:26:10

标签: matlab newtons-method numerical-analysis

我需要编写一个MATLAB代码来声明以下函数的错误。

My functions

实施后,我需要对答案进行数值分析。我写一个代码。在这段代码中,我给了a和b值。

function newtons(x0,y0,TC)
if nargin <3 , x0=2; y0=3; TC=10^-20; 
end
a=1; 
b=9;
syms x y
f1 = @(x,y)((1/5)*(exp(-2*a*x)-b*sin(x*y))-0.4325);
f2 = @(x,y)((1/5)*((x^2*y)+b*cos(x))-0.0643);
invJ = matlabFunction(inv([diff(f1, x) diff(f1, y); diff(f2, x) diff(f2, y)]));
q =[x0; y0] - (feval(invJ,x0,y0)* [feval(f1,x0,y0) ; feval(f2,x0,y0)]);
X(1) = q(1,1); Y(1) = q(2,1);
i= 0; error = 100;
while(error > TC)
    i = i + 1;
    q = [X(i); Y(i)] - (feval(invJ,X(i),Y(i)) * [feval(f1,X(i),Y(i));feval(f2,X(i),Y(i))]);
    X(i+1) = q(1,1);
    Y(i+1) = q(2,1);
    error(i) = max(abs(((X(i+1)-X(i))/X(i+1))*100), abs((((Y(i+1)-Y(i))/Y(i+1)))*100)); 
end
fprintf('error: %f index: %i x: %f \n',error(i),i,X(i+1));
end

代码输出为:

error: 0.000000 index: 8 x: 1.150714 

但是当我更改a和b值时,您的输出将是:

error: NaN index: 3 x: NaN

我的错误在哪里? 感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

实际上主要的问题是指数函数

按比例缩小f1,f2和导数,然后在需要对其求值时,请记住将其乘以该大数

代码从这里开始

x0=2; y0=3; TC=10^-20; 
a=1; 
b=9;

由于您使用的是syms变量,因此无需再次定义函数句柄

Note: syms x y ;f = cosx + siny --> same as f =@(x,y)cosx + siny

t指定如果您获得NaN作为结果增加t,那么大缩放比例将有多大

t = 50; big_number = round(log10(exp(-2*t*x)));

syms x y

f1仅用于导数计算

f1 = (((1/5)*(exp(-2*a*x)-b*sin(x*y))-0.4325));

f11仅用于q计算

f11 = matlabFunction(f1./big_number);

f2仅用于导数计算

f2 = ((1/5)*((x^2*y)+b*cos(x))-0.0643);

f22仅用于q计算

f22 = matlabFunction(f2./big_number);


invJ = inv([diff(f1, x) diff(f1, y); diff(f2, x) diff(f2, y)])./big_number;

将invJ拆分以使用feval

invJ11 = feval(matlabFunction(invJ(1,1)), x0, y0);
invJ12 = feval(matlabFunction(invJ(1,2)), x0, y0);
invJ21 = feval(matlabFunction(invJ(2,1)), x0, y0);
invJ22 = feval(matlabFunction(invJ(2,2)), x0, y0);
deriv = [invJ11 invJ12; invJ21 invJ22];

将结果乘以big_number = round(log10(exp(-2 * t * x0)))

big_number = round(log10(exp(-2*t*x0)))
q =[x0; y0] - big_number.*(deriv* [feval(f11,x0,y0) ; feval(f22,x0,y0)]);

q是一维数组,无需指定列索引,行索引就足够了

X(1) = q(1); Y(1) = q(2);
i= 0; error = 100;

while(error > TC)
    i = i + 1;
    if i == 30
        break;
    end
invJ11 = feval(matlabFunction(invJ(1,1)), X(i),Y(i));
invJ12 = feval(matlabFunction(invJ(1,2)), X(i),Y(i));
invJ21 = feval(matlabFunction(invJ(2,1)), X(i),Y(i));
invJ22 = feval(matlabFunction(invJ(2,2)), X(i),Y(i));
deriv = [invJ11 invJ12; invJ21 invJ22];
big_number = round(log10(exp(-2*t*X(i))))


 q =[X(i);Y(i)] - big_number.*(deriv* [feval(f11,X(i),Y(i)) ; feval(f22,X(i),Y(i))]);

        X(i+1) = q(1);
        Y(i+1) = q(2);
        error = max(abs(((X(i+1)-X(i))/X(i+1))*100), abs((((Y(i+1)-Y(i))/Y(i+1)))*100));
        fprintf('error: %f index: %i x: %f \n',error,i,X(i+1));
    end

在下面找到完整的代码而无需注释

function newtons(x0,y0,TC)
if nargin <3 , x0=2; y0=3; TC=10^-20; 
x0=2; y0=3; TC=10^-20; 
a=1; 
b=9;
syms x y
t = 50;
f1 = (((1/5)*(exp(-2*a*x)-b*sin(x*y))-0.4325));
f11 = matlabFunction(f1./round(log10(exp(-2*t*x))));
f2 = ((1/5)*((x^2*y)+b*cos(x))-0.0643);
f22 = matlabFunction(f2./round(log10(exp(-2*t*x))));


invJ = inv([diff(f1, x) diff(f1, y); diff(f2, x) diff(f2, y)])./round(log10(exp(-2*t*x)));
invJ11 = feval(matlabFunction(invJ(1,1)), x0, y0);
invJ12 = feval(matlabFunction(invJ(1,2)), x0, y0);
invJ21 = feval(matlabFunction(invJ(2,1)), x0, y0);
invJ22 = feval(matlabFunction(invJ(2,2)), x0, y0);
deriv = [invJ11 invJ12; invJ21 invJ22];

q =[x0; y0] - round(log10(exp(-2*t*x0))).*(deriv* [feval(f11,x0,y0) ; feval(f22,x0,y0)]);
 X(1) = q(1); Y(1) = q(2);
i= 0; error = 100;

while(error > TC)
    i = i + 1;
invJ11 = feval(matlabFunction(invJ(1,1)), X(i),Y(i));
invJ12 = feval(matlabFunction(invJ(1,2)), X(i),Y(i));
invJ21 = feval(matlabFunction(invJ(2,1)), X(i),Y(i));
invJ22 = feval(matlabFunction(invJ(2,2)), X(i),Y(i));
deriv = [invJ11 invJ12; invJ21 invJ22];
q =[X(i);Y(i)] - round(log10(exp(-2*t*X(i)))).*(deriv* [feval(f11,X(i),Y(i)) ; feval(f22,X(i),Y(i))]);

    X(i+1) = q(1);
    Y(i+1) = q(2);
    error = max(abs(((X(i+1)-X(i))/X(i+1))*100), abs((((Y(i+1)-Y(i))/Y(i+1)))*100));
    fprintf

('error: %f index: %i x: %f \n',error,i,X(i+1));
end
end