Roots of a function: Difference between revisions

Content added Content deleted
(→‎{{header|J}}: exact or approximate)
Line 46: Line 46:
=={{header|ALGOL 68}}==
=={{header|ALGOL 68}}==
Finding 3 roots using the secant method:
Finding 3 roots using the secant method:
<pre>
MODE DBL = LONG REAL;
FORMAT dbl = $g$;
MODE DBL = LONG REAL;
FORMAT dbl = $g(-long real width, long real width-6, -2)$;

MODE DBLRES = UNION(DBL, VOID);
MODE DBLOPT = UNION(DBL, VOID);
MODE XY = STRUCT(DBL x, y);
FORMAT xy root = $f(dbl)" ("b("Exactly", "Approximately")")"$;

PROC find root = (PROC (DBL)DBL f, DBLOPT in x1, in x2, in ex)DBLRES:(
MODE DBLOPT = UNION(DBL, VOID);
INT limit=100;
MODE XYRES = UNION(XY, VOID);
DBL x1 := (in x1|(DBL x1):x1|-5.0), # if x1 is EMPTY then use -5.0 #

x2 := (in x2|(DBL x2):x2|+5.0), # if x2 is EMPTY then use +5.0 #
PROC find root = (PROC (DBL)DBL f, DBLOPT in x1, in x2, in x error, in y error)XYRES:(
ex := (in ex|(DBL ex):ex|small real);
INT limit = ENTIER (long real width / log(2)); # worst case of a binary search) #
DBL f o x1 := f(x1), f o x2;
DBL dx := x1 - x2;
DBL x1 := (in x1|(DBL x1):x1|-5.0), # if x1 is EMPTY then -5.0 #
x2 := (in x2|(DBL x2):x2|+5.0),
x error := (in x error|(DBL x error):x error|small real),
IF f o x1 = 0 THEN
y error := (in y error|(DBL y error):y error|small real);
x1 # we already have a solution! #
DBL y1 := f(x1), y2;
ELSE
FOR i WHILE
DBL dx := x1 - x2, dy;

f o x2 := f(x2);
IF f o x2 = 0 THEN stop iteration FI;
IF y1 = 0 THEN
XY(x1, y1) # we already have a solution! #
IF i = limit THEN value error FI;
ELSE
IF f o x1 = f o x2 THEN value error FI;
FOR i WHILE
dx := dx / ( f o x1 - f o x2 ) * f o x2;
x1 := x2; f o x1 := f o x2; # retain for next iteration #
y2 := f(x2);
x2 -:= dx;
IF y2 = 0 THEN stop iteration FI;
# WHILE # ABS dx > ex DO
IF i = limit THEN value error FI;
IF y1 = y2 THEN value error FI;
SKIP
OD;
dy := y1 - y2;
stop iteration:
dx := dx / dy * y2;
x1 := x2; y1 := y2; # retain for next iteration #
x2 EXIT
value error:
x2 -:= dx;
# WHILE # ABS dx > x error AND ABS dy > y error DO
EMPTY
FI
SKIP
OD;
);
stop iteration:
XY(x2, y2) EXIT
PROC f = (DBL x)DBL: x*x*x - LONG 3.0*x*x + LONG 2.0*x;
value error:
EMPTY
DBL first root, second root, third root;
FI
);
DBLRES first result = find root(f, LENG -1.0, LENG 3.0, EMPTY);

CASE first result IN
PROC f = (DBL x)DBL: x UP 3 - LONG 3.1 * x UP 2 + LONG 2.0 * x;
(DBL first result): (

printf(($"1st root found at x = "f(dbl)l$, first result));
DBL first root, second root, third root;
first root := first result

)
XYRES first result = find root(f, LENG -1.0, LENG 3.0, EMPTY, EMPTY);
OUT printf($"No first root found"l$)
CASE first result IN
ESAC;
(XY first result): (
DBLRES second result = find root( (DBL x)DBL: f(x) / (x - first root), EMPTY, EMPTY, EMPTY);
printf(($"1st root found at x = "f(xy root)l$, x OF first result, y OF first result=0));
first root := x OF first result
CASE second result IN
)
(DBL second result): (
printf(($"2nd root found at x = "f(dbl)l$, second result));
OUT printf($"No first root found"l$); stop
ESAC;
second root := second result

)
XYRES second result = find root( (DBL x)DBL: f(x) / (x - first root), EMPTY, EMPTY, EMPTY, EMPTY);
OUT printf($"No second root found"l$)
CASE second result IN
ESAC;
(XY second result): (
DBLRES third result = find root( (DBL x)DBL: f(x) / (x - first root) / ( x - second root ), EMPTY, EMPTY, EMPTY);
printf(($"2nd root found at x = "f(xy root)l$, x OF second result, y OF second result=0));
second root := x OF second result
CASE third result IN
)
(DBL third result): (
printf(($"3rd root found at x = "f(dbl)l$, third result));
OUT printf($"No second root found"l$); stop
ESAC;
third root := third result

)
XYRES third result = find root( (DBL x)DBL: f(x) / (x - first root) / ( x - second root ), EMPTY, EMPTY, EMPTY, EMPTY);
OUT printf($"No third root found"l$)
CASE third result IN
ESAC
(XY third result): (
printf(($"3rd root found at x = "f(xy root)l$, x OF third result, y OF third result=0));
third root := x OF third result
)
OUT printf($"No third root found"l$); stop
ESAC
</pre>
Output:<pre>
Output:<pre>

1st root found at x = +1.000000000000000000000000000e +0
2nd root found at x = +2.000000000000000000000000000e +0
1st root found at x = 9.1557112297752398099031e-1 (Approximately)
3rd root found at x = +0.000000000000000000000000000e +0</pre>
2nd root found at x = 2.1844288770224760190097e 0 (Approximately)
3rd root found at x = 0.0000000000000000000000e 0 (Exactly)</pre>


=={{header|C++}}==
=={{header|C++}}==