Bisection method (old-fashioned)

  1. function r=bisect(f,a,b,eps)
  2. n=1+round((log(b-a)-log(eps))/log(2))
  3. fa=feval(f,a);
  4. fb=feval(f,b);
  5. for i=1:n
  6. c=(b+a)/2;
  7. fc=feval(f,c);
  8. if fc*fa<0
  9. b=c;
  10. fb=fc;
  11. else
  12. a=c;
  13. fa=fc;
  14. end
  15. end
  16. r=c;
  17. %SAVE AS bisect.m

注意,这里feval(Fcuntion EVALuate) 用法为 feval(function, argument1, argument2…),相当于将argument1,argument2……作为变量输入到function中并计算。
比如feval(f,2);
其中f=x^2;

feval(f,2) ==> 4。
注意,这里inline为创建行内(inline)函数。
注意,这里初始区间需要人为给定,下面将会给a,b初始区间的范围
When executing with

%IMPUT AS COMMANDS


>> format long
>> f=inline('exp(x)*log(x)-x*x');
>> eps=1e-5;
>> a=1;
>> b=2;
>> bisect(f,a,b,eps)

Result:

bisect(f,a,b,eps)

n =

    18


ans =

   1.69459915161133

Secant method (old-fashioned)

function r=secant(f,x0,x1,eps,nmax)
dx=x1-x0;
n=0;
while((abs(dx)>=eps) & (n<nmax))
    x2=x1-f(x1)*(x1-x0)/(f(x1)-f(x0));
    if(f(x0)*f(x2)>0)
        dx=x2-x0;
        x0=x2;
    else
        dx=x2-x1;
        x1=x2;
    end
    n=n+1;
end
r=x2

%SAVE AS secant.m

when executing with

format long;
>> x0=1.0;
>> x1=2.0;
>> eps=0.000001;
>> nmax=100;
>> secant(f,x0,x1,eps,nmax)

gives

secant(f,x0,x1,eps,nmax)

r =

   1.69460080240014


ans =

   1.69460080240014

Newton’s matrix method

function [x n]=newton(x0)
x1=x0-f(x0)/df(x0);
n=1;
while (norm(x1-x0)>=1e-6) & (n<=1000)
    x0=x1;
    x1=x0-f(x0)/df(x0);
    n=n+1;
end
x=x1
n
end

%SAVE AS newton.m
function y=f(x)
y(1)=x(1)-0.7*sin(x(1))-0.2*cos(x(2));
y(2)=x(2)-0.7*cos(x(1))+0.2*sin(x(2));
end

%save as f.m
function y=df(x)
y=[1-0.7*cos(x(1)) 0.2*sin(x(2));
  0.7*sin(x(1)) 1+0.2*cos(x(2))];
end

%save as df.m

注意这里牛顿法,参照计算物理学(刘金远)公式 2.2.11,所要求解的答案中,A*d=B;其中A为导数矩阵,分别为对x,y的偏导数矩阵(人工求解, df.m 2 by 2 matrix),而B为函数(人工输入 f.m 1 by 2 vector),d为所求答案矩阵,做除法即可。
Executing with

x0=[0.5 0.5]
newton([0.5 0.5])

gives

x =

   0.52652301348344   0.50791962157383


n =

    12


ans =

   0.52652301348344   0.50791962157383

Gradient desent

function [x n f]=dsense(x0)
eps=1.0e-6;
x=x0;
[f f2 g g2]=myfun(x);
lambda=f2/g2;
x=x-lambda*g;
n=0;
while (norm(x-x0)>=eps)
    x0=x;
    n=n+1;
    [f f2 g g2]=myfun(x);
    lambda =f2/g2;
    x=x-lambda*g;
    if(n>100000)
        disp('WRONG');
        return;
    end
end
end

%save as dsense.m
%FUNCTION DEFINE
function [f f2 g g2]=myfun(x)
f(1)=x(1)-5*x(2)*x(2)+7*x(3)*x(3)+12;
f(2)=3*x(1)*x(2)+x(1)*x(3)-11*x(1);
f(3)=2*x(2)*x(3)+40*x(1);
f=[f(1) f(2) f(3)];
f2=f(1)*f(1)+f(2)*f(2)+f(3)*f(3);

g(1)=2*f(1)+2*f(2)*(3*x(2)+x(3)-11)+2*40*f(3);
g(2)=2*f(1)*(-10*x(2))+2*f(2)*(3*x(1))+2*f(3)*(2*x(3));
g(3)=2*f(1)*(14*x(3))+2*f(2)*(x(1))+2*f(3)*(2*x(2));
g=[g(1) g(2) g(3)];
g2=g(1)*g(1)+g(2)*g(2)+g(3)*g(3);
end\

%save as myfun.m

参见计算物理学(刘金远)公式(2.2.20),给定初始值(x,y,z);
executing with

x0=[-1.5 6.5 -5.0]
dsense(x)

gives

ans =

   1.00001447533909   5.00003436406575  -4.00003033024421

注意,如果结果出现wrong,很可能为函数给定部分myfun.m 哪一步出错了。
wolframalpha.com求解,发现所得答案正式4组实数解中的一组
另外,由于这种局域数值计算法极度依赖于初始条件,不同的初始条件会给出来不同的解,在选定初始条件的时候,有时候需要大片撒网观察其输出情况;用人话说:

假如函数是蛋托形状的:
MSP335221e0730234bg11fc0000300cgh2cg14354be.gif
在上面放一个小球,小球最终会滑到临近的坑里,由于这个蛋托有很多坑(一个坑就是一个解),所以小球滚到哪个坑里(输出哪个数值解)与初始放小球的位置(初始条件选取)有关。

General Iteration Method (error occurred)

function [x, y]=iteration(x0,y0)
x=x0;
y=y0;
n=1;
while n<3
    x1=(1/2)*(x*x-y+0.5);
    y1=(1/8)*(x*x+4*y*y+8*y-4);
    n=n+1;
    x=x1
    y=y1
end
end

%save as iteration.m

An error occurred as iteration tiem n increases (x and y diverges quickly)