example_1_5.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. # New functions for version 1.5 of the Python wrapper
  2. import cmsisdsp as dsp
  3. import cmsisdsp.fixedpoint as f
  4. import numpy as np
  5. import math
  6. import colorama
  7. from colorama import init,Fore, Back, Style
  8. from numpy.testing import assert_allclose
  9. from numpy.linalg import qr
  10. def householder(x,eps=1e-16):
  11. #print(x)
  12. v=np.hstack([[1],x[1:]])
  13. alpha = x[0]
  14. xnorm2=x[1:].dot(x[1:])
  15. epsilon=eps
  16. #print(sigma)
  17. if xnorm2<=epsilon:
  18. tau = 0.0
  19. v = np.zeros(len(x))
  20. else:
  21. if np.sign(alpha) <= 0:
  22. beta = math.sqrt(alpha*alpha + xnorm2)
  23. else:
  24. beta = -math.sqrt(alpha*alpha + xnorm2)
  25. r = (alpha - beta)
  26. v = x / r
  27. tau = (beta - alpha) / beta
  28. v[0] = 1
  29. return(v,tau)
  30. init()
  31. def printTitle(s):
  32. print("\n" + Fore.GREEN + Style.BRIGHT + s + Style.RESET_ALL)
  33. def printSubTitle(s):
  34. print("\n" + Style.BRIGHT + s + Style.RESET_ALL)
  35. printTitle("Householder")
  36. VECDIM = 10
  37. a=np.random.randn(VECDIM)
  38. a = a / np.max(np.abs(a))
  39. # Reference
  40. vRef,betaRef = householder(a)
  41. printSubTitle("Householder F32")
  42. betaF32,vF32 = dsp.arm_householder_f32(a,dsp.DEFAULT_HOUSEHOLDER_THRESHOLD_F32)
  43. print(np.isclose(betaRef,betaF32,1e-6,1e-6))
  44. print(np.isclose(vRef,vF32,1e-6,1e-6))
  45. printSubTitle("Householder F64")
  46. betaF64,vF64 = dsp.arm_householder_f64(a,dsp.DEFAULT_HOUSEHOLDER_THRESHOLD_F64)
  47. print(np.isclose(betaRef,betaF64,1e-6,1e-6))
  48. print(np.isclose(vRef,vF64,1e-6,1e-6))
  49. printSubTitle("Householder Proportional F32")
  50. a=np.random.randn(5)
  51. # With the threshold defined with DEFAULT_HOUSEHOLDER_THRESHOLD_F32
  52. # this vector is considered as proportional to (1,0,...)
  53. # and thus the function will return (0,[0,...,0])
  54. a = a / np.max(np.abs(a)) * 1.0e-7
  55. resF32 = dsp.arm_householder_f32(a,dsp.DEFAULT_HOUSEHOLDER_THRESHOLD_F32)
  56. print(resF32)
  57. # With a smaller threshold, a computation is taking place
  58. resF32 = dsp.arm_householder_f32(a,0.001*dsp.DEFAULT_HOUSEHOLDER_THRESHOLD_F32)
  59. print(resF32)
  60. printTitle("QR decomposition")
  61. def checkOrtho(A,err=1e-10):
  62. product = A.T.dot(A)
  63. #print(A)
  64. np.fill_diagonal(product,0)
  65. #print(product)
  66. print(np.max(np.abs(product)))
  67. return (np.all(np.abs(product)<=err))
  68. rows = 8
  69. columns = 5
  70. def randomIsometry(rows,cols,rank):
  71. if rank==1:
  72. r=np.random.randn(rows)
  73. r = Tools.normalize(r)[np.newaxis]
  74. c=np.random.randn(cols)
  75. c = Tools.normalize(c)[np.newaxis]
  76. result=r.T.dot(c)
  77. else:
  78. a = np.random.randn(rows,rows)
  79. b = np.random.randn(cols,cols)
  80. diagDim = min(rows,cols)
  81. d = np.zeros((rows,cols))
  82. diag = np.ones(diagDim)
  83. diag[rank:] = 0
  84. np.fill_diagonal(d,diag)
  85. qa,_ = qr(a)
  86. qb,_ = qr(b)
  87. result = qa .dot(d.dot(qb))
  88. return(result)
  89. m = randomIsometry(rows,columns,columns-1)
  90. rows,columns = m.shape
  91. # The CMSIS-DSP C functions is requiring two temporary arrays
  92. # To follow the C function as closely as possible, we create
  93. # two arrays. Their size will be used internally by the Python
  94. # wrapper to allocate two temporary buffers.
  95. # Like that you can check you have dimensionned the arrays in the
  96. # right way.
  97. # The content of the temporary buffers is not accesible from the
  98. # Python API. tmpa and tmpb are not modified.
  99. tmpa=np.zeros(rows)
  100. tmpb=np.zeros(rows)
  101. printSubTitle("QR F64")
  102. status,r,q,tau = dsp.arm_mat_qr_f64(m,dsp.DEFAULT_HOUSEHOLDER_THRESHOLD_F64,tmpa,tmpb)
  103. # Status different from 0 if matrix dimensions are not right
  104. # (rows must be >= columns)
  105. #print(status)
  106. #print(q)
  107. #print(r)
  108. #print(tau)
  109. # Check that the matrix Q is orthogonal
  110. assert(checkOrtho(q,err=1e-14))
  111. # Remove householder vectors from R matrix
  112. i=1
  113. for c in r.T:
  114. c[i:] = 0
  115. i = i+1
  116. # Check that M = Q R
  117. newm = np.dot(q,r)
  118. assert_allclose(newm,m)
  119. printSubTitle("QR F32")
  120. status,r,q,tau = dsp.arm_mat_qr_f32(m,dsp.DEFAULT_HOUSEHOLDER_THRESHOLD_F32,tmpa,tmpb)
  121. # Status different from 0 if matrix dimensions are not right
  122. # (rows must be >= columns)
  123. #print(status)
  124. #print(q)
  125. #print(r)
  126. #print(tau)
  127. # Check that the matrix Q is orthogonal
  128. assert(checkOrtho(q,err=1.0e-6))
  129. # Remove householder vectors from R matrix
  130. i=1
  131. for c in r.T:
  132. c[i:] = 0
  133. i = i+1
  134. # Check that M = Q R
  135. newm = np.dot(q,r)
  136. assert_allclose(newm,m,2e-6,1e-7)