zeroin.a68
1 COMMENT
2
3 @section Synopsis
4
5 Zeroin is a classic root-finding algorithm.
6
7 After MCA 2310 in 'ALGOL 60 Procedures in Numerical Algebra' by Th. J. Dekker.
8
9 This Algol 68 version originates from the legacy "REVISED MC ALGOL 68 TEST SET":
10
11 Dick Grune, The Revised MC ALGOL 68 Test Set, IW XX/79,
12 Mathematical Centre, Amsterdam.
13
14 The Mathematical Centre ("Stichting Mathematisch Centrum" or SMC) was a Dutch
15 non-profit institution aiming at the promotion of pure mathematics and its
16 applications.
17
18 SMC is now "Stichting Centrum Wiskunde & Informatica" (CWI). The test set
19 is available as an open access publication from the CWI repository:
20
21 https://ir.cwi.nl/pub/
22
23 Selected (modified) "Revised MC ALGOL 68 Test Set" programs are distributed
24 with Algol 68 Genie with kind permission of Dick Grune.
25
26 COMMENT
27
28 BEGIN MODE NUM = LONG LONG REAL;
29
30 PROC zero in = (REF NUM x, y, PROC (NUM) NUM f, tol) BOOL:
31 BEGIN NUM a := x, b := y; NUM fa := f (a), fb := f (b);
32 NUM c := a, fc := fa;
33 WHILE
34 (ABS fc < ABS fb |
35 (a := b, fa := fb); (b := c, fb := fc); (c := a, fc := fa));
36 NUM tolb := tol (b), m := (c + b) * .5;
37 ABS (m - b) > tolb
38 DO NUM p := (b - a) * fb, q := fa - fb;
39 (p < 0 | (p := -p, q := -q));
40 (a := b, fa := fb);
41 fb := f (b :=
42 IF p <= ABS q * tolb
43 THEN (c > b | b + tolb | b - tolb)
44 ELSE (p < (m - b) * q | p / q + b | m)
45 FI);
46 IF ABS (SIGN fb + SIGN fc) = 2
47 THEN (c := a, fc := fa)
48 FI
49 OD;
50 (x := b, y := c); ABS (SIGN fb + SIGN fc) < 2
51 END;
52
53 # Pretty print NUM. #
54
55 OP PRETTY = (NUM z) STRING:
56 IF ABS (z - ROUND z) < 10 * long long small real
57 THEN whole (z, 0)
58 ELIF ABS (z) >= 0.1 THEF ABS (z) <= 10
59 THEN STRING buf;
60 FOR digits TO long real width
61 WHILE puts (buf, fixed (z, 0, digits));
62 NUM y;
63 gets (buf, y);
64 z /= y
65 DO ~ OD;
66 buf
67 ELSE STRING buf, INT expw = 4;
68 FOR digits TO long real width
69 WHILE puts (buf, float (z, 4 + digits + expw, digits, expw));
70 NUM y;
71 gets (buf, y);
72 z /= y
73 DO ~ OD;
74 buf
75 FI;
76
77 NUM eps = long small real;
78
79 PROC solve = (NUM u, v, PROC (NUM) NUM f, STRING s) VOID:
80 IF u >= v
81 THEN error
82 ELSE print (("Expression: ", s, new line));
83 print (("[", PRETTY u, ", ", PRETTY v, "]", new line));
84 IF NUM x, y;
85 zero in (x := u, y := v, f, (NUM p) NUM : eps + eps * ABS p)
86 THEN print (("x: ", PRETTY x, new line));
87 print (("y: ", PRETTY f(x), new line))
88 ELSE print (("zeroin cannot find a root", new line))
89 FI;
90 new line (standout)
91 FI;
92
93 MODE FUN = PROC (NUM) NUM;
94 PROC pow = (FUN f, INT n, NUM x) NUM: f (x) ** n;
95 OP ** = (FUN f, INT n) FUN: pow (f, n, );
96
97 solve (-long long pi, long long pi, (NUM x) NUM : (long long sin **2) (x) - 1, "sin^2 x - 1");
98 solve (-1, 1, (NUM x) NUM: x * x + 1, "x^2 + 1");
99
100 EXIT
101
102 error: print (("Error detected", new line))
103 END
104
105 COMMENT
106
107 Output:
108
109 Expression: sin^2 x -1
110 [-3.14159265358979323846264338327950, 3.14159265358979323846264338327950]
111 x: 1.57079632679489661923132169163975
112 y: 0
113
114 Expression: x^2 + 1
115 [-1, 1]
116 zeroin cannot find a root
117
118 COMMENT
© 2002-2024 J.M. van der Veer (jmvdveer@xs4all.nl)
|