Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 142 lines (127 sloc) 5.429 kb
02e626a @colomon Start first continued fraction experiments.
authored
1 use Test;
2
949d46f @colomon More sqrt(2) tests.
authored
3 plan 18;
02e626a @colomon Start first continued fraction experiments.
authored
4
5 sub make-continued-fraction (Real $x is copy) {
6 gather loop {
7 my $a = $x.floor;
8 take $a;
9 $x = $x - $a;
10 last if $x == 0;
11 $x = 1 / $x;
12 }
13 }
14
15 is make-continued-fraction(3), [3], "Sanity test";
16 is make-continued-fraction(-42), [-42], "Sanity test";
17 is make-continued-fraction(3.245), [3, 4, 12, 4], "Wikipedia example works";
18 is make-continued-fraction(-4.2), [-5, 1, 4], "Wikipedia example works";
aff6975 @colomon Implement mjd's example z function.
authored
19
d7b9d88 @colomon I'm not Foster@Maher
authored
20 multi sub z($a is copy, $b is copy, $c is copy, $d is copy, @x) {
aff6975 @colomon Implement mjd's example z function.
authored
21 gather loop {
22 # say "abcd: $a $b $c $d";
23 my $a-div-c = $c ?? $a div $c !! Inf;
24 my $b-div-d = $d ?? $b div $d !! Inf;
25 # say "a/c b/d: $a-div-c $b-div-d";
26 last if $a-div-c == Inf && $b-div-d == Inf;
27 if $a-div-c == $b-div-d {
28 my $n = $a-div-c;
29 ($a, $b, $c, $d) = ($c, $d, $a - $c * $n, $b - $d * $n);
30 take $n;
31 # say "took $n";
32 } else {
33 if @x {
34 my $p = @x.shift;
35 ($a, $b, $c, $d) = ($b, $a + $b * $p, $d, $c + $d * $p);
f09400e @colomon working tests of addition, subtraction, multiplication, and division!
authored
36 # say "got $p";
aff6975 @colomon Implement mjd's example z function.
authored
37 } else {
38 ($a, $b, $c, $d) = ($b, $b, $d, $d); # WHY????
f09400e @colomon working tests of addition, subtraction, multiplication, and division!
authored
39 # say "got Inf";
aff6975 @colomon Implement mjd's example z function.
authored
40 }
41 }
42 }
43 }
44
45 is z(1, 2, 2, 0, [1, 5, 2]), [1, 1, 2, 7], "mjd's example works";
46 is z(1, 0, 1, 0, [1, 2, 3, 4]), [1], "z handles case where it is 0 times x";
47 is z(1, 0, 1, 0, [0]), [1], "z handles another case where it is 0 times x";
f6739f7 @colomon Couple more (passing!) tests.
authored
48 is z(1, 4, 4, 0, make-continued-fraction(22/7)), make-continued-fraction(22/7+1/4),
49 "+1/4 works, with make-continued-fraction";
50 is z(1, 0, 0, 1, make-continued-fraction(22/7)), make-continued-fraction(7/22), "z works to get reciprocal";
d7b9d88 @colomon I'm not Foster@Maher
authored
51
52 multi sub z($a is copy, $b is copy, $c is copy, $d is copy,
53 $e is copy, $f is copy, $g is copy, $h is copy,
54 @x, @y) {
f09400e @colomon working tests of addition, subtraction, multiplication, and division!
authored
55 my $oops = 0;
d7b9d88 @colomon I'm not Foster@Maher
authored
56 gather loop {
f09400e @colomon working tests of addition, subtraction, multiplication, and division!
authored
57 # say "\n$a $b $c $d $e $f $g $h";
58 last if all($e, $f, $g, $h) == 0;
59 die "No answer found" if ++$oops > 30;
60
61 my $b00 = $e ?? FatRat.new($a, $e) !! Inf;
62 my $b10 = $f ?? FatRat.new($b, $f) !! Inf;
63 my $b01 = $g ?? FatRat.new($c, $g) !! Inf;
64 my $b11 = $h ?? FatRat.new($d, $h) !! Inf;
65 # say "$b00 $b01 $b10 $b11";
66
67 my $i11 = $b11.floor;
68 my $i01 = $b01.floor;
69 my $i10 = $b10.floor;
70 my $i00 = $b00.floor;
71
72 if $i00 == all($i01, $i10, $i11) {
73 my $r = $i00;
d7b9d88 @colomon I'm not Foster@Maher
authored
74 ($a, $b, $c, $d, $e, $f, $g, $h)
75 = ($e, $f, $g, $h, $a - $e * $r, $b - $f * $r, $c - $g * $r, $d - $h * $r);
76 take $r;
f09400e @colomon working tests of addition, subtraction, multiplication, and division!
authored
77 # say "r = $r";
78 $oops = 0;
79 } else {
80 sub idiff($a, $b) {
81 # $a | $b == Inf ?? Inf !! ($a - $b).abs;
82 (($a == Inf ?? 100000000000 !! $a) - ($b == Inf ?? 100000000000 !! $b)).abs;
83 }
84
85 my $xw = idiff($b11, $b01) max idiff($b10, $b00);
86 my $yw = idiff($b11, $b10) max idiff($b01, $b00);
87 # say "xw = $xw yw = $yw";
88
89 if $xw > $yw {
90 if @x {
91 my $p = @x.shift;
92 ($a, $b, $c, $d, $e, $f, $g, $h)
93 = ($b, $a + $b * $p, $d, $c + $d * $p, $f, $e + $f * $p, $h, $g + $h * $p);
94 # say "p = $p";
95 } else {
96 ($a, $b, $c, $d, $e, $f, $g, $h)
97 = ($b, $b, $d, $d, $f, $f, $h, $h);
98 # say "p = Inf";
99 }
d7b9d88 @colomon I'm not Foster@Maher
authored
100 } else {
f09400e @colomon working tests of addition, subtraction, multiplication, and division!
authored
101 if @y {
102 my $q = @y.shift;
103 ($a, $b, $c, $d, $e, $f, $g, $h)
104 = ($c, $d, $a + $c * $q, $b + $d * $q, $g, $h, $e + $g * $q, $f + $h * $q);
105 # say "q = $q";
106 } else {
107 ($a, $b, $c, $d, $e, $f, $g, $h)
108 = ($c, $d, $c, $d, $g, $h, $g, $h);
109 # say "q = Inf";
110 }
d7b9d88 @colomon I'm not Foster@Maher
authored
111 }
112 }
113 }
114 }
115
f09400e @colomon working tests of addition, subtraction, multiplication, and division!
authored
116 is z(1, 2, 0, 0, 2, 0, 0, 0, [1, 5, 2], [1]), [1, 1, 2, 7], "mjd's example works (big z version)";
736b38b @colomon Simple tests with the sqrt(2).
authored
117 is z(0, 1, 1, 0, 1, 0, 0, 0, make-continued-fraction(1/4), make-continued-fraction(1/2)),
f09400e @colomon working tests of addition, subtraction, multiplication, and division!
authored
118 make-continued-fraction(1/4+1/2),
119 "Basic continued fraction addition";
120 is z(0, 1, -1, 0, 1, 0, 0, 0, make-continued-fraction(1/4), make-continued-fraction(1/2)),
121 make-continued-fraction(1/4-1/2),
122 "Basic continued fraction subtraction";
123 is z(0, 0, 0, 1, 1, 0, 0, 0, make-continued-fraction(1/4), make-continued-fraction(1/2)),
124 make-continued-fraction(1/4*1/2),
125 "Basic continued fraction multiplication";
126 is z(0, 1, 0, 0, 0, 0, 1, 0, make-continued-fraction(1/4), make-continued-fraction(1/2)),
127 make-continued-fraction(1/4 * 2),
128 "Basic continued fraction division";
129
736b38b @colomon Simple tests with the sqrt(2).
authored
130 sub cf-sqrt-two() {
30ec042 @colomon Tweak to sequence to make Rakudo happy.
authored
131 1, 2, 2, 2 ... *;
736b38b @colomon Simple tests with the sqrt(2).
authored
132 }
133
134 is cf-sqrt-two()[^10], make-continued-fraction(sqrt(2))[^10], "approximation for sqrt-2 works";
135 is z(0, 1, 1, 0, 1, 0, 0, 0, cf-sqrt-two(), make-continued-fraction(1/2))[^10],
136 make-continued-fraction(sqrt(2)+1/2)[^10],
137 "Extended continued fraction addition";
949d46f @colomon More sqrt(2) tests.
authored
138 is z(0, 1, 1, 0, 1, 0, 0, 0, cf-sqrt-two(), cf-sqrt-two())[^10],
139 make-continued-fraction(sqrt(2)*2)[^10],
140 "Extended continued fraction addition";
141 eval_dies_ok "z(0, 0, 0, 1, 1, 0, 0, 0, cf-sqrt-two(), cf-sqrt-two())[0]", "sqrt(2)^2 cannot be calculated";
Something went wrong with that request. Please try again.