Advertisement
miklis

Untitled

Apr 22nd, 2014
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. from itertools import* #reikalinga funkcijai starmap
  2. from math import* # to get pi
  3. from numbers import* #to solve equations with complex numbers
  4. #SKAICIU TEORIJA
  5. def primes(n, sieve=[False,False,True]): #by-need calculation of primes; not includes n
  6. #TEST1
  7. #sieve: [1,1,1,1,1,1,1,1,1,1]=[1]*10
  8. #possible primes [0,1,2,3,4,5,6,7,8,9]
  9. #given sieve [0,0,1,1,0]
  10. #a=3
  11. #check from 0 to sqrt(len(sieve))
  12. #last five entries were checked dividing by primes 0 to a=3
  13. #sieve is given as list of bools to save memory
  14. #TEST2
  15. #primes(20) returns [2, 3, 5, 7, 11, 13, 17, 19], sieve is [False, False, True]
  16. #after that primes(30) returns [2, 3, 5, 7, 11, 13, 17, 19, 23, 29], taken sieve is list of bools with len=20
  17. #print sieve - get a primary sieve
  18. if len(sieve)<n:
  19. a=len(sieve)
  20. sieve+=[True]*(n-a)
  21. i=1
  22. while i<=int((n-1)**0.5):
  23. i+=1
  24. if sieve[i]:
  25. for j in range(max(2*i, a+(i-a)%i),n,i): sieve[j]=False
  26. return [i for i in range(n) if sieve[i]]
  27. from time import*
  28. def factor(num):
  29. product=[]
  30. t=time()
  31. if num==0: return 0
  32. if num<0: return None
  33. for n in primes(int(num**0.5)+1):
  34. while num%n==0:
  35. if time()-t>2: break
  36. product.append(n)
  37. num/=n
  38. if num==1: break
  39. if num<>1: return product+[num]
  40. return product
  41. def divisors(num):
  42. if num<1: return None
  43. def multiply(array):
  44. k=1
  45. for n in array: k*=n
  46. return k
  47. M=tuple(factor(num))
  48. return list(map(lambda x: multiply(x), product(*[[n**i for i in range(M.count(n)+1)] for n in set(M)])))
  49. #POLINOMU OPERACIJOS, kur a+bx+cx^2+...=[a,b,c...]
  50. def divide(P1,P2):
  51. residue=[]
  52. Pol=[n for n in P1]
  53. if len(P2)<2: return
  54. from time import*
  55. t=time()
  56. while len(P2)<=len(Pol):
  57. if time()-t>2:
  58. break
  59. print 'Serious error in polynomial division'
  60. coef=Pol[0]/float(P2[0])
  61. residue.append(coef)
  62. del(Pol[0])
  63. for i in range(len(P2)-1):
  64. Pol[i]-=coef*P2[i+1]
  65. if Pol==[0]: return residue
  66. def roots(pol):
  67. pol=[float(n) for n in pol]
  68. deg=max([i for i in range(len(pol)) if pol[i]<>0])
  69. if deg==0: return None
  70. elif deg==1: return [-pol[0]/pol[1]]
  71. elif deg==2:
  72. a,b,c=pol[2],pol[1],pol[0]
  73. D=b*b-4*a*c
  74. if D<0: return [(-b-(0+1j)*(-D)**0.5)/(2*a), (-b+(0+1j)*(-D)**0.5)/(2*a)]
  75. else: return [(-b-D**0.5)/(2*a), (-b+D**0.5)/(2*a)]
  76. #Given ax^3+bx^2+cx+d=0. Reduce to x^3+ax^2+bx+c=0. Substitute x=y-a/3.
  77. #Reduce to y^3+yp+q=0. Substitute y=z-p/3z. Got z^6+qz^3-p^3/27=0
  78. elif deg==3: #kinda mystics why half of solutions can be omitted
  79. a,b,c=pol[2]/pol[3],pol[1]/pol[3],pol[0]/pol[3]
  80. p,q=b-a*a/3, c+2*a*a*a/27-a*b/3
  81. unity=[cos(2*pi*i/3)+sin(2*pi*i/3)*(0+1j) for i in range(3)]
  82. solve_z=(roots([-p*p*p/27, q, 1])[0]+0j)**(1./3) #solved for z
  83. zs=[solve_z*unity[i] for i in range(3)]
  84. ys=[z-p/(3*z) for z in zs]
  85. return [y-a/3 for y in ys]
  86. elif deg==4: #Reduce to y^4=py^2+qy+r
  87. a,b,c,d=pol[3]/pol[4],pol[2]/pol[4],pol[1]/pol[4], pol[0]/pol[4]
  88. p,q,r=3*a*a/8-b, a*b/2-a*a*a/8-c,3*a**4/256-a*a*b/16+a*c/4-d
  89. #print p,q,r, [4*p*r-q*q,8*r,4*p,8]
  90. D=roots([4*p*r-q*q,8*r,4*p,8]) #solving cubics for a constant :)
  91. if D[0].imag<D[1].imag: t=D[0].real
  92. else: t=D[1].real #choosing real root
  93. pre=((2*t+p+0j)**0.5).real
  94. return [x-a/4 for x in roots([t+pre*q/(2*(2*t+p)),pre,1])+roots([t-pre*q/(2*(2*t+p)),-pre,1])]
  95. else:
  96. print "I can't solve for big degrees cuz I don't know how to approximate complex roots efficiently"
  97. return None
  98. #MATRICU OPERACIJOS
  99. def div(a,b): #norim, kad nebutu stufo, tokio kaip 0.0, o butu vietoj to sveikieji
  100. if float(a)/b==a/b: return a/b
  101. return float(a)/b
  102. def gcd(*args): #rasime skaiciu DBD
  103. def gcd_of_two(a,b):
  104. a,b=abs(a),abs(b)
  105. while a>0:
  106. if b>a: a,b=b,a
  107. if a==1: return 1
  108. a-=(a/b)*b
  109. return b
  110. return reduce(lambda x,y: gcd_of_two(x,y), args)
  111. def T(matrix): return zip(*matrix) #transponuota matrica
  112. def mul(*args):
  113. def simple_mul(matrix_a, matrix_b):#matricu daugyba
  114. if len(matrix_a[0])==len(matrix_b): return map(lambda x: tuple(sum(starmap(lambda j,k: k*j, zip(x,n))) for n in zip(*matrix_b)),matrix_a)
  115. return reduce(lambda x,y: simple_mul(x,y), args)
  116. def add(matrix_a, matrix_b, m1=1, m2=1):
  117. #sudetis m1*matrix_a+m2*matrix_b
  118. return [tuple(m1*matrix_a[i][j]+m2*matrix_b[i][j] for j in range(len(matrix_a[0]))) for i in range(len(matrix_a))]
  119. def scalmul(matrix,const): return [tuple(matrix[i][j]*const for j in range(len(matrix[0]))) for i in range(len(matrix))] #matrica dauginta is skaliaro
  120. def unit(length, diagonal=[]):
  121. if diagonal==[]: diagonal=[1]*length
  122. return [tuple(int(i==j)*diagonal[i] for i in range(length)) for j in range(length)] #vienetine matrica
  123. def inverse(matrix): #atvirkstines matricos algoritmas
  124. #EXAMPLE: [[a1,a2,x1,x2],[b1,b2,y1,y2]] ->[[a3,a4,a5,a6],[x3,x4,x5,x6]], nes tai ekvivalentu zingsniui
  125. # /a1 a2\|/1 0 x1 x2\ _______\ /1 0\|/a3 a4 a5 a6\
  126. # \b1 b2/|\0 1 y1 y2/ / \0 1/|\x3 x4 x5 x6/
  127. #rows can be longer than len of matrix; that case last terms means solutions to several systems of equations
  128. M=[[m for m in n] for n in matrix] #SIDE EFFECTS ARE ELIMINATED IN THIS ROW
  129. U=unit(len(M))
  130. order=[(i,j) for i in range(len(M)-1) for j in range(i+1,len(M))]+[(i,j) for i in range(len(M)-1,0,-1) for j in range(i-1,-1,-1)]
  131. #eiluciu keitimo tvarka, kai reikia suvesti i trikampi, po to i diagolini pavidala
  132. for i in range(len(M)):
  133. U[i]=U[i]+tuple(M[i][len(matrix):len(M[0])])
  134. #eiluciu sudejimo eiliskumas
  135. try:
  136. for n in order:
  137. i,j=n[0],n[1]
  138. if M[i][i]==0: # jei pasitaike nulinis elementas ant istrizaines, keiciame matricos eilutes. Jei neradome, ka sukeisti - nera atvirkstines matricos
  139. p=0
  140. for k in range(i+1,len(M)):
  141. if M[k][i]<>0:
  142. M[i],M[k]=M[k],M[i]
  143. U[i],U[k]=U[k],U[i]
  144. p=1
  145. break
  146. if p==0: return [M[i] for i in range(len(M)) if M[i][i]<>0] #bug we'll use later
  147. if M[j][i]<>0: #suvedimo i trikampi pavidala vienas zingsnis, kai uznulinama kazkuri eilute
  148. c=M[i][i]*M[j][i]/gcd(M[i][i], M[j][i])
  149. c1,c2=c/M[i][i],c/M[j][i]
  150. M[j]=tuple(map(lambda x: x[1]*c1-x[0]*c2, zip(M[j],M[i])))
  151. U[j]=tuple(map(lambda x: x[1]*c1-x[0]*c2, zip(U[j],U[i])))
  152. return map(lambda i: tuple(map(lambda x: div(x, M[i][i]),U[i])), range(len(U)))
  153. except IndexError: print 'Nesiskaiciuoja inverse, per daug eiluciu matricoje'
  154. #pradine matrica pasikeite i matrica su skaiciais ant istrizaines; jos istrizaine normalizavus, graziname U reiksme
  155. def rank(M): #gudras metodas, kur klaidos atveju inverse funkcijoje grazinamas tiesiskai nepriklausomu eiluciu matrica
  156. if len(M)>len(M[0]): return len(inverse(T(M))) #transponuojam, nes inverse taikosi tik siuo atveju
  157. else: return len(inverse(M))
  158. def det(matrix): #determinanto algoritmas - padaryta pagal inverse funkcija
  159. D=[]
  160. M=[[m for m in n] for n in matrix]
  161. order=[(i,j) for i in range(len(M)-1) for j in range(i+1,len(M))]
  162. for n in order:
  163. i,j=n[0],n[1]
  164. if M[i][i]==0: # jei pasitaike nulinis elememtas ant istrizaines, keiciame matricos eilutes. Jei neradome, ka sukeisti - det=0
  165. p=0
  166. for k in range(i+1,len(M)):
  167. if M[k][i]<>0:
  168. M[i],M[k]=M[k],M[i]
  169. p=1
  170. break
  171. if p==0: return 0
  172. if M[j][i]<>0: #suvedimo i trikampi pavidala vienas zingsnis, kai uznulinama kazkuri eilute
  173. c=M[i][i]*M[j][i]/gcd(M[i][i], M[j][i])
  174. c1,c2=c/M[i][i],c/M[j][i]
  175. D.append(-c2)
  176. M[j]=tuple(map(lambda x: x[1]*c1-x[0]*c2, zip(M[j],M[i])))
  177. if D<>[]: D=reduce(lambda x,y:x*y,D)
  178. else: D=1
  179. return reduce(lambda x,y: x*y, map(lambda i: M[i][i], range(len(M))))/D
  180. def solve_system(matrix): return [list(n) for n in zip(*inverse(matrix))[len(matrix):]]
  181. def chr_pol(M): #charakteristinis daugianaris, rastas aprepianciuju minoru pagalba
  182. def minors(M,k):
  183. L=len(M)
  184. #first row is elements of matrix with connection of order=[(M[n],M[n]) for n in second_row]
  185. #second_row says cyclic permutations with len=k of the sequence with len=L
  186. return [[[M[i][j] for j in n] for i in n] for n in [[x%L for x in range(i,i+k)] for i in range(L)]]
  187. return [sum([det(n) for n in minors(M,k)])*(-1)**k for k in range(len(M),0,-1)]+[1]
  188. def eigenvalues(M): return roots(chr_pol(M))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement