From a1b8dec0b6d990701bf79c9591cf823eb8dac943 Mon Sep 17 00:00:00 2001
From: Kasun Samarasinghe <kwsamarasinghe@gmail.com>
Date: Thu, 15 Apr 2010 22:36:45 +0200
Subject: [PATCH] changed patch

---
 sympy/abstractalgebra/finitefield.py     |   70 +++++++++++++++++++++++++++
 sympy/abstractalgebra/test_primefield.py |   77 ++++++++++++++++++++++++++++++
 2 files changed, 147 insertions(+), 0 deletions(-)
 create mode 100644 sympy/abstractalgebra/finitefield.py
 create mode 100644 sympy/abstractalgebra/test_primefield.py

diff --git a/sympy/abstractalgebra/finitefield.py b/sympy/abstractalgebra/finitefield.py
new file mode 100644
index 0000000..dc5e124
--- /dev/null
+++ b/sympy/abstractalgebra/finitefield.py
@@ -0,0 +1,70 @@
+"""Finite Field (Galois Field) Module for sympy"""
+from sympy.ntheory.primetest import isprime
+from sympy.core.numbers import igcdex
+
+class PrimeField():
+    """PrimeField object object which represents GF(p)"""
+
+    def __init__(self, p):
+        if isprime(p) == True:
+            self.p = p
+        else:
+            raise ValueError('Invalid Argument')
+
+    def elements(self):
+        """Returns the elements of the finite field"""
+
+        elements = range(0, self.p, 1)
+        return elements
+
+    def add(self,x1,x2):
+        """Returns the addition of the two arguements in modulo p"""
+
+        if x1 <= self.p -1 and x2 <= self.p -1:
+            return (x1+x2)%self.p
+        else:
+            raise ValueError('Invalid Arguments')
+
+    def additive_inverse(self,x):
+        """Returns the additive inverse of the element"""
+        return self.p-x
+
+    def multiply(self,x1,x2):
+        """Returns the multiplication of arguements in modulo p"""
+
+        if x1 <= self.p -1 and x2 <= self.p -1:
+            return (x1*x2)%self.p
+        else:
+            raise ValueError('Invalid Arguments')
+
+    def multiplicative_inverse(self,x):
+        """Returns the multiplicative inverse of the element"""
+
+        """Uses the extended euclid algorithm,
+        Inverse is y, such that xy+qp=1 iff gcd of x and p is 1"""
+
+        if x < self.p and x > -1:
+            return igcdex(x,self.p)[0]
+        else:
+            raise ValueError('Invalid Argument')
+
+    def power(self,x,power):
+        """Raises the element to the given power in modulo p"""
+
+        """Uses repeated squaring"""
+
+        if x < self.p and x > -1:
+            if power%2 == 0:
+                limit = power/2
+                ans = 1
+            else:
+                limit = (power - 1)/2
+                ans = x
+
+            i=0
+            while i<limit:
+                ans = ans * x**2
+                i=i+1
+            return ans%self.p
+        else:
+            raise ValueError('Invalid Argument')
\ No newline at end of file
diff --git a/sympy/abstractalgebra/test_primefield.py b/sympy/abstractalgebra/test_primefield.py
new file mode 100644
index 0000000..d0c9b6c
--- /dev/null
+++ b/sympy/abstractalgebra/test_primefield.py
@@ -0,0 +1,77 @@
+from finitefield import PrimeField
+
+def test_elements():
+    """Test Elements in the prime field"""
+    #In GF(2)
+    gf2=PrimeField(2)
+    assert gf2.elements() == [0,1]
+    #In GF(7)
+    gf7=PrimeField(7)
+    assert gf7.elements() == [0,1,2,3,4,5,6]
+
+def test_add():
+    """Test addition of two elements' in the prime field"""
+    #In GF(2)
+    gf2 = PrimeField(2)
+    assert gf2.add(1, 0) == 1
+    #In GF(3)
+    gf3 = PrimeField(3)
+    assert gf3.add(1,2) == 0
+    #In GF(7)
+    gf7=PrimeField(7)
+    assert gf7.add(4,5) == 2
+
+def test_additive_inverse():
+    """Test additive inverse of an element in the prime field"""
+    #In GF(2)
+    gf2 = PrimeField(2)
+    assert gf2.additive_inverse(1) == 1
+    #In GF(3)
+    gf3 = PrimeField(3)
+    assert gf3.additive_inverse(2) == 1
+    #In GF(7)
+    gf7=PrimeField(7)
+    assert gf7.additive_inverse(5) == 2
+
+
+def test_multiply():
+    """Test multiplication of two elements in the prime field"""
+    #In GF(2)
+    gf2 = PrimeField(2)
+    assert gf2.multiply(1, 0) == 0
+    #In GF(3)
+    gf3 = PrimeField(3)
+    assert gf3.multiply(1, 2) == 2
+    #In GF(7)
+    gf7=PrimeField(7)
+    assert gf7.multiply(4,5) == 6
+    assert gf7.multiply(3,6) == 4
+
+
+
+def test_multiplicative_inverse():
+    """Test multiplicative inverse of an element in the prime field"""
+    #In GF(2)
+    gf2 = PrimeField(2)
+    assert gf2.multiplicative_inverse(1) == 1
+    #In GF(3)
+    gf3 = PrimeField(3)
+    assert gf3.multiplicative_inverse(1) == 1
+    #In GF(7)
+    gf7=PrimeField(7)
+    assert gf7.multiplicative_inverse(5) == 3
+    assert gf7.multiplicative_inverse(6) == 6
+
+
+def test_power():
+    """Test exponentiation of an element in the prime field"""
+    #In GF(2)
+    gf2 = PrimeField(2)
+    assert gf2.power(1, 2) == 1
+    #In GF(7)
+    gf7 = PrimeField(7)
+    assert gf7.power(3, 3) == 6
+    assert gf7.power(4, 2) == 2
+    assert gf7.power(2, 5) == 4
+
+
-- 
1.7.0.2.msysgit.0

