# -*- coding: cp1252 -*- # -*- coding: ISO-8859-1 -*- # Python Math Lab # Version 0.8 # Stefan Mueller-Stach 2005 # This program is open source under GPL license # Python for Nokia Series 60 from __future__ import generators import whrandom, math, graphics, appuifw, e32, string, operator, sys, re def factorlist(m): list_of_factors = [] sq = math.sqrt(m) while m%2 == 0: list_of_factors.append(2) m = m//2 sq = math.sqrt(m) d = 3 while d <= sq: if m % d == 0: list_of_factors.append(d) m = m//d sq = math.sqrt(m) else: d = d+2 if m > 1: list_of_factors.append(m) return list(list_of_factors) def primes(n): if n <= 1: return [] X = [i for i in range(3,n+1) if i%2 != 0] P = [2] sqrt_n = math.sqrt(n) while len(X) > 0 and X[0] <= sqrt_n: p = X[0] P.append(p) X = [a for a in X if a%p != 0] return P + X def isprime(n): if n % 2 == 0 and not n == 2: return (0) else: limit = int(math.sqrt(n)) + 1 for l in range (3, limit, 2): if n % l == 0: return (0) return (1) def nextprime(n): np = n + 1 while np: if isprime(np): return (np) np = np + 1 def sgn(n): if n > 0: return 1 elif n < 0: return -1 else: return 0 def gcd(a,b): x1,x2,y1,y2=1,0,0,1 sgna=sgn(a) #unnoetig? sgnb=sgn(b) a=abs(a) #unnoetig? b=abs(b) while b!=0: q=a//b x1,x2,y1,y2=x2,x1-q*x2,y2,y1-q*y2 #x1->x2,x2->x3,y1->y2,y2->y3 a,b=b,a%b return a,x1*sgna,y1*sgnb # ggt>0 and ax1+bx2=ggt def lcm(a,b): return a//gcd(a,b)[0]*b def binomial(n,k): out = n for i in range(1,k): out = out * (n-i) for i in range(1,k+1): out = out//i return out def factorial(n): f = 1 for i in range(1, n+1): f = f*i return f def fibonacci(n): a,b = 0,1 list=[1,1] for x in range(1,n-1): a,b=b,a+b list.append(a+b) return list def eulerphi(n): negative_list=[] for p in factorlist(n): if not p in negative_list: n = n*(p-1)//p negative_list.append(p) return n def contfrac(number, steps=8): l = [] for i in range(steps): i = int(math.floor(number)) l.append(i) if abs(number-i) < 0.00000001: break number = 1/(number-i) return l def legendre(a,m): a=a%m t=1 while a!=0: while a%2==0: a=a//2 if m%8==3 or m%8==5: t=-t a,m=m,a if a%4==3 and m%4==3: t=-t a=a%m if m==1: return t return 0 def is_primitive_root( modulus, b = 2L ): less_one = modulus - 1 list_of_factors = factorlist( modulus - 1 ) for factor in list_of_factors: if pow(b, less_one//factor, modulus) == 1: return 0 return 1 def primitive_root(modulus): b = 2 while ( is_primitive_root( modulus, b) == 0): b = b+1 return b def inverse(a,b): if a<0: while a<0: a += b y = gcd(a,b) if y[0] != 1: raise ZeroDivisionError, (a,b) assert y[0]==1, "not coprime!" return y[1]%b def chinese(a,m,b,n): modulus= lcm(m,n) d, u, v = gcd(m,n) #um+vn=d > 0 if (b-a)%d == 0: # d must divide b-a, otherwise there is no solution c= (b-a)//d # c(um+vn)=cd=b-a, hence x=b-vcn=a+ucm is the solution return (a+u*c*m)%modulus, modulus else: pass def solve_linear(a,b,n): g, c, _ = gcd(a,n) if b%g != 0: return None return ((b//g)*c) % n def powermod(a, m, n): assert m >= 0, "m must be nonnegative." assert n >= 1, "n must be positive." ans = 1 apow = a while m != 0: if m%2 != 0: ans = (ans * apow) % n apow = (apow * apow) % n m //= 2 return ans % n def sqrtmod(a, p): # after code in forthcoming Springer book by Stein a %= p if p == 2: return a assert legendre(a, p) == 1, "a must be a square mod p." if p%4 == 3: return powermod(a, (p+1)//4, p) def mul(x, y): return ((x[0]*y[0] + a*y[1]*x[1]) % p, (x[0]*y[1] + x[1]*y[0]) % p) def pow(x, n): ans = (1,0) xpow = x while n != 0: if n%2 != 0: ans = mul(ans, xpow) xpow = mul(xpow, xpow) n //= 2 return ans while True: z = whrandom.randrange(2,p) u, v = pow((1,z), (p-1)//2) if v != 0: vinv = inverse(v, p) for x in [-u*vinv, (1-u)*vinv, (-1-u)*vinv]: if (x*x)%p == a: return x%p assert False, "Bug in sqrtmod." def real_class_number(d): #class number of real quadratic field with discriminant d =0,1 mod 4 counter=0 arrayB=[] # sammelt b's array2C=[] # sammelt 2c's class_number=0 f=int(math.floor(math.sqrt(d))) t=f*f if t==d: #print "d ist Quadrat" return u=d%4 if u<>0 and u<>1: #print "d ist nicht 0,1 mod 4" return if u==1: e=1 else: e=2 g = f//2; for a in range(1,f+1): for b in range(e,f+1,2): h = b*b - d i = 2*a j = 4*a if (h%j == 0) and (a<= g and f-i < b): #test reduced ! c = -h//j done=0 for i in range(0,counter): if (b==arrayB[i]) and (2*c==array2C[i]): done=1 if (gcd(gcd(a, b)[0],c)[0] == 1) and done==0: u,v=b,2*c s,r=v,u k=counter while (counter==k) or (s<>v or u<>r): a=(f+u)//v u=a*v-u v=(d-u*u)//v arrayB.append(u) array2C.append(v) counter=counter+1 class_number = class_number + 1 #print "Reduzierte Form [", class_number, "]: (", a, ",", b, ",", -c, ")" #print "Zykellaenge=", counter-k else: pass return class_number def imaginary_class_number(d): # class number of imaginary quadratic field with discriminant -d =0,1 mod 4 # d = abs(d) f=int(math.floor(math.sqrt(d))) t=f*f if t==d: #print "d ist Quadrat" return u=-d%4 if u<>0 and u<>1: #print "d ist nicht 0,1 mod 4" return h = 0 g = 1 if d%4 == 0: b = 0 else: b = 1 bound = math.sqrt(d//3) while b <= bound: q =(b**2+d)//4 a = b if a <= 1: a = 1 while a**2 <= q: if q%a == 0: t=q//a ggt=gcd(a,b)[0] ggt=gcd(ggt,t)[0] if ggt > 1: g = 0 if g == 1: if a == b or a**2 == q or b == 0: h = h+1 else: h = h+2 else: g = 1 a = a+1 b = b+2 return h def pollard(N, m): for a in [2, 3]: x = powermod(a, m, N) - 1 g = gcd(x, N)[0] if g != 1 and g != N: return g return N def randcurve(m): assert m > 2, "m must be > 2." a = whrandom.randrange(m) while gcd(4*a**3 + 27, m)[0] != 1: a = whrandom.randrange(m) return (a, 1, m), (0,1) def elliptic_curve_method(N, m, tries=5): for _ in range(tries): E, P = randcurve(N) try: Q = ellcurve_mul(E, m, P) except ZeroDivisionError, x: g = gcd(x[0],N)[0] if g != 1 or g != N: return g return N def ellcurve_add(E, P1, P2): a, b, p = E assert p > 2, "p must be odd." if P1 == "Identity": return P2 if P2 == "Identity": return P1 x1, y1 = P1; x2, y2 = P2 x1 %= p; y1 %= p; x2 %= p; y2 %= p if x1 == x2 and y1 == p-y2: return "Identity" if P1 == P2: if y1 == 0: return "Identity" lam = (3*x1**2+a) * inverse(2*y1,p) else: lam = (y1 - y2) * inverse(x1 - x2, p) x3 = lam**2 - x1 - x2 y3 = -lam*x3 - y1 + lam*x1 return (x3%p, y3%p) def ellcurve_mul(E, m, P): assert m >= 0, "m must be nonnegative." power = P mP = "Identity" while m != 0: if m%2 != 0: mP = ellcurve_add(E, mP, power) power = ellcurve_add(E, power, power) m /= 2 return mP def lcm_to(B): ans = 1 logB = math.log(B) for p in primes(B): ans *= p**int(logB/math.log(p)) return ans def miller_rabin(n, num_trials=4): if n < 0: n = -n if n in [2,3]: return True if n <= 4: return False m = n - 1 k = 0 while m%2 == 0: k += 1; m /= 2 # Now n - 1 = (2**k) * m with m odd for i in range(num_trials): a = whrandom.randrange(2,n-1) apow = powermod(a, m, n) if not (apow in [1, n-1]): some_minus_one = False for r in range(k-1): apow = (apow**2)%n if apow == n-1: some_minus_one = True break if (apow in [1, n-1]) or some_minus_one: prob_prime = True else: return False return True def gen(n,c=1): x = 1 while True: x = (x**2 + c) % n yield x def rho(n, max=500, maxc=10): # Pollard's Rho Method seqslow = gen(n) seqfast = gen(n) trials = 0 c = 1 while c < maxc: while trials < max: xb = seqslow.next() seqfast.next() xk = seqfast.next() trials += 1 diff = abs(xk-xb) if not diff: continue d = gcd(diff,n)[0] if n>d>1: return rho(d, max, maxc) + rho(n//d, max, maxc) c += 1 seqslow = gen(n,c) seqfast = gen(n,c) trials = 0 return [n] # failure to factor def sum(v): if len(v) == 0: return 0 return reduce(operator.add, v) def ggt(a,b): while b !=0: a,b=b,a%b return a def isInteger(n): return type(n) in (int, long) class Rational (object): def operators(self): pass def __init__(self, p, q=1): if type(p) == str: # z.B. '3/17' l = p.split('/') p = int(l[0]) if len(l) > 1: q = int(l[1]) p=int(p) if q < 0: p,q = -p, -q d = ggt(abs(p), q) if d > 1: p //= d q //= d self.p = p self.q = q def __abs__(self): return Rational(abs(self.p), self.q) # def abs(self): # return A - B def __float__(self): return float(self.p) / float(self.q) def __int__(self): assert self.q > 0 return (self.p + self.q/2) // self.q def __long__(self): assert self.q > 0 return (self.p + self.q/2) // self.q def _unify(self, other): return (self, Rational(other)) def __repr__(self): if self.q == 1: return str(self.p) else: return '%d/%d' % (self.p, self.q) def __cmp__(a, b): if type(b) == float: return cmp(float(a), b) if not isinstance(b, Rational): a,b = a._unify(b) return cmp(a.p*b.q, b.p*a.q) def __neg__(self): return Rational(-self.p, self.q) def neg(self): return A + B def __add__(a, b): if type(b) == float: return float(a) + b if not isinstance(b, Rational): a,b = a._unify(b) return Rational(a.p*b.q + b.p*a.q, a.q*b.q) def add(a,b): return a + b def __radd__(a, b): return a + b def __sub__(a, b): if type(b) == float: return float(a) - b if not isinstance(b, Rational): a,b = a._unify(b) return Rational(a.p*b.q - b.p*a.q, a.q*b.q) def sub(a,b): return a - b def __rsub__(b, a): if type(a) == float: return a - float(b) if not isinstance(a, Rational): b,a = b._unify(a) return a - b def __mul__(a, b): if type(b) == float: return float(a) * b if not isinstance(b, Rational): a,b = a._unify(b) return Rational(a.p*b.p, a.q*b.q) def mul(a,b): return a * b def __rmul__(b, a): return b * a def __div__(a, b): if type(b) == float: return float(a) / b if not isinstance(b, Rational): a,b = a._unify(b) return Rational(a.p*b.q, a.q*b.p) def div(a,b): return a * b def __rdiv__(b, a): if type(a) == float: return a / float(b) if not isinstance(a, Rational): b,a = b._unify(a) return Rational(a.p*b.q, a.q*b.p) def __truediv__(a, b): return a.__div__(b) def __rtruediv__(a, b): return a.__rdiv__(b) def __floordiv__(a, b): return a.__div__(b) def __rfloordiv__(a, b): return a.__rdiv__(b) def toNumber(s): if '.' in s or 'e' in s or 'E' in s: return float(s) else: return Rational(s) class Vector (list): def operators(self): pass def __init__(v, n): if isinstance(n, list): list.__init__(v, n) elif isinstance(n, tuple): list.__init__(v, list(n)) def __repr__(A): """ Darstellung des Objekts als String """ return 'Vector(%s)' % list.__repr__(A) def __invert__(v): """ v.__invert__()
Transposition
berechnet die transponierte Matrix (Spaltenvektor)
Auch Operatorschreibweise: ~v
""" return Matrix([[a] for a in v]) def transp(v): """ v.transp()
berechnet die transponierte Matrix (Spaltenvektor)
kürzer: ~v """ return Matrix([[a] for a in v]) def concat(x, y): """ .concat(v)
Verkettung mit dem Vektor v """ return Vector(list(x)+list(y)) def __neg__(v): return Vector([-x for x in v]) def __add__(x, y): n = len(x) assert n == len(y) return Vector([x[i]+y[i] for i in range(n)]) def __radd__(a, b): return a + b def __sub__(x, y): return x + (-y) def __rsub__(y, x): return x - y def __mul__(x, y): if isinstance(y, Vector): n = len(x) assert n == len(y) return sum([x[i]*y[i] for i in range(n)]) else: return Vector([y*x[i] for i in range(len(x))]) def __rmul__(x, c): return x * c def __imul__(x, c): for i in range(len(x)): x[i] *= c return x class Matrix (Vector): def operators(self): pass def __init__(A, v): Vector.__init__(A, [Vector(v[i]) for i in range(len(v))]) A._makeRational() def null(m, n=0): if n == 0: n = m return Matrix([ [0 for k in range(n)] for i in range(m)]) # @staticmethod def fromFunction(m, n, fn, offset=0): return Matrix([ [fn(i,k) for k in range(n)] for i in range(m)]) # @staticmethod def fromString(s): return Matrix([ [toNumber(a) for a in row.split(',')] for row in s.split(';')]) def _makeRational(A): for i in A.rowRange(): for k in A.colRange(): if isInteger(A[i,k]): A[i,k] = Rational(A[i,k]) def copy(A): return Matrix([ [A[i,k] for k in A.colRange()] for i in A.rowRange()]) def isSquare(A): return A.height() == A.width() def str(A, i,k): if type(A[i,k]) == float: return '%g' % A[i,k] else: return str(A[i,k]) def _getColWidth(A, k): return max([len(A.str(i,k)) for i in A.rowRange()]) def _pp(A, name=''): w = [A._getColWidth(k) for k in A.colRange()] strW = sum(w) + 3 * (A.width()-1) if A.height() == 1: left, right = '[', ']' else: mid = (2*A.height()-3) * '|' left, right = '/'+mid+'\\', '\\'+mid+'/' s = '' fill = len(name) * ' ' n = 2*A.height()-1 for j in range(n): if j == A.height()-1: s += name else: s += fill i = j // 2 if j % 2 == 0: s += left[j] + ' ' for k in A.colRange(): s += A.str(i,k).center(w[k]) if k < A.width()-1: s += ' ' s += ' ' + right[j] + '\n' else: s += '|' + (strW+2) * ' ' + '|\n' return s def __repr__(A): return A._pp() def __getitem__(A, i): if isinstance(i, tuple): return A[i[0]][i[1]] else: return Vector.__getitem__(A, i) def __setitem__(A, i, x): if isinstance(i, tuple): A[i[0]][i[1]] = x else: Vector.__setitem__(A, i, x) def height(A): #Zeilenzahl return len(A) def width(A): #Spaltenzahl return len(A[0]) def rowRange(A): return range(A.height()) def colRange(A): return range(A.width()) def __neg__(A): return Matrix([ [-A[i,k] for k in A.colRange()] for i in A.rowRange()]) def __cmp__(A, B): if A.heigth() != B.heigth(): return A.heigth() - B.heigth() for i in A.rowRange(): if A[i] != A[i]: return cmp(A[i], B[i]) return 0 def concat(A, B): assert A.height() == B.height() return Matrix([ list(A[i])+list(B[i]) for i in A.rowRange()]) def __add__(A, B): assert A.height() == B.height() and A.width() == B.width() return Matrix([ [A[i,k]+B[i,k] for k in A.colRange()] for i in A.rowRange() ]) def __sub__(A, B): return A + (-B) def __mul__(A, B): # Wenn beide Operanden Matrizen sind wird Matrizenmultiplikation durchgeführt, # sonst Skalarmultiplikation if isinstance(B, Matrix): # Matrizenmultiplikation assert A.width() == B.height() return Matrix( [ [ sum([A[i,j] * B[j,k] for j in A.colRange()]) for k in B.colRange()] for i in A.rowRange()]) else: # Skalarmultiplikation return Matrix([ [B*A[i,k] for k in A.colRange()] for i in A.rowRange()]) def __rmul__(A, B): assert not isinstance(B, Matrix) return A * B def transp(A): return Matrix([ [A[i,k] for i in A.rowRange()] for k in A.colRange()]) def __invert__(A): return A.transp() def submatrix(A, i, k, m, n): assert i+m-1 < A.height() and k+n-1 < A.width() return Matrix([ [A[i1,k1] for k1 in range(k,k+n)] for i1 in range(i,i+m)]) def complement(A, i, k): return Matrix([ [A[i1,k1] for k1 in A.colRange() if k1 != k] for i1 in A.rowRange() if i1 != i]) def minor(A, i, k): return A.complement(i,k).det() def cofactor(A, i, k): return (-1)**(i+k) * A.minor(i,k) def adjoint(A): assert A.isSquare() return Matrix([ [A.cofactor(k,i) for k in A.rowRange()] for i in A.colRange()]) def det(A): if not A.isSquare(): raise 'Matrix ist nicht quadratisch' n = A.height() if n == 1: return A[0,0] else: return sum([A[0,k] * A.cofactor(0,k) for k in A.colRange()]) def _gaussElim0(A, jordan=True): m, n = A.height(), A.width() k = 0 for i0 in A.rowRange(): k = i0 # oberste Zeile für führende Eins passend durchmultiplizieren A[i0] *= 1/A[i0,k] # Passende Vielfache zu anderen Zeilen addieren, so dass # unterhalb der führenden Eins Nullen entstehen for i in range(i0+1, m): A[i] -= A[i0] * A[i,k] if jordan: # Gauß-Jordan: dto. auch oberhalb der führenden Eins for i in range(i0): A[i] -= A[i0] * A[i,k] def gaussElim(A, jordan=True): m, n = A.height(), A.width() k = -1 for i0 in A.rowRange(): # Bestimme die am weitesten links stehende Spalte k, die # (ab Zeile i0) von Null verschiedene Elemente enthält: k += 1 aMax, iMax = 0, i0 while aMax == 0 and k < n: for i in range(i0,m): if abs(A[i,k]) >aMax: aMax, iMax = abs(A[i,k]), i if aMax == 0: k += 1 if k < n: # Oberste Zeile mit der vertauschen, die das (dem Betrag nach) # größte Element in Spalte i0 enthält A[iMax], A[i0] = A[i0], A[iMax] # oberste Zeile für führende Eins passend durchmultiplizieren A[i0] *= 1/A[i0,k] # Passende Vielfache zu anderen Zeilen addieren, so dass # unterhalb der führenden Eins Nullen entstehen for i in range(i0+1, m): A[i] -= A[i0] * A[i,k] if jordan: # Gauß-Jordan: dto. auch oberhalb der führenden Eins for i in range(i0): A[i] -= A[i0] * A[i,k] def inverse(A): if not A.isSquare(): raise 'not a square matrix' n = A.height() I=Matrix([ [int(i==k) for k in range(n)] for i in range(n)]) B = A.concat(I) B.gaussElim() if B.submatrix(0,0,n,n) != I: raise 'matrix not invertible' return B.submatrix(0,n,n,n) def solve(A, b): if not isinstance(b, Matrix): assert isinstance(b, Vector) b = b.transp() v=A.inverse() * b return v.transp() ############## Beginning of Math Lab ################# def single_number_query(string): a=appuifw.query(string, 'float') if a is None: pass else: return a def single_text_query(string,default=u"0"): a=appuifw.query(string, 'text',default) if a is None: pass else: return a def double_text_query(string1, string2): a=appuifw.query(string1, 'text') if a is None: pass else: b=appuifw.query(string2, 'text') if b is None: pass else: return a,b def double_number_query(string1, string2): a=appuifw.query(string1, 'number') if a is None: pass else: b=appuifw.query(string2, 'number') if b is None: pass else: return a,b def triple_number_query(string1, string2, string3): a=appuifw.query(string1, 'number') if a is None: pass else: b=appuifw.query(string2, 'number') if b is None: pass else: c=appuifw.query(string3, 'number') if c is None: pass else: return a,b,c class mathlab: def __init__(self): self.script_lock = e32.Ao_lock() def run(self): choices=[u"Topics:", u"Arithmetic", u"Linear Algebra", u"Calculator", u"Combinatorics"] from key_codes import EKeyLeftArrow self.lb = appuifw.Listbox(choices, self.math) self.lb.bind(EKeyLeftArrow, lambda: self.math(0)) old_title = appuifw.app.title self.refresh() self.script_lock.wait() appuifw.app.title = old_title appuifw.app.body = None self.lb = None def refresh(self): appuifw.app.title = u"Python Math Lab 0.8" appuifw.app.menu = [] appuifw.app.exit_key_handler = self.exit_key_handler appuifw.app.body = self.lb def do_exit(self): self.exit_key_handler() def exit_key_handler(self): appuifw.app.exit_key_handler = None self.script_lock.signal() def display(self,t): if t is None: pass i=appuifw.query(u"Result:" + "\n" + t + "\n"+u"New computation?",'query') def math(self, ind = None): if not ind == None: index = ind else: index = self.lb.current() if index == 1: self.arithmetic() elif index == 3: self.calculator() elif index == 4: self.combinatorics() elif index == 2: self.linear_algebra() else: pass def arithmetic(self): menu1=[u"real classno", u"imaginary classno", u"factors", u"eratosthenes", u"lcm_to", u"pollard p-1", u"pollard rho", u"elliptic curve method", u"miller rabin", u"nextprime", u"jacobi symbol", u"gcd", u"lcm", u"eulerphi", u"contfrac", u"primitive root", u"modular power", u"chinese", u"modular inverse", u"modular sqrt", u"solve linear"] i=appuifw.popup_menu(menu1, u"Arithmetic functions:") if i is None: pass elif menu1[i] == u"miller rabin": d = single_number_query(u"number:") if d is None: self.arithmetic() else: ergebnis=miller_rabin(int(d)) if ergebnis is None: self.display(u"Not possible!") self.arithmetic() elif ergebnis: self.display(u"Probably prime") self.arithmetic() else: self.display(u"Probably not prime") self.arithmetic() elif menu1[i] == u"lcm_to": d = single_number_query(u"number:") if d is None: self.arithmetic() else: ergebnis=lcm_to(int(d)) if ergebnis is None: self.display(u"Not possible!") self.arithmetic() else: self.display(unicode(ergebnis)) self.arithmetic() elif menu1[i] == u"pollard rho": d = single_number_query(u"Number to factor:") if d is None: self.arithmetic() else: ergebnis=rho(int(d)) if ergebnis is None: self.display(u"No solution!") self.arithmetic() else: self.display(unicode(ergebnis)) self.arithmetic() elif menu1[i] == u"pollard p-1": d = double_number_query(u"Number to factor:", u"bound:") if d is None: self.arithmetic() else: ergebnis=pollard(int(d[0]),int(d[1])) if ergebnis is None: self.display(u"No solution!") self.arithmetic() else: self.display(u"One Factor is"+u" "+unicode(ergebnis)) self.arithmetic() elif menu1[i] == u"elliptic curve method": d = double_number_query(u"Number to factor:", u"bound:") if d is None: self.arithmetic() else: ergebnis=elliptic_curve_method(int(d[0]),int(d[1])) if ergebnis is None: self.display(u"No solution!") self.arithmetic() else: self.display(u"One Factor is" +u" "+unicode(ergebnis)) self.arithmetic() elif menu1[i] == u"chinese": d1 = double_number_query(u"1st residue:", u"1st modulus:") if d1 is None: self.arithmetic() else: d2 = double_number_query(u"2nd residue:", u"2nd modulus:") if d1 is None: self.arithmetic() else: ergebnis=chinese(int(d1[0]),int(d1[1]),int(d2[0]),int(d2[1])) if ergebnis is None: self.display(u"No solution!") self.arithmetic() else: self.display(unicode(ergebnis[0])+u" "+u"mod"+u" "+unicode(ergebnis[1])) self.arithmetic() elif menu1[i] == u"factors": n=single_number_query(u"number to factor:") if n is not None: ergebnis=factorlist(int(n)) self.display(unicode(ergebnis)) self.arithmetic() else: self.arithmetic() elif menu1[i] == u"eratosthenes": n=single_number_query(u"number to test:") if n is None: self.arithmetic() elif isprime(int(n)): ergebnis=n self.display(unicode(ergebnis)+u" "+u"is a prime.") self.arithmetic() else: ergebnis=n self.display(unicode(ergebnis) +u" "+u"is not a prime.") self.arithmetic() elif menu1[i] == u"imaginary classno": n=single_number_query(u"- discriminant:") if n is not None: ergebnis=imaginary_class_number(n) if ergebnis is None: self.display(u"d is square or not 0,1 mod 4!") self.arithmetic() else: self.display("class number is"+ " " + unicode(ergebnis)+".") self.arithmetic() else: self.arithmetic() elif menu1[i] == u"real classno": n=single_number_query(u"discriminant:") if n is not None: ergebnis=real_class_number(n) if ergebnis is None: self.display(u"d is square or not 0,1 mod 4!") self.arithmetic() else: self.display("class number is"+ " " + unicode(ergebnis)+".") self.arithmetic() else: self.arithmetic() elif menu1[i] == u"nextprime": n=single_number_query(u"number below:") if n is not None: ergebnis=nextprime(int(n)) self.display(u"next prime is"+ " "+ unicode(ergebnis)+ ".") self.arithmetic() else: self.arithmetic() elif menu1[i] == u"jacobi symbol": d=double_number_query(u"top number:", u"bottom number:") if d is not None: ergebnis=legendre(int(d[0]),int(d[1])) self.display(unicode(ergebnis)) self.arithmetic() else: self.arithmetic() elif menu1[i] == u"gcd": d=double_number_query(u"1st number:", u"2nd number:") if d is not None: ergebnis=unicode(gcd(d[0],d[1])) self.display(ergebnis) self.arithmetic() else: self.arithmetic() elif menu1[i] == u"lcm": d=double_number_query(u"1st number:", u"2nd number:") if d is None: self.arithmetic() else: ergebnis=lcm(d[0],d[1]) self.display(unicode(ergebnis)) self.arithmetic() elif menu1[i] == u"eulerphi": n=single_number_query(u"number:") if n is None: self.arithmetic() else: ergebnis=eulerphi(int(n)) self.display(unicode(ergebnis)) self.arithmetic() elif menu1[i] == u"contfrac": n=single_text_query(u"real number:") if n is None: self.arithmetic() else: ergebnis=contfrac(float(n)) self.display(unicode(ergebnis)) self.arithmetic() elif menu1[i] == u"primitive root": n=single_number_query(u"modulus:") if n is None: self.arithmetic() else: ergebnis=primitive_root(int(n)) self.display(unicode(ergebnis)) self.arithmetic() elif menu1[i] == u"modular power": d=triple_number_query(u"base:", u"exponent:", u"modulus:") if d is None: self.arithmetic() else: ergebnis=powermod(d[0],d[1],d[2]) self.display(unicode(ergebnis)) self.arithmetic() elif menu1[i] == u"solve linear": d=triple_number_query(u"number:", u"remainder:", u"modulus:") if d is None: self.arithmetic() else: ergebnis=solve_linear(d[0],d[1],d[2]) self.display(unicode(ergebnis)) self.arithmetic() elif menu1[i] == u"modular inverse": d=double_number_query(u"number:", u"modulus:") if d is None: self.arithmetic() else: ergebnis=inverse(int(d[0]),int(d[1])) self.display(unicode(ergebnis)) self.arithmetic() elif menu1[i] == u"modular sqrt": d=double_number_query(u"number:", u"modulus:") if d is None: self.arithmetic() else: ergebnis=sqrtmod(int(d[0]),int(d[1])) self.display(unicode(ergebnis)) self.arithmetic() else: self.arithmetic() def calculator(self): menu2=[u"pi", u"e", u"sin", u"cos", u"tan", u"sqrt", u"exp", u"log", u"addition", u"subtraction", u"multiplication",u"exponentiation", u"division"] j = appuifw.popup_menu(menu2, u"Calculator functions:") if j is None: pass elif menu2[j]== u"pi": ergebnis=math.pi self.display(unicode(ergebnis)) self.calculator() elif menu2[j] == u"e": ergebnis=math.e self.display(unicode(ergebnis)) self.calculator() elif menu2[j] == u"sin": n=single_number_query(u"argument:") if n is None: self.calculator() else: ergebnis=math.sin(float(n)) self.display(unicode(ergebnis)) self.calculator() elif menu2[j] == u"cos": n=single_number_query(u"argument:") if n is None: self.calculator() else: ergebnis=math.cos(float(n)) self.display(unicode(ergebnis)) self.calculator() elif menu2[j] == u"tan": n=single_number_query(u"argument:") if n is None: self.calculator() else: ergebnis=math.tan(float(n)) self.display(unicode(ergebnis)) self.calculator() elif menu2[j] == u"sqrt": n=single_number_query(u"argument:") if n is None: self.calculator() else: ergebnis=math.sqrt(float(n)) self.display(unicode(ergebnis)) self.calculator() elif menu2[j] == u"exp": n=single_number_query(u"argument:") if n is None: self.calculator() else: ergebnis=math.exp(float(n)) self.display(unicode(ergebnis)) self.calculator() elif menu2[j] == u"log": n=single_number_query(u"argument:") if n is None: self.calculator() else: ergebnis=math.log(float(n)) self.display(unicode(ergebnis)) self.calculator() elif menu2[j]== u"addition": n=single_text_query(u"add a+b:", u"1+1") if n is None: self.calculator() n=string.split(n,"+") if len(n)!=2: self.calculator() else: for i in range(2): if '/' in str(n[i]): n[i]=Rational(str(n[i])) else: n[i]=eval(n[i]) ergebnis=n[0]+n[1] self.display(unicode(ergebnis)) self.calculator() elif menu2[j]== u"subtraction": n=single_text_query(u"subtract a-b:", u"1-1") if n is None: self.calculator() n=string.split(n,"-") if len(n)!=2: self.calculator() else: for i in range(2): if '/' in str(n[i]): n[i]=Rational(str(n[i])) else: n[i]=eval(n[i]) ergebnis=n[0]-n[1] self.display(unicode(ergebnis)) self.calculator() elif menu2[j]== u"multiplication": n=single_text_query(u"multiply a*b:", u"1*1") if n is None: self.calculator() n=string.split(n,"*") if len(n)!=2: self.calculator() else: for i in range(2): if '/' in str(n[i]): n[i]=Rational(str(n[i])) else: n[i]=eval(n[i]) ergebnis=n[0]*n[1] self.display(unicode(ergebnis)) self.calculator() elif menu2[j]== u"division": n=single_text_query(u"divide a%b:", u"1%1") if n is None: self.calculator() n=string.split(n,"%") if len(n)!=2: self.calculator() else: for i in range(2): if '/' in str(n[i]): n[i]=Rational(str(n[i])) else: n[i]=eval(n[i]) if type(n[1])==int: n[1]=Rational(n[1]) ergebnis=n[0]/n[1] self.display(unicode(ergebnis)) self.calculator() elif menu2[j]== u"exponentiation": v=single_text_query(u"power a^b:", u"1^1") if v is None: self.calculator() v=string.split(v,"^") if len(v)!=2: self.calculator() else: a,b=[eval(z) for z in v] ergebnis=pow(a,b) self.display(unicode(ergebnis)) self.calculator() def combinatorics(self): menu3=[u"factorial", u"binomial", u"fibonacci"] k=appuifw.popup_menu(menu3, u"Combinatorial tools:") if k is None: pass elif menu3[k] == u"factorial": n=single_number_query(u"number:") if n is None: self.combinatorics() else: ergebnis=factorial(int(n)) self.display(unicode(ergebnis)) self.combinatorics() elif menu3[k] == u"binomial": d=double_number_query(u"top number:", u"botton number:") if d is None: self.combinatorics() else: ergebnis=binomial(int(d[0]),int(d[1])) self.display(unicode(ergebnis)) self.combinatorics() elif menu3[k] == u"fibonacci": n=single_number_query(u"number:") if n is None: self.combinatorics() else: ergebnis=fibonacci(int(n)) self.display(unicode(ergebnis)) self.combinatorics() def linear_algebra(self): menu4=[u"2x2 determinant", u"3x3 determinant", u"inverse 3x3 matrix", u"row echelon form", u"solve Av=b"] i=appuifw.popup_menu(menu4, u"Linear Algebra:") if i is None: pass elif menu4[i]== u"2x2 determinant": n=single_text_query(u"entries:", u"0,0,0,0") if n is None: self.linear_algebra() n=string.split(n,",") if len(n)!=4: self.linear_algebra() else: for i in range(4): if '/' in str(n[i]): n[i]=Rational(str(n[i])) else: n[i]=eval(n[i]) ergebnis= n[0]*n[3]-n[1]*n[2] self.display(unicode(ergebnis)) self.linear_algebra() elif menu4[i]== u"3x3 determinant": m=single_text_query(u"entries:",u"0,0,0,0,0,0,0,0,0") if m is None: self.linear_algebra() n=string.split(m,",") if len(n)!=9: self.linear_algebra() else: for i in range(9): if '/' in str(n[i]): n[i]=Rational(str(n[i])) else: n[i]=eval(n[i]) a1,a2,a3,b1,b2,b3,c1,c2,c3=[n[i] for i in range(9)] ergebnis=a1*(b2*c3-c2*b3)-a2*(b1*c3-c1*b3)+a3*(b1*c2-c1*b2) self.display(unicode(ergebnis)) self.linear_algebra() elif menu4[i]== u"inverse 3x3 matrix": m=single_text_query(u"entries:",u"0,0,0,0,0,0,0,0,0") if m is None: self.linear_algebra() m=string.split(m,",") if len(m)!=9: self.linear_algebra() else: for i in range(9): if '/' in str(m[i]): m[i]=Rational(str(m[i])) else: m[i]=eval(m[i]) M=Matrix([[m[0],m[1],m[2]],[m[3],m[4],m[5]],[m[6],m[7],m[8]]]) if M.det()==0: self.display(u"Matrix is not invertible.") self.linear_algebra() else: N=M.inverse() ergebnis=N[0,0],N[0,1],N[0,2],N[1,0],N[1,1],N[1,2],N[2,0],N[2,1],N[2,2] self.display(unicode(ergebnis)) self.linear_algebra() elif menu4[i]== u"solve Av=b": d=single_text_query(u"Matrix A:", u"0,0,0,0,0,0,0,0,0") if d is None: self.linear_algebra() e=single_text_query(u"vector b:", u"0,0,0") if e is None: self.linear_algebra() m=string.split(d,",") n=string.split(e,",") if len(n)!=3 or len(m)!=9: self.linear_algebra() else: for i in range(9): if '/' in str(m[i]): m[i]=Rational(str(m[i])) else: m[i]=eval(m[i]) M=Matrix([[m[0],m[1],m[2]],[m[3],m[4],m[5]],[m[6],m[7],m[8]]]) if M.det()==0: self.display(u"Matrix is not invertible, use row echelon form.") self.linear_algebra() else: for i in range(2): if '/' in str(n[i]): n[i]=Rational(str(n[i])) else: n[i]=eval(n[i]) v=Vector([n[0],n[1],n[2]]) ergebnis=Matrix.solve(M,v) self.display(unicode(ergebnis)) self.linear_algebra() elif menu4[i]== u"row echelon form": n=single_text_query(u"entries:", u"0,0,0,0,0,0,0,0,0") if n is None: self.linear_algebra() n=string.split(n,",") if len(n)!=9: self.linear_algebra() else: for i in range(9): if '/' in str(n[i]): n[i]=Rational(str(n[i])) else: n[i]=eval(n[i]) N=Matrix([[n[0],n[1],n[2]],[n[3],n[4],n[5]],[n[6],n[7],n[8]]]) N.gaussElim(jordan=False) ergebnis=[N[0,0],N[0,1],N[0,2]],[N[1,0],N[1,1],N[1,2]],[N[2,0],N[2,1],N[2,2]] self.display(unicode(ergebnis)) self.linear_algebra() if __name__ == '__main__': mathlab().run()