-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add bisection and secant algorithms for root finding.
- Loading branch information
1 parent
4346db2
commit 56cfed0
Showing
5 changed files
with
111 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
# Object file | ||
*.o | ||
obj/* | ||
lib/* | ||
|
||
# Ada Library Information | ||
*.ali |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
with Ada.Text_IO; | ||
with Ada.Float_Text_IO; | ||
package body BBS.roots_real is | ||
-- | ||
-- Bisection algorithm for finding a root. | ||
-- | ||
function bisection(test : test_func; lower, upper : in out f; limit : Positive; err : out errors) return f is | ||
val_high : f; | ||
val_low : f; | ||
val_mid : f; | ||
mid_limit : f; | ||
begin | ||
val_high := test(upper); | ||
val_low := test(lower); | ||
if (val_high * val_low) > 0.0 then | ||
err := bad_args; | ||
return 0.0; | ||
end if; | ||
err := none; | ||
for i in 0 .. limit loop | ||
mid_limit := (lower + upper)/2.0; | ||
val_mid := test(mid_limit); | ||
exit when val_mid = 0.0; | ||
if (val_high * val_mid) > 0.0 then | ||
upper := mid_limit; | ||
val_high := val_mid; | ||
else | ||
lower := mid_limit; | ||
val_low := val_mid; | ||
end if; | ||
end loop; | ||
return (lower + upper)/2.0; | ||
end; | ||
-- | ||
function seacant(test : test_func; lower, upper : in out f; limit : Positive; err : out errors) return f is | ||
val_high : f; | ||
val_low : f; | ||
val_mid : f; | ||
mid_limit : f; | ||
begin | ||
val_high := test(upper); | ||
val_low := test(lower); | ||
if (val_high * val_low) > 0.0 then | ||
err := bad_args; | ||
return 0.0; | ||
end if; | ||
err := none; | ||
for i in 0 .. limit loop | ||
mid_limit := upper - val_high*(upper - lower)/(val_high - val_low); | ||
val_mid := test(mid_limit); | ||
exit when val_mid = 0.0; | ||
if (val_high * val_mid) > 0.0 then | ||
upper := mid_limit; | ||
val_high := val_mid; | ||
else | ||
lower := mid_limit; | ||
val_low := val_mid; | ||
end if; | ||
end loop; | ||
if val_mid = 0.0 then | ||
upper := mid_limit; | ||
lower := mid_limit; | ||
end if; | ||
return upper - val_high*(upper - lower)/(val_high - val_low); | ||
end; | ||
end; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
generic | ||
type F is digits <>; | ||
package BBS.roots_real is | ||
type errors is (none, bad_args, no_solution); | ||
type test_func is access function (x : f) return f; | ||
|
||
-- | ||
-- If there is an odd number of roots between the lower and upper limits, | ||
-- the bisection algorithm will always converge. Each iteration simply halves | ||
-- the interval between the limits, keeping a root between them. The result | ||
-- is the midpoint of the final interval after the specified number of iterations. | ||
-- | ||
-- The lower and upper values are updated during the iterations to provide an | ||
-- interval containing the root. | ||
-- | ||
function bisection(test : test_func; lower, upper : in out f; limit : Positive; err : out errors) return f; | ||
-- | ||
-- If there is an odd number of roots between the lower and upper limits, | ||
-- the secant method will always converge. Each stage of the iteration | ||
-- identifies a point where a line between the lower and upper values crosses | ||
-- the axis. This point is used instead of the midpoint in the bisection | ||
-- algorithm. | ||
-- | ||
-- Depending on the function, this can converge to a root much faster than | ||
-- the bisection algorithm. On the other had, it can also converge much | ||
-- slower. | ||
-- | ||
-- The lower and upper values are updated during the iterations to provide an | ||
-- interval containing the root. If the root is exact, the lower and upper | ||
-- values are equal to the returned value. | ||
-- | ||
function seacant(test : test_func; lower, upper : in out f; limit : Positive; err : out errors) return f; | ||
end; |