example_1_5.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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.linalg import qr
  9. def householder(x,eps=1e-16):
  10. #print(x)
  11. v=np.hstack([[1],x[1:]])
  12. alpha = x[0]
  13. xnorm2=x[1:].dot(x[1:])
  14. epsilon=eps
  15. #print(sigma)
  16. if xnorm2<=epsilon:
  17. tau = 0.0
  18. v = np.zeros(len(x))
  19. else:
  20. if np.sign(alpha) <= 0:
  21. beta = math.sqrt(alpha*alpha + xnorm2)
  22. else:
  23. beta = -math.sqrt(alpha*alpha + xnorm2)
  24. r = (alpha - beta)
  25. v = x / r
  26. tau = (beta - alpha) / beta
  27. v[0] = 1
  28. return(v,tau)
  29. init()
  30. def printTitle(s):
  31. print("\n" + Fore.GREEN + Style.BRIGHT + s + Style.RESET_ALL)
  32. def printSubTitle(s):
  33. print("\n" + Style.BRIGHT + s + Style.RESET_ALL)
  34. printTitle("Householder")
  35. VECDIM = 10
  36. a=np.random.randn(VECDIM)
  37. a = a / np.max(np.abs(a))
  38. # Reference
  39. vRef,betaRef = householder(a)
  40. printSubTitle("Householder F32")
  41. betaF32,vF32 = dsp.arm_householder_f32(a,dsp.DEFAULT_HOUSEHOLDER_THRESHOLD_F32)
  42. print(np.isclose(betaRef,betaF32,1e-6,1e-6))
  43. print(np.isclose(vRef,vF32,1e-6,1e-6))
  44. printSubTitle("Householder F64")
  45. betaF64,vF64 = dsp.arm_householder_f64(a,dsp.DEFAULT_HOUSEHOLDER_THRESHOLD_F64)
  46. print(np.isclose(betaRef,betaF64,1e-6,1e-6))
  47. print(np.isclose(vRef,vF64,1e-6,1e-6))
  48. printSubTitle("Householder Proportional F32")
  49. a=np.random.randn(5)
  50. # With the threshold defined with DEFAULT_HOUSEHOLDER_THRESHOLD_F32
  51. # this vector is considered as proportional to (1,0,...)
  52. # and thus the function will return (0,[0,...,0])
  53. a = a / np.max(np.abs(a)) * 1.0e-7
  54. resF32 = dsp.arm_householder_f32(a,dsp.DEFAULT_HOUSEHOLDER_THRESHOLD_F32)
  55. print(resF32)
  56. # With a smaller threshold, a computation is taking place
  57. resF32 = dsp.arm_householder_f32(a,0.001*dsp.DEFAULT_HOUSEHOLDER_THRESHOLD_F32)
  58. print(resF32)
  59. printTitle("QR decomposition")
  60. def checkOrtho(A,err=1e-10):
  61. product = A.T.dot(A)
  62. #print(A)
  63. np.fill_diagonal(product,0)
  64. #print(product)
  65. print(np.max(np.abs(product)))
  66. return (np.all(np.abs(product)<=err))
  67. m=np.array([[-0.35564874, -0.07809871, -0.10350569, -0.50633135, -0.65073484],
  68. [-0.71887395, 0.45257918, 0.29606363, 0.1497621 , 0.07002738],
  69. [-0.50586141, -0.50613839, -0.01650463, -0.29693649, 0.47667742],
  70. [ 0.06802137, 0.07689169, -0.02726221, -0.09996672, 0.15521956],
  71. [ 0.21220523, -0.22273009, 0.78247386, -0.2760002 , -0.24438688],
  72. [ 0.09683658, 0.62026597, 0.26771763, -0.26935342, 0.18443573],
  73. [-0.01014268, 0.27578087, -0.44635721, -0.21827312, -0.26463186],
  74. [-0.20420646, -0.12880459, 0.13207738, 0.65319578, -0.3956695 ]])
  75. rows,columns = m.shape
  76. # The CMSIS-DSP C functions is requiring two temporary arrays
  77. # To follow the C function as closely as possible, we create
  78. # two arrays. Their size will be used internally by the Python
  79. # wrapper to allocate two temporary buffers.
  80. # Like that you can check you have dimensionned the arrays in the
  81. # right way.
  82. # The content of the temporary buffers is not accesible from the
  83. # Python API. tmpa and tmpb are not modified.
  84. tmpa=np.zeros(rows)
  85. tmpb=np.zeros(rows)
  86. printSubTitle("QR F32")
  87. status,r,q,tau = dsp.arm_mat_qr_f32(m,dsp.DEFAULT_HOUSEHOLDER_THRESHOLD_F32,tmpa,tmpb)
  88. # Status different from 0 if matrix dimensions are not right
  89. # (rows must be >= columns)
  90. #print(status)
  91. #print(q)
  92. #print(r)
  93. #print(tau)
  94. # Check that the matrix Q is orthogonal
  95. assert(checkOrtho(q,err=1.0e-6))
  96. # Remove householder vectors from R matrix
  97. i=1
  98. for c in r.T:
  99. c[i:] = 0
  100. i = i+1
  101. # Check that M = Q R
  102. newm = np.dot(q,r)
  103. assert_allclose(newm,m,2e-6,1e-7)
  104. printSubTitle("QR F64")
  105. status,r,q,tau = dsp.arm_mat_qr_f64(m,dsp.DEFAULT_HOUSEHOLDER_THRESHOLD_F64,tmpa,tmpb)
  106. # Status different from 0 if matrix dimensions are not right
  107. # (rows must be >= columns)
  108. #print(status)
  109. #print(q)
  110. #print(r)
  111. #print(tau)
  112. # Check that the matrix Q is orthogonal
  113. assert(checkOrtho(q,err=1e-14))
  114. # Remove householder vectors from R matrix
  115. i=1
  116. for c in r.T:
  117. c[i:] = 0
  118. i = i+1
  119. # Check that M = Q R
  120. newm = np.dot(q,r)
  121. assert_allclose(newm,m)