Secant Method: What you need to know
Secant’s method and its MATLAB implementation are detailed in this article. We try to connect the dots between both Newton and Secant
As in my previous post on the fixed point method and bisection method, the goal here is to find a root of
The secant method takes a step forward – applies more approximations on the form of that we have in order to avoid the knowledge of the derivative of
.
How Secant Method Works
If you recall properly from my previous article on Newton; the Newton updates go as such




Afterwards, let’s define our “small enough” factor as the signed interval length so that we get


MATLAB implementation of Secant method
This is easily achieved on MATLAB. First and foremost, let’s write a secant function so that we can utilize it in the main.m function
function [x,error] = secant(f,x0,Niter)
% Input:
% f - input function
% x0 - current iteration value (call it x_0)
% Niter - number of iterations
% Output:
% x - vector x containing all iteration values x = [x0 x1 x2 .... xNiter]
% error - error vector containing all iteration values error = [|x1 - x0|, |x2 - x1| ... |xNiter - xNiter-1|]
Note that in the above is an initial guess.
Now let’s write the secant body function. Please note that in the expression of Secant method, we should not allow the denominator to be very small; otherwise, we will run through division-by-zero type of errors. To avoid this, we test the magnitude of the denominator vs. a user pre-defined tolerance value.
function [x,error] = secant(f,x0,Niter)
% Input:
% f - input function
% x0 - current iteration value (call it x_0)
% Niter - number of iterations
% Output:
% x - vector x containing all iteration values x = [x0 x1 x2 .... xNiter]
% error - error vector containing all iteration values error = [|x1 - x0|, |x2 - x1| ... |xNiter - xNiter-1|]
tolerance = 1e-10;
error = [];
x(1) = x0;
denominator = (f(x(1))-f(0));
if abs(denominator) < tolerance
disp('Early termination')
else
x(2) = (0*f(x(1)) - f(0)*x(1))/denominator;
error(1) = abs(x(1) - x(2));
for n = 1:(Niter-1)
denominator = (f(x(n+1))-f(x(n)));
if abs(denominator) < tolerance
disp('Early termination')
break;
else
x(n+2) = (x(n)*f(x(n+1)) - f(x(n))*x(n+1))/(f(x(n+1))-f(x(n)));
error(n+1) = abs(x(n+1) - x(n+2));
end
end
end
Now, let’s proceed to implement the main function for testing. As we did with the Bisection method, we will re-use the same previous main function
Niter = 20;
Note that in the above, we have assumed the stopping criterion of max number of iterations instead of min tolerance. Next, we can proceed to defining some functions to test, for example:
%given functions
f1 = @(x)x^3 - 2*x -5;
f2 = @(x)exp(-x) - x;
f3 = @(x)x*sin(x) -1;
f4 = @(x)x^3 - 3*x^2 +3*x - 1;
We can now solve each function using
% solve via secant
[x_1_secant,error_1_secant] = secant(f1,x0+1,Niter);
[x_2_secant,error_2_secant] = secant(f2,x0+1,Niter);
[x_3_secant,error_3_secant] = secant(f3,x0+1,Niter);
[x_4_secant,error_4_secant] = secant(f4,x0+50,Niter);
For comparison sake, we will also check whether we converged properly or not. We can either us the error function outputted by our bisection.m function or we can use MATLAB’s fsolve function as
%solving using a library routine
x_1 = fsolve(f1,1);
x_2 = fsolve(f2,1);
x_3 = fsolve(f3,1);
x_4 = fsolve(f4,1);
Right now, we are ready to plot
figure
subplot(2,2,1)
plot(x_1_secant,'m','Linewidth',1)
hold on
plot(x_1*ones(Niter,1),'g--','Linewidth',2)
xlabel('Iteration number n','Interpreter','latex')
ylabel('x','Interpreter','latex')
title('Solving
','Interpreter','latex')
legend('Secant','Library Routine','Interpreter','latex')
grid on
grid minor
subplot(2,2,2)
plot(x_2_newton,'m','Linewidth',1)
hold on
plot(x_2*ones(Niter,1),'g--','Linewidth',2)
xlabel('Iteration number n','Interpreter','latex')
ylabel('x','Interpreter','latex')
title('Solving
','Interpreter','latex')
legend('Secant','Library Routine','Interpreter','latex')
grid on
grid minor
subplot(2,2,3)
plot(x_3_newton,'m','Linewidth',1)
hold on
plot(x_3*ones(Niter,1),'g--','Linewidth',2)
xlabel('Iteration number n','Interpreter','latex')
ylabel('x','Interpreter','latex')
title('Solving
','Interpreter','latex')
legend('Secant','Library Routine','Interpreter','latex')
grid on
grid minor
subplot(2,2,4)
plot(x_4_newton,'m','Linewidth',1)
hold on
plot(x_4*ones(Niter,1),'g--','Linewidth',2)
xlabel('Iteration number n','Interpreter','latex')
ylabel('x','Interpreter','latex')
title('Solving
','Interpreter','latex')
legend('Secant','Library Routine','Interpreter','latex')
grid on
grid minor
Our complete main function looks like this
Niter = 20;
%given functions
f1 = @(x)x^3 - 2*x -5;
f2 = @(x)exp(-x) - x;
f3 = @(x)x*sin(x) -1;
f4 = @(x)x^3 - 3*x^2 +3*x - 1;
% solve via secant
[x_1_secant,error_1_secant] = secant(f1,x0+1,Niter);
[x_2_secant,error_2_secant] = secant(f2,x0+1,Niter);
[x_3_secant,error_3_secant] = secant(f3,x0+1,Niter);
[x_4_secant,error_4_secant] = secant(f4,x0+50,Niter);
%solving using a library routine
x_1 = fsolve(f1,1);
x_2 = fsolve(f2,1);
x_3 = fsolve(f3,1);
x_4 = fsolve(f4,1);
figure
subplot(2,2,1)
plot(x_1_secant,'m','Linewidth',1)
hold on
plot(x_1*ones(Niter,1),'g--','Linewidth',2)
xlabel('Iteration number n','Interpreter','latex')
ylabel('x','Interpreter','latex')
title('Solving
','Interpreter','latex')
legend('Secant','Library Routine','Interpreter','latex')
grid on
grid minor
subplot(2,2,2)
plot(x_2_newton,'m','Linewidth',1)
hold on
plot(x_2*ones(Niter,1),'g--','Linewidth',2)
xlabel('Iteration number n','Interpreter','latex')
ylabel('x','Interpreter','latex')
title('Solving
','Interpreter','latex')
legend('Secant','Library Routine','Interpreter','latex')
grid on
grid minor
subplot(2,2,3)
plot(x_3_newton,'m','Linewidth',1)
hold on
plot(x_3*ones(Niter,1),'g--','Linewidth',2)
xlabel('Iteration number n','Interpreter','latex')
ylabel('x','Interpreter','latex')
title('Solving
','Interpreter','latex')
legend('Secant','Library Routine','Interpreter','latex')
grid on
grid minor
subplot(2,2,4)
plot(x_4_newton,'m','Linewidth',1)
hold on
plot(x_4*ones(Niter,1),'g--','Linewidth',2)
xlabel('Iteration number n','Interpreter','latex')
ylabel('x','Interpreter','latex')
title('Solving
','Interpreter','latex')
legend('Secant','Library Routine','Interpreter','latex')
grid on
grid minor

Summary
In this article, we have detailed the secant method along with as why it looks the way it looks. Moreover, we sliced down the MATLAB code so that we explain each and every block appearing in our youtube lecture.
Follow my other courses such as convex optimization.
Buy me a cup of coffee using the donate link below 😊☕️
PS: I’m on twitter. I retweet stuff around algorithms, python, MATLAB and mathematical optimization, mostly convex.
PSS: We are so close to 100K subscribers on YouTube. It would mean so much if you could share the channel and subscribe to help us sustain.
Recent Comments