QR.py 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import numpy as np
  2. import Tools
  3. from numpy.linalg import qr
  4. import math
  5. def randomIsometry(rows,cols,rank):
  6. if rank==1:
  7. r=np.random.randn(rows)
  8. r = Tools.normalize(r)[np.newaxis]
  9. c=np.random.randn(cols)
  10. c = Tools.normalize(c)[np.newaxis]
  11. result=r.T.dot(c)
  12. else:
  13. a = np.random.randn(rows,rows)
  14. b = np.random.randn(cols,cols)
  15. diagDim = min(rows,cols)
  16. d = np.zeros((rows,cols))
  17. diag = np.ones(diagDim)
  18. diag[rank:] = 0
  19. np.fill_diagonal(d,diag)
  20. qa,_ = qr(a)
  21. qb,_ = qr(b)
  22. result = qa .dot(d.dot(qb))
  23. return(result)
  24. def kahan_matrix(rows):
  25. cols = rows
  26. eps = np.finfo(np.float32).eps
  27. s = math.pow(eps,1.0/rows)
  28. c = math.sqrt(1-s*s)
  29. m = np.zeros((rows,cols))
  30. sc = 1.0
  31. for i in range(rows-1):
  32. m[i,i] = sc
  33. m[i,i+1:] = - sc * c * np.ones(rows-i-1)
  34. sc = sc * s
  35. m = m + m.T
  36. return(m)
  37. def householder(x,eps=1e-16):
  38. #print(x)
  39. v=np.hstack([[1],x[1:]])
  40. alpha = x[0]
  41. xnorm2=x[1:].dot(x[1:])
  42. epsilon=eps
  43. #print(sigma)
  44. if xnorm2<=epsilon:
  45. tau = 0.0
  46. v = np.zeros(len(x))
  47. else:
  48. if np.sign(alpha) <= 0:
  49. beta = math.sqrt(alpha*alpha + xnorm2)
  50. else:
  51. beta = -math.sqrt(alpha*alpha + xnorm2)
  52. r = (alpha - beta)
  53. v = x / r
  54. tau = (beta - alpha) / beta
  55. v[0] = 1
  56. return(v,tau)
  57. def QR(oldm,eps=1e-16):
  58. m=np.copy(oldm)
  59. (rows,cols) = m.shape
  60. hvects=[]
  61. tau=[]
  62. h=[]
  63. for c in range(cols):
  64. currentSize = rows - c
  65. v,beta=householder(m[c:,c],eps=eps)
  66. tau.append(beta)
  67. h.append(v)
  68. hvects.append((v,beta))
  69. t = np.identity(currentSize) - beta * np.outer(v,v)
  70. m[c:,c:] = np.dot(t,m[c:,c:])
  71. hvects.reverse()
  72. q=np.identity(rows)
  73. c=cols - 1
  74. for (v,beta) in hvects:
  75. t = np.identity(len(v)) - beta * np.outer(v,v)
  76. q[c:,c:] = np.dot(t,q[c:,c:])
  77. c = c - 1
  78. return(q,m,tau,h)