# -*- 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()