Skip to content

Commit 05ff277

Browse files
samuelcfpiresCascadingCascadescpiresPanquesito7
authored
feat: add Secant Method (#1255)
* feat: add secant method * Apply suggestions from code review Co-authored-by: Sharon "Cass" Cassidy <[email protected]> * fixed indentation * added more tests * better clarification for the tolerance parameter * removed redundant comments * chore: apply suggestions from code review --------- Co-authored-by: Sharon "Cass" Cassidy <[email protected]> Co-authored-by: scpires <[email protected]> Co-authored-by: David Leal <[email protected]>
1 parent d222df7 commit 05ff277

File tree

1 file changed

+80
-0
lines changed

1 file changed

+80
-0
lines changed

numerical_methods/secant_method.c

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/**
2+
* @file
3+
* @brief [Secant Method](https://en.wikipedia.org/wiki/Secant_method) implementation. Find a
4+
* continuous function's root by using a succession of roots of secant lines to
5+
* approximate it, starting from the given points' secant line.
6+
* @author [Samuel Pires](https://github.com/disnoca)
7+
*/
8+
9+
#include <assert.h> /// for assert
10+
#include <math.h> /// for fabs
11+
#include <stdio.h> /// for io operations
12+
13+
#define TOLERANCE 0.0001 // root approximation result tolerance
14+
#define NMAX 100 // maximum number of iterations
15+
16+
/**
17+
* @brief Continuous function for which we want to find the root
18+
* @param x Real input variable
19+
* @returns The evaluation result of the function using the input value
20+
*/
21+
double func(double x)
22+
{
23+
return x * x - 3.; // x^2 = 3 - solution is sqrt(3)
24+
}
25+
26+
/**
27+
* @brief Root-finding method for a continuous function given two points
28+
* @param x0 One of the starting secant points
29+
* @param x1 One of the starting secant points
30+
* @param tolerance Determines how accurate the returned value is. The returned
31+
* value will be within `tolerance` of the actual root
32+
* @returns `root of the function` if secant method succeed within the
33+
* maximum number of iterations
34+
* @returns `-1` if secant method fails
35+
*/
36+
double secant_method(double x0, double x1, double tolerance)
37+
{
38+
int n = 1; // step counter
39+
40+
while (n++ < NMAX)
41+
{
42+
// calculate secant line root
43+
double x2 = x1 - func(x1) * (x1 - x0) / (func(x1) - func(x0));
44+
45+
// update values
46+
x0 = x1;
47+
x1 = x2;
48+
49+
// return value if it meets tolerance
50+
if (fabs(x1 - x0) < tolerance)
51+
return x2;
52+
}
53+
54+
return -1; // method failed (maximum number of steps exceeded)
55+
}
56+
57+
/**
58+
* @brief Self-test implementations
59+
* @returns void
60+
*/
61+
static void test()
62+
{
63+
// compares root values found by the secant method within the tolerance
64+
assert(secant_method(0.2, 0.5, TOLERANCE) - sqrt(3) < TOLERANCE);
65+
assert(fabs(secant_method(-2, -5, TOLERANCE)) - sqrt(3) < TOLERANCE);
66+
assert(secant_method(-3, 2, TOLERANCE) - sqrt(3) < TOLERANCE);
67+
assert(fabs(secant_method(1, -1.5, TOLERANCE)) - sqrt(3) < TOLERANCE);
68+
69+
printf("All tests have successfully passed!\n");
70+
}
71+
72+
/**
73+
* @brief Main function
74+
* @returns 0 on exit
75+
*/
76+
int main()
77+
{
78+
test(); // run self-test implementations
79+
return 0;
80+
}

0 commit comments

Comments
 (0)