Matlab非线性方程求根

 
                                                        非线性方程求根                     
 
二分法 :           
function root=MultiRoot(f,a,b,eps)
if(nargin==3)
    eps=1.0e-4;
end
 
f1=subs(sym(f),findsym(sym(f)),a);
f2=subs(sym(f),findsym(sym(f)),b);
if(f1==0)
    root=a;
end
if(f2==0)
    root=b;
end
 
if(f1*f2>0)
    disp(' 两端点函数值乘积大于0!');
    return;
else
    tol=1;
    fun=diff(sym(f));
    ddf=diff(sym(fun));
    fa=subs(sym(f),findsym(sym(f)),a);
    fb=subs(sym(f),findsym(sym(f)),b);
    dfa=subs(sym(fun),findsym(sym(fun)),a);
    dfb=subs(sym(fun),findsym(sym(fun)),b);
    if(dfa>dfb)
        root=a;
    else
        root=b;
    end
    while(tol>eps)
        r1=root;
        fx=subs(sym(f),findsym(sym(f)),r1);
        dfx=subs(sym(fun),findsym(sym(fun)),r1);
        ddfx=subs(sym(ddf),findsym(sym(ddf)),r1);
        root=r1-fx*dfx/(dfx*dfx-fx*ddfx);
        tol=abs(root-r1);
    end
end
Example:
>> HalfInterval('x^3-3*x+1',0,1)
 
ans =
 
    0.3473
黄金分割法 :
function root=hj(f,a,b,eps)
if(nargin==3)
    eps=1.0e-4;
end
 
f1=subs(sym(f),findsym(sym(f)),a);
f2=subs(sym(f),findsym(sym(f)),b);
if(f1==0)
    root=a;
end
if(f2==0)
    root=b;
end
 
if(f1*f2>0)
    disp(' 两端点函数值乘积大于0!');
    return;
else   
    t1=a+(b-a)*0.382;
    t2=a+(b-a)*0.618;
    f_1=subs(sym(f),findsym(sym(f)),t1);
    f_2=subs(sym(f),findsym(sym(f)),t2);
    tol=abs(t1-t2);
    while(tol>eps)                           % 精度控制
        if(f_1*f_2<0)
            a=t1;
            b=t2;
        else
            fa=subs(sym(f),findsym(sym(f)),a);        
            if(f_1*fa>0)
                a=t2;
            else
                b=t1;
            end
        end
        t1=a+(b-a)*0.382;
        t2=a+(b-a)*0.618;
        f_1=subs(sym(f),findsym(sym(f)),t1);
        f_2=subs(sym(f),findsym(sym(f)),t2);
        tol=abs(t2-t1);
    end
    root=(t1+t2)/2;                             % 输出根
end
 
>> hj('x^3-3*x+1',0,1)
 
ans =
 
    0.3473
不动点迭代:
function [root,n]=StablePoint(f,x0,eps)
if(nargin==2)
    eps=1.0e-4;
end
 
tol=1;
root=x0;
n=0;
while(tol>eps)
    n=n+1;
    r1=root;
    root=subs(sym(f),findsym(sym(f)),r1)+r1;
    tol=abs(root-r1);
end
>> [r,n]=StablePoint('1/sqrt(x)+x-2',0.5)
 
r =
 
    0.3820
 
 
n =
 
     4
Atken 加速迭代法:
function [root,n]=AtkenStablePoint(f,x0,eps)
if(nargin==2)
    eps=1.0e-4;
end
 
tol=1;
root=x0;
x(1:2)=0;
n=0;
m=0;
a2=x0;
while(tol>eps)
    n=n+1;
    a1=a2;
    r1=root;
    root=subs(sym(f),findsym(sym(f)),r1)+r1;
    x(n)=root;
    if(n>2)
        m=m+1;
        a2=x(m)-(x(m+1)-x(m))^2/(x(m+2)-2*x(m+1)+x(m));
        tol=abs(a2-a1);
    end  
end
root=a2;
>> [r,n]=AtkenStablePoint('1/sqrt(x)+x-2',0.5)
 
r =
 
    0.3820
 
 
n =
 
     4
Steffensen 加速迭代:
function [root,n]=StevenStablePoint(f,x0,eps)
if(nargin==2)
    eps=1.0e-4;
end
 
tol=1;
root=x0;
n=0;
while(tol>eps)
    n=n+1;
    r1=root;
    y=subs(sym(f),findsym(sym(f)),r1)+r1;
    z=subs(sym(f),findsym(sym(f)),y)+y;
    root=r1-(y-r1)^2/(z-2*y+r1);
    tol=abs(root-r1);
end
>> [r,n]=StevenStablePoint('1/sqrt(x)+x-2',0.5)
 
r =
 
    0.3820
 
 
n =
 
     4
弦截法:       
function root=Secant(f,a,b,eps)
if(nargin==3)
    eps=1.0e-4;
end
 
f1=subs(sym(f),findsym(sym(f)),a);
f2=subs(sym(f),findsym(sym(f)),b);
if(f1==0)
    root=a;
end
if(f2==0)
    root=b;
end
 
if(f1*f2>0)
    disp(' 两端点函数值乘积大于0!');
    return;
else
    tol=1;
    fa=subs(sym(f),findsym(sym(f)),a);
    fb=subs(sym(f),findsym(sym(f)),b); 
    root=a-(b-a)*fa/(fb-fa);
    while(tol>eps)
         r1=root;
        fx=subs(sym(f),findsym(sym(f)),r1);
        s=fx*fa;
        if(s==0)
            root=r1;
        else
            if(s>0)
                root=b-(r1-b)*fb/(fx-fb);
            else
                root=a-(r1-a)*fa/(fx-fa);
            end
        end
        tol=abs(root-r1);
    end
end
>> Secant('x^3-3*x+1',0,1)
 
ans =
 
    0.3473
Steffensen 弦截法:
function root=StevenSecant(f,a,b,eps)
if(nargin==3)
    eps=1.0e-4;
end
 
f1=subs(sym(f),findsym(sym(f)),a);
f2=subs(sym(f),findsym(sym(f)),b);
if(f1==0)
    root=a;
end
if(f2==0)
    root=b;
end
 
if(f1*f2>0)
    disp(' 两端点函数值乘积大于0!');
    return;
else
    tol=1;
    fa=subs(sym(f),findsym(sym(f)),a);
    fb=subs(sym(f),findsym(sym(f)),b);
    faa=subs(sym(f),findsym(sym(f)),fa+a);
    root=a-fa*fa/(faa-fa);
    while(tol>eps)
        r1=root;
        fx=subs(sym(f),findsym(sym(f)),r1);
        v=fx+r1;
        fxx=subs(sym(f),findsym(sym(f)),v);
        root=r1-fx*fx/(fxx-fx);
        tol=abs(root-r1);
    end
end
>> StevenSecant('x^3-3*x+1',0,1)
 
ans =
 
    0.3473
抛物线法:
function root=Parabola(f,a,b,x,eps)
if(nargin==4)
    eps=1.0e-4;
end
 
f1=subs(sym(f),findsym(sym(f)),a);
f2=subs(sym(f),findsym(sym(f)),b);
if(f1==0)
    root=a;
end
if(f2==0)
    root=b;
end
 
if(f1*f2>0)
    disp(' 两端点函数值乘积大于0!');
    return;
else
     tol=1;
    fa=subs(sym(f),findsym(sym(f)),a);
    fb=subs(sym(f),findsym(sym(f)),b);
    fx=subs(sym(f),findsym(sym(f)),x);
    d1=(fb-fa)/(b-a);
    d2=(fx-fb)/(x-b);
    d3=(d2-d1)/(x-a);
    B=d2+d3*(x-b);
    root=x-2*fx/(B+sign(B)*sqrt(B^2-4*fx*d3));
    t=zeros(3);
    t(1)=a;
    t(2)=b;
    t(3)=x;
    while(tol>eps)
        t(1)=t(2);
        t(2)=t(3);
        t(3)=root;
        f1=subs(sym(f),findsym(sym(f)),t(1));
        f2=subs(sym(f),findsym(sym(f)),t(2));
        f3=subs(sym(f),findsym(sym(f)),t(3));
        d1=(f2-f1)/(t(2)-t(1));
        d2=(f3-f2)/(t(3)-t(2));
        d3=(d2-d1)/(t(3)-t(1));
        B=d2+d3*(t(3)-t(2));
        root=t(3)-2*f3/(B+sign(B)*sqrt(B^2-4*f3*d3)); 
        tol=abs(root-t(3));
    end
end
>> Parabola('sqrt(x)+log(x)-2',1,4,2)
 
ans =
 
    1.8773
Newton 法:
function root=NewtonRoot(f,a,b,eps)
if(nargin==3)
    eps=1.0e-4;
end
 
f1=subs(sym(f),findsym(sym(f)),a);
f2=subs(sym(f),findsym(sym(f)),b);
if(f1==0)
    root=a;
end
if(f2==0)
    root=b;
end
 
if(f1*f2>0)
    disp(' 两端点函数值乘积大于0!');
    return;
else
    tol=1;
    fun=diff(sym(f));
    fa=subs(sym(f),findsym(sym(f)),a);
    fb=subs(sym(f),findsym(sym(f)),b);
    dfa=subs(sym(fun),findsym(sym(fun)),a);
    dfb=subs(sym(fun),findsym(sym(fun)),b);
    if(dfa>dfb)
        root=a-fa/dfa;
    else
        root=b-fb/dfb;
    end
    while(tol>eps)
        r1=root;
        fx=subs(sym(f),findsym(sym(f)),r1);
        dfx=subs(sym(fun),findsym(sym(fun)),r1);
        root=r1-fx/dfx;
        tol=abs(root-r1);
    end
end
>> NewtonRoot('sqrt(x)-x^3+2',0.5,2)
 
ans =
 
    1.4759
简化Newton 法:
function root=SimpleNewton(f,a,b,eps)
if(nargin==3)
    eps=1.0e-4;
end
 
f1=subs(sym(f),findsym(sym(f)),a);
f2=subs(sym(f),findsym(sym(f)),b);
if(f1==0)
    root=a;
end
if(f2==0)
    root=b;
end
 
if(f1*f2>0)
    disp(' 两端点函数值乘积大于0!');
    return;
else
    tol=1;
    fun=diff(sym(f));
    fa=subs(sym(f),findsym(sym(f)),a);
    fb=subs(sym(f),findsym(sym(f)),b);
    dfa=subs(sym(fun),findsym(sym(fun)),a);
    dfb=subs(sym(fun),findsym(sym(fun)),b);
 
    if(dfa>dfb)
        df0=1/dfa;
        root=a-df0*fa;
    else
        df0=1/dfb;
        root=b-df0*fb;
    end
    while(tol>eps)
        r1=root;  
        fx=subs(sym(f),findsym(sym(f)),r1);
        root=r1-df0*fx;
        tol=abs(root-r1);
    end
end
>> SimpleNewton('sqrt(x)-x^3+2',1.2,2)
 
ans =
 
    1.4759
Newton 下山法:
function root=NewtonDown(f,a,b,eps)
if(nargin==3)
    eps=1.0e-4;
end
 
f1=subs(sym(f),findsym(sym(f)),a);
f2=subs(sym(f),findsym(sym(f)),b);
if(f1==0)
    root=a;
end
if(f2==0)
    root=b;
end
 
if(f1*f2>0)
    disp(' 两端点函数值乘积大于0!');
    return;
else
    tol=1;
    fun=diff(sym(f));
    fa=subs(sym(f),findsym(sym(f)),a);
    fb=subs(sym(f),findsym(sym(f)),b);
    dfa=subs(sym(fun),findsym(sym(fun)),a);
    dfb=subs(sym(fun),findsym(sym(fun)),b);
    if(dfa>dfb)
        root=a;
    else
        root=b;
    end
    while(tol>eps)
        r1=root;  
        fx=subs(sym(f),findsym(sym(f)),r1);   
        dfx=subs(sym(fun),findsym(sym(fun)),r1);
        toldf=1;
        alpha=2;
        while toldf>0
            alpha=alpha/2;
            root=r1-alpha*fx/dfx;
            fv=subs(sym(f),findsym(sym(f)),root);
            toldf=abs(fv)-abs(fx);
        end
        tol=abs(root-r1);
    end
end
>> NewtonDown('sqrt(x)-x^3+2',1.2,2)
 
ans =
 
1.4759
 
两步迭代法:
function root=TwoStep(f,a,b,type,eps)
if(nargin==4)
    eps=1.0e-4;
end
 
f1=subs(sym(f),findsym(sym(f)),a);
f2=subs(sym(f),findsym(sym(f)),b);
if(f1==0)
    root=a;
end
if(f2==0)
    root=b;
end
 
if(f1*f2>0)
    disp(' 两端点函数值乘积大于0!');
    return;
else
    tol=1;
    fun=diff(sym(f));
    fa=subs(sym(f),findsym(sym(f)),a);
    fb=subs(sym(f),findsym(sym(f)),b);
    dfa=subs(sym(fun),findsym(sym(fun)),a);
    dfb=subs(sym(fun),findsym(sym(fun)),b);
    if(dfa>dfb)
        root=a;
    else
        root=b;
    end
    while(tol>eps)
        if(type==1)
            r1=root;
            fx1=subs(sym(f),findsym(sym(f)),r1);
            dfx=subs(sym(fun),findsym(sym(fun)),r1);
            r2=r1-fx1/dfx;
            fx2=subs(sym(f),findsym(sym(f)),r2);
            root=r2-fx2/dfx;
            tol=abs(root-r1);
        else
            r1=root;
            fx1=subs(sym(f),findsym(sym(f)),r1);
            dfx=subs(sym(fun),findsym(sym(fun)),r1);
            r2=r1-fx1/dfx;
            fx2=subs(sym(f),findsym(sym(f)),r2);
            root=r2-fx2*(r2-r1)/(2*fx2-fx1);
             tol=abs(root-r1);
        end
    end
end
>> Two_Step('log(x)-sin(x)+1',0.1,3,1)
 
ans =
 
    0.7013
重根的迭代法:
function root=MultiRoot(f,a,b,eps)
if(nargin==3)
    eps=1.0e-4;
end
 
f1=subs(sym(f),findsym(sym(f)),a);
f2=subs(sym(f),findsym(sym(f)),b);
if(f1==0)
    root=a;
end
if(f2==0)
    root=b;
end
 
if(f1*f2>0)
    disp(' 两端点函数值乘积大于0!');
    return;
else
    tol=1;
    fun=diff(sym(f));
    ddf=diff(sym(fun));
    fa=subs(sym(f),findsym(sym(f)),a);
    fb=subs(sym(f),findsym(sym(f)),b);
    dfa=subs(sym(fun),findsym(sym(fun)),a);
    dfb=subs(sym(fun),findsym(sym(fun)),b);
    if(dfa>dfb)
        root=a;
    else
        root=b;
    end
    while(tol>eps)
        r1=root;
        fx=subs(sym(f),findsym(sym(f)),r1);
        dfx=subs(sym(fun),findsym(sym(fun)),r1);
        ddfx=subs(sym(ddf),findsym(sym(ddf)),r1);
        root=r1-fx*dfx/(dfx*dfx-fx*ddfx);
        tol=abs(root-r1);
    end
end
>> MultiRoot('(sin(x)-x+2)*x*x',-2,3,1e-8)
 
ans =
 
     0
 
非线性方程组的数值解法
 
不动点迭代:
function [r,n]=mulStablePoint(myf,x0,eps)
if nargin==1
    eps=1.0e-4;
end
 
r=myf(x0);
n=1;
tol=1;
while tol>eps
    x0=r;
    r=myf(x0);
    tol=norm(r-x0);
    n=n+1;
    if(n>100000)
        disp(' 迭代步数太多,可能不收敛!');
        return;
    end
end
Newton
function [r,n]=mulNewton(myf,dmyf,x0,eps)
if nargin==1
    eps=1.0e-4;
end
 
r=x0-myf(x0)/dmyf(x0);
n=1;
tol=1;
while tol>eps
    x0=r;
    r=x0-myf(x0)/dmyf(x0);
    tol=norm(r-x0);
    n=n+1;
    if(n>100000)
        disp(' 迭代步数太多,可能不收敛!');
        return;
    end
end
简化 Newton
function [r,n]=mulSimNewton(myf,dmyf,x0,eps)
if nargin==1
    eps=1.0e-4;
end
 
r=x0-myf(x0)/dmyf(x0);
c=dmyf(x0);
n=1;
tol=1;
while tol>eps
    x0=r;
    r=x0-myf(x0)/c;
    tol=norm(r-x0);
    n=n+1;
    if(n>100000)
        disp(' 迭代步数太多,可能不收敛!');
        return;
    end
end
Newton 下山法:
function [r,n]=mulDNewton(myf,dmyf,x0,eps)
if nargin==1
    eps=1.0e-4;
end
 
r=x0-myf(x0)/dmyf(x0);
n=1;
tol=1;
while tol>eps
    x0=r;
    ttol=1;
    w=1;
    F1=norm(myf(x0));
    while ttol>=0
        r=x0-w*myf(x0)/dmyf(x0);
        ttol=norm(myf(r))-F1;
        w=w/2;
    end
    tol=norm(r-x0);
    n=n+1;
    if(n>100000)
        disp(' 迭代步数太多,可能不收敛!');
        return;
    end
end
Newton
function [r,n]=mulVNewton(myf,x0,A,eps)
if nargin==1 
    A=eye(length(x0));
else
    if nargin==2
        eps=1.0e-4;
    end
end
 
r=x0-myf(x0)/A;
n=1;
tol=1;
while tol>eps
    x0=r;
    r=x0-myf(x0)/A;
    y=r-x0;
    z=myf(r)-myf(x0);
    A1=A+(z-y*A)'*y/norm(y);
    A=A1;
    n=n+1;
    if(n>100000)
        disp(' 迭代步数太多,可能不收敛!');
        return;
    end
    tol=norm(r-x0);
end                                        
 
 
 
 
 

你可能感兴趣的:(c,function,matlab,n2,fun)