% 
% 二分法，Steffensen 迭代，Newton 迭代
%

clear all;
close all;

f = @(x) x - 2*sin(x);  % 函数
tol = 1e-6;    % 精度要求

% 调用二分法
a = 1; b = 2;  % 求解区间
[x,iter] = bisection(f,a,b,tol);
fprintf('二分法：近似解 x=%f, 迭代步数 %d\n\n', x, iter);

% 调用 Steffensen 迭代法
g = @(x) 2*sin(x);  % 迭代函数
x0 = 2.0;    % 迭代初值
[x,iter] = steffensen(f,g,x0,tol);
fprintf('Steffensen 迭代：近似解 x=%f, 迭代步数 %d\n\n', x, iter);

% 调用 Newton 迭代法
df = @(x) 1-2*cos(x);  % 导函数
x0 = 2.0;    % 迭代初值
[x,iter] = newton(f,df,x0,tol);
fprintf('Newton 迭代：近似解 x=%f, 迭代步数 %d\n\n', x, iter);


%%%%% 二分法
function [x,iter] = bisection(f,a,b,tol)
if abs(f(a)) < tol
    x = a;
elseif abs(f(b)) < tol
    x = b;
else
    x = (a+b)/2;
    fx = f(x);
    iter = 1;
    while abs(fx) > tol && a<b
        fprintf('iter=%d, a=%f, b=%f, f(x)=%e \n', iter, a, b, fx);
        if f(a)*fx < 0
            b = x;
        else
            a = x;
        end
        x = (a+b)/2;
        fx = f(x);
        iter = iter+1;
    end
    fprintf('iter=%d, a=%f, b=%f, f(x)=%e \n', iter, a, b, fx);
end
end

%%%%% Steffensen 迭代
function [x,iter] = steffensen(f,g,x,tol)
iter = 1;    
fx = f(x);
fprintf('iter=%d, x=%f, f(x)=%e\n', iter, x, fx)
while abs(fx) > tol
    y = g(x); z = g(y);
    x = x - (y-x)^2/(z-2*y+x);
    iter = iter + 1;
    fx = f(x);
    fprintf('iter=%d, x=%f, f(x)=%e\n', iter, x, fx)
end
end

%%%%% Newton 迭代
function [x,iter] = newton(f,df,x,tol)
iter = 1;    
fx = f(x);
fprintf('iter=%d, x=%f, f(x)=%e\n', iter, x, fx)
while abs(fx) > tol   
    x = x - f(x)/df(x);
    iter = iter + 1;
    fx = f(x);
    fprintf('iter=%d, x=%f, f(x)=%e\n', iter, x, fx)
end
end
