Skip to content
Browse files

Add pow_mod, tweak previous changes a bit.

  • Loading branch information...
1 parent 366e173 commit 6cab59a52f6a3032a2f78e8d065f6f50aaac5618 @colomon committed Aug 30, 2012
Showing with 43 additions and 23 deletions.
  1. +22 −2 lib/Math/Polynomial.pm
  2. +21 −21 t/03_expressions.t
View
24 lib/Math/Polynomial.pm
@@ -2,6 +2,8 @@ use v6;
class Math::Polynomial {
has @.coefficients;
+ has $.coeff_zero = 0;
+ has $.coeff_one = 1;
multi method new (*@coefficients) {
self.new(@coefficients);
@@ -117,7 +119,7 @@ class Math::Polynomial {
!! ($a xx $b).reduce(* * *);
}
- method divmod($that) {
+ method divmod(Math::Polynomial $that) {
my @den = $that.coefficients;
@den or fail 'division by zero polynomial';
my $hd = @den.pop;
@@ -149,7 +151,7 @@ class Math::Polynomial {
$a.divmod($b)[1];
}
- method mmod($that) {
+ method mmod(Math::Polynomial $that) {
my @den = $that.coefficients;
@den or fail 'division by zero polynomial';
my $hd = @den.pop;
@@ -170,4 +172,22 @@ class Math::Polynomial {
}
return Math::Polynomial.new(@rem);
}
+
+ method pow_mod(Int $exp is copy where $exp >= 0, Math::Polynomial $that) {
+ my $this = self % $that;
+ return $this.new if 0 == $that.degree;
+ return $this.new($this.coeff_one) if 0 == $exp;
+ return $this if $this.is-zero;
+ return $this.new($this.coefficients[0] ** $exp) if 0 == $this.degree;
+ my $result = Any;
+ while $exp {
+ say :$exp.perl;
+ if 1 & $exp {
+ $result = $result.defined ?? ($this * $result) % $that !! $this;
+ }
+ $exp +>= 1 and $this = ($this * $this) % $that;
+ }
+ return $result;
+ }
+
}
View
42 t/03_expressions.t
@@ -289,27 +289,27 @@ ok(has_coeff($qq)); # 0 ** 3
# $qq = eval { $p ** $p };
# ok(!defined $qq); # not defined p ** p
# ok($@ =~ /non-negative integer argument expected/);
-#
-# $qq = $p->pow_mod(0, $q);
-# ok(has_coeff($qq, 1)); # p ** 0 % q
-# $qq = $p->pow_mod(1, $q);
-# ok(has_coeff($qq, 1)); # p ** 1 % q
-# $qq = $p->pow_mod(2, $q);
-# ok(has_coeff($qq, 1)); # p ** 2 % q
-# $qq = $p->pow_mod(3, $q);
-# ok(has_coeff($qq, 1)); # p ** 3 % q
-# $qq = $p->pow_mod(0, $r);
-# ok(has_coeff($qq, 1)); # p ** 0 % r
-# $qq = $p->pow_mod(1, $r);
-# ok(has_coeff($qq, 1/16)); # p ** 1 % r
-# $qq = $p->pow_mod(2, $r);
-# ok(has_coeff($qq, 1/256)); # p ** 2 % r
-# $qq = $p->pow_mod(0, $c);
-# ok(has_coeff($qq)); # p ** 0 % c
-# $qq = $p->pow_mod(1, $c);
-# ok(has_coeff($qq)); # p ** 1 % c
-# $qq = $p->pow_mod(2, $c);
-# ok(has_coeff($qq)); # p ** 2 % c
+
+$qq = $p.pow_mod(0, $q);
+ok(has_coeff($qq, 1)); # p ** 0 % q
+$qq = $p.pow_mod(1, $q);
+ok(has_coeff($qq, 1)); # p ** 1 % q
+$qq = $p.pow_mod(2, $q);
+ok(has_coeff($qq, 1)); # p ** 2 % q
+$qq = $p.pow_mod(3, $q);
+ok(has_coeff($qq, 1)); # p ** 3 % q
+$qq = $p.pow_mod(0, $r);
+ok(has_coeff($qq, 1)); # p ** 0 % r
+$qq = $p.pow_mod(1, $r);
+ok(has_coeff($qq, 1/16)); # p ** 1 % r
+$qq = $p.pow_mod(2, $r);
+ok(has_coeff($qq, 1/256)); # p ** 2 % r
+$qq = $p.pow_mod(0, $c);
+ok(has_coeff($qq)); # p ** 0 % c
+$qq = $p.pow_mod(1, $c);
+ok(has_coeff($qq)); # p ** 1 % c
+$qq = $p.pow_mod(2, $c);
+ok(has_coeff($qq)); # p ** 2 % c
# $qq = eval { $p->pow_mod(0, $zp) };
# ok(!defined $qq); # not defined p ** 0 % 0
# ok($@ =~ /division by zero polynomial/);

0 comments on commit 6cab59a

Please sign in to comment.
Something went wrong with that request. Please try again.