nihilator
nihilator

Reputation: 13

Developing a Secant Method Program for root finding

So I have been trying to develop a secant method program that can be used for finding the root of

f(x) = tanh(x) - (x / 3)

However the answer output is nowhere close. Every solution I have found seems a more complex way to solve it.

    x = 2;
prevx = x;

for i = 1:20

    x = x - (tanh(x)-(x/3))*((x-(prevx))/((tanh(x)-(x/3))-(tanh(prevx))-((prevx/3))));
    prevx = prevx + x;
    x
end

The answer should be 2.987. I am getting a negative number though for some reason.

Upvotes: 1

Views: 6134

Answers (2)

Benoit_11
Benoit_11

Reputation: 13945

Here is an alternative way to do it (@madbitloman is right on spot as for the error in your code).

The secant method can be illustrated as follows (from Wikipedia):

enter image description here

Now if we translate this into MATLAB code, that would look like this:

x(k) = x(k-1) - (f(x(k-1)))*((x(k-1) - x(k-2))/(f(x(k-1)) - f(x(k-2))));

What is left to be done is provide the algorithm with 2 initial estimates and some tolerance value to tell it when to stop searching for a root, i.e. when 2 consecutive entries in x are very close to each other.

Let's choose 2 and 4. The closer the estimates to the real root, the faster the convergence.

To avoid using tanh(x)-(x/3) inside the for loop, which could get messy, let's define an anonymous function that takes x as an argument:

f = @(x) tanh(x)-(x/3);

So that would be the f in the line of code above.

Therefore, the whole code would look like the following, with a tolerance of say 0.001:

clear
clc

%// Initial values and tolerance
x(1) = 2;
x(2) = 4;
f = @(x) tanh(x)-(x/3);

tolerance = 0.001;

%// Let's try from 3 to 15. 
for k=3:15

    x(k) = x(k-1) - (f(x(k-1)))*((x(k-1) - x(k-2))/(f(x(k-1)) - f(x(k-2))));

    if abs(x(k)-x(k-1)) < tolerance
        break
    end
end

After running the code, x looks like this:

x =

    2.0000    4.0000    2.9420    2.9839    2.9847

so it took 5 iterations to reach the desired tolerance. Note that due to floating arithmetic you might want to use a smaller tolerance because Matlab stores numbers with much more digits than 4.

Finally you can get the negative root as well using appropriate initial estimates like -2 and -4:

x =

   -2.0000   -4.0000   -2.9420   -2.9839   -2.9847

Hope that helps somehow!

Upvotes: 3

madbitloman
madbitloman

Reputation: 826

You suppose to add up terms so replace minus in this line:

x = x - (tanh(x)-(x/3))*((x-(prevx))/((tanh(x)-(x/3))-(tanh(prevx))-((prevx/3))));

To a plus:

x = x + (tanh(x)-(x/3))*((x-(prevx))/((tanh(x)-(x/3))-(tanh(prevx))-((prevx/3))));

To get a desired result of 2.987 for x. Also remove x before the end of the loop.

Upvotes: 3

Related Questions