]> gitweb.factorcode.org Git - factor.git/commitdiff
Add math.algebra module with some useful words.
authorSamuel Tardieu <sam@rfc1149.net>
Wed, 26 Dec 2007 21:42:33 +0000 (22:42 +0100)
committerSamuel Tardieu <sam@rfc1149.net>
Wed, 26 Dec 2007 22:08:15 +0000 (23:08 +0100)
  - ext-euclidian implements the extended Euclidian algorithm
  - ring-inverse computes an inverse in a Z/nZ ring
  - chinese-remainder solves a multi-constraints modular equation

extra/math/algebra/algebra-docs.factor [new file with mode: 0644]
extra/math/algebra/algebra-tests.factor [new file with mode: 0644]
extra/math/algebra/algebra.factor [new file with mode: 0644]
extra/math/algebra/authors.txt [new file with mode: 0644]
extra/math/algebra/summary.txt [new file with mode: 0644]

diff --git a/extra/math/algebra/algebra-docs.factor b/extra/math/algebra/algebra-docs.factor
new file mode 100644 (file)
index 0000000..14fdc9a
--- /dev/null
@@ -0,0 +1,14 @@
+USING: help.markup help.syntax ;
+IN: math.algebra
+
+HELP: ext-euclidian
+{ $values { "a" "a positive integer" } { "b" "a positive integer" } { "gcd" "a positive integer" } { "u" "an integer" } { "v" "an integer" } }
+{ $description "Compute the greatest common divisor " { $snippet "gcd" } " of integers " { $snippet "a" } " and " { $snippet "b" } " using the extended Euclidian algorithm. In addition, this word also computes two other values " { $snippet "u" } " and " { $snippet "v" } " such that " { $snippet "a*u + b*v = gcd" } "." } ;
+
+HELP: ring-inverse
+{ $values { "a" "a positive integer" } { "b" "a positive integer" } { "i" "a positive integer" } }
+{ $description "If " { $snippet "a" } " and " { $snippet "b" } " are coprime, " { $snippet "i" } " is the smallest positive integer such as " { $snippet "a*i = 1" } " in ring " { $snippet "Z/bZ" } "." } ;
+
+HELP: chinese-remainder
+{ $values { "aseq" "a sequence of integers" } { "nseq" "a sequence of positive integers" } { "x" "an integer" } }
+{ $description "If " { $snippet "nseq" } " integers are pairwise coprimes, " { $snippet "x" } " is the smallest positive integer congruent to each element in " { $snippet "aseq" } " modulo the corresponding element in " { $snippet "nseq" } "." } ;
diff --git a/extra/math/algebra/algebra-tests.factor b/extra/math/algebra/algebra-tests.factor
new file mode 100644 (file)
index 0000000..86b513a
--- /dev/null
@@ -0,0 +1,5 @@
+USING: math.algebra tools.test ;
+
+{ 2 5 -2 } [ 10 24 ext-euclidian ] unit-test
+{ 17 } [ 19 23 ring-inverse ] unit-test
+{ 11 } [ { 2 3 1 } { 3 4 5 } chinese-remainder ] unit-test
diff --git a/extra/math/algebra/algebra.factor b/extra/math/algebra/algebra.factor
new file mode 100644 (file)
index 0000000..6ba445b
--- /dev/null
@@ -0,0 +1,34 @@
+! Copyright (c) 2007 Samuel Tardieu
+! See http://factorcode.org/license.txt for BSD license.
+USING: kernel math math.ranges namespaces sequences vars math.algebra ;
+IN: math.algebra
+
+<PRIVATE
+
+VARS: r-1 u-1 v-1 r u v ;
+
+: init ( a b -- )
+  >r >r-1 0 >u 1 >u-1 1 >v 0 >v-1 ;
+
+: advance ( r u v -- )
+  v> >v-1 >v u> >u-1 >u r> >r-1 >r ; inline
+
+: step ( -- )
+  r-1> r> 2dup /mod drop [ * - ] keep u-1> over u> * - v-1> rot v> * -
+  advance ;
+
+PRIVATE>
+
+! Extended Euclidian: http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
+: ext-euclidian ( a b -- gcd u v )
+  [ init [ r> 0 > ] [ step ] [ ] while r-1> u-1> v-1> ] with-scope ; foldable
+
+! Inverse a in ring Z/bZ
+: ring-inverse ( a b -- i )
+  [ ext-euclidian drop nip ] keep rem ; foldable
+
+! Chinese remainder: http://en.wikipedia.org/wiki/Chinese_remainder_theorem
+: chinese-remainder ( aseq nseq -- x )
+  dup product
+  [ [ over / [ ext-euclidian ] keep * 2nip * ] curry 2map sum ] keep rem ;
+  foldable
diff --git a/extra/math/algebra/authors.txt b/extra/math/algebra/authors.txt
new file mode 100644 (file)
index 0000000..f3b0233
--- /dev/null
@@ -0,0 +1 @@
+Samuel Tardieu
diff --git a/extra/math/algebra/summary.txt b/extra/math/algebra/summary.txt
new file mode 100644 (file)
index 0000000..5f0748e
--- /dev/null
@@ -0,0 +1 @@
+Various algebra-related words