-
Notifications
You must be signed in to change notification settings - Fork 34
/
function_inverse_binary_search.pl
executable file
·49 lines (36 loc) · 1.22 KB
/
function_inverse_binary_search.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#!/usr/bin/perl
# Daniel "Trizen" Șuteu
# Date: 10 July 2019
# https://github.com/trizen
# Compute the inverse of any function, using the binary search algorithm.
# See also:
# https://en.wikipedia.org/wiki/Binary_search_algorithm
use 5.020;
use strict;
use warnings;
use experimental qw(signatures);
use Math::AnyNum qw(:overload approx_cmp float);
sub binary_inverse ($n, $f, $min = 0, $max = $n, $prec = 192) {
local $Math::AnyNum::PREC = "$prec";
($min, $max) = ($max, $min) if ($min > $max);
$min = float($min);
$max = float($max);
for (; ;) {
my $m = ($min + $max) / 2;
my $c = approx_cmp($f->($m), $n);
if ($c < 0) {
$min = $m;
}
elsif ($c > 0) {
$max = $m;
}
else {
return $m;
}
}
}
say binary_inverse(2, sub ($x) { exp($x) }); # solution to x for: exp(x) = 2
say binary_inverse(43, sub ($x) { $x**2 }); # solution to x for: x^2 = 43
say binary_inverse(-43, sub ($x) { $x**3 }); # solution to x for: x^3 = -43
# Find the value of x such that Li(x) = 100
say binary_inverse(100, sub ($x) { Math::AnyNum::Li($x) }, 1, 1e6); #=> 488.871909852807531906050863920333348273780185564