Stats.py 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. import os.path
  2. import itertools
  3. import Tools
  4. import random
  5. import numpy as np
  6. import scipy
  7. import scipy.stats
  8. import math
  9. NBTESTS = 10
  10. VECDIM = [12,14,20]
  11. def entropyTest(config,nb):
  12. DIMS = [3,8,9,12]
  13. inputs = []
  14. outputs = []
  15. dims=[NBTESTS]
  16. for i in range(0,NBTESTS):
  17. vecDim = DIMS[i % len(DIMS)]
  18. dims.append(vecDim)
  19. v = np.random.rand(vecDim)
  20. v = v / np.sum(v)
  21. e = scipy.stats.entropy(v)
  22. inputs += list(v)
  23. outputs.append(e)
  24. inputs = np.array(inputs)
  25. outputs = np.array(outputs)
  26. dims = np.array(dims)
  27. config.writeInput(nb, inputs,"Input")
  28. config.writeInputS16(nb, dims,"Dims")
  29. config.writeReference(nb, outputs,"RefEntropy")
  30. def logsumexpTest(config,nb):
  31. DIMS = [3,8,9,12]
  32. inputs = []
  33. outputs = []
  34. dims=[NBTESTS]
  35. for i in range(0,NBTESTS):
  36. vecDim = DIMS[i % len(DIMS)]
  37. dims.append(vecDim)
  38. v = np.random.rand(vecDim)
  39. v = v / np.sum(v)
  40. e = scipy.special.logsumexp(v)
  41. inputs += list(v)
  42. outputs.append(e)
  43. inputs = np.array(inputs)
  44. outputs = np.array(outputs)
  45. dims = np.array(dims)
  46. config.writeInput(nb, inputs,"Input")
  47. config.writeInputS16(nb, dims,"Dims")
  48. config.writeReference(nb, outputs,"RefLogSumExp")
  49. def klTest(config,nb):
  50. DIMS = [3,8,9,12]
  51. inputsA = []
  52. inputsB = []
  53. outputs = []
  54. vecDim = VECDIM[nb % len(VECDIM)]
  55. dims=[NBTESTS]
  56. for i in range(0,NBTESTS):
  57. vecDim = DIMS[i % len(DIMS)]
  58. dims.append(vecDim)
  59. va = np.random.rand(vecDim)
  60. va = va / np.sum(va)
  61. vb = np.random.rand(vecDim)
  62. vb = vb / np.sum(vb)
  63. e = scipy.stats.entropy(va,vb)
  64. inputsA += list(va)
  65. inputsB += list(vb)
  66. outputs.append(e)
  67. inputsA = np.array(inputsA)
  68. inputsB = np.array(inputsB)
  69. outputs = np.array(outputs)
  70. dims = np.array(dims)
  71. config.writeInput(nb, inputsA,"InputA")
  72. config.writeInput(nb, inputsB,"InputB")
  73. config.writeInputS16(nb, dims,"Dims")
  74. config.writeReference(nb, outputs,"RefKL")
  75. def logSumExpDotTest(config,nb):
  76. DIMS = [3,8,9,12]
  77. inputsA = []
  78. inputsB = []
  79. outputs = []
  80. vecDim = VECDIM[nb % len(VECDIM)]
  81. dims=[NBTESTS]
  82. for i in range(0,NBTESTS):
  83. vecDim = DIMS[i % len(DIMS)]
  84. dims.append(vecDim)
  85. va = np.random.rand(vecDim)
  86. va = va / np.sum(va)
  87. vb = np.random.rand(vecDim)
  88. vb = vb / np.sum(vb)
  89. d = 0.001
  90. # It is a proba so must be in [0,1]
  91. # But restricted to ]d,1] so that the log exists
  92. va = (1-d)*va + d
  93. vb = (1-d)*vb + d
  94. e = np.log(np.dot(va,vb))
  95. va = np.log(va)
  96. vb = np.log(vb)
  97. inputsA += list(va)
  98. inputsB += list(vb)
  99. outputs.append(e)
  100. inputsA = np.array(inputsA)
  101. inputsB = np.array(inputsB)
  102. outputs = np.array(outputs)
  103. dims = np.array(dims)
  104. config.writeInput(nb, inputsA,"InputA")
  105. config.writeInput(nb, inputsB,"InputB")
  106. config.writeInputS16(nb, dims,"Dims")
  107. config.writeReference(nb, outputs,"RefLogSumExpDot")
  108. def writeF32OnlyTests(config,nb):
  109. entropyTest(config,nb)
  110. logsumexpTest(config,nb+1)
  111. klTest(config,nb+2)
  112. logSumExpDotTest(config,nb+3)
  113. return(nb+4)
  114. def writeF64OnlyTests(config,nb):
  115. entropyTest(config,nb)
  116. klTest(config,nb+2)
  117. return(nb+4)
  118. # For index in min and max we need to ensure that the difference between values
  119. # of the input is big enough to be representable on q31, q15 or q7.
  120. # Otherwise python will compute an index different from the one
  121. # computed by CMSIS which is normal but then the CMSIS test will fail.
  122. #vfunc = np.vectorize(squarer)
  123. def floatRound(x,f):
  124. return(np.round(x * 2**f)/2**f)
  125. def generateMaxTests(config,nb,format,data):
  126. indexes=[]
  127. maxvals=[]
  128. nbiters = Tools.loopnb(format,Tools.TAILONLY)
  129. index=np.argmax(data[0:nbiters])
  130. maxvalue=data[index]
  131. indexes.append(index)
  132. maxvals.append(maxvalue)
  133. nbiters = Tools.loopnb(format,Tools.BODYONLY)
  134. index=np.argmax(data[0:nbiters])
  135. maxvalue=data[index]
  136. indexes.append(index)
  137. maxvals.append(maxvalue)
  138. nbiters = Tools.loopnb(format,Tools.BODYANDTAIL)
  139. index=np.argmax(data[0:nbiters])
  140. maxvalue=data[index]
  141. indexes.append(index)
  142. maxvals.append(maxvalue)
  143. if format == 7:
  144. # Force max at position 280
  145. nbiters = 280
  146. data = np.zeros(nbiters)
  147. data[nbiters-1] = 0.9
  148. data[nbiters-2] = 0.8
  149. index=np.argmax(data[0:nbiters])
  150. maxvalue=data[index]
  151. indexes.append(index)
  152. maxvals.append(maxvalue)
  153. config.writeInput(nb, data,"InputMaxIndexMax")
  154. config.writeReference(nb, maxvals,"MaxVals")
  155. config.writeInputS16(nb, indexes,"MaxIndexes")
  156. return(nb+1)
  157. def generateMinTests(config,nb,format,data):
  158. indexes=[]
  159. maxvals=[]
  160. nbiters = Tools.loopnb(format,Tools.TAILONLY)
  161. index=np.argmin(data[0:nbiters])
  162. maxvalue=data[index]
  163. indexes.append(index)
  164. maxvals.append(maxvalue)
  165. nbiters = Tools.loopnb(format,Tools.BODYONLY)
  166. index=np.argmin(data[0:nbiters])
  167. maxvalue=data[index]
  168. indexes.append(index)
  169. maxvals.append(maxvalue)
  170. nbiters = Tools.loopnb(format,Tools.BODYANDTAIL)
  171. index=np.argmin(data[0:nbiters])
  172. maxvalue=data[index]
  173. indexes.append(index)
  174. maxvals.append(maxvalue)
  175. if format == 7:
  176. # Force max at position 280
  177. nbiters = 280
  178. data = 0.9*np.ones(nbiters)
  179. data[nbiters-1] = 0.0
  180. data[nbiters-2] = 0.1
  181. index=np.argmin(data[0:nbiters])
  182. maxvalue=data[index]
  183. indexes.append(index)
  184. maxvals.append(maxvalue)
  185. config.writeInput(nb, data,"InputMinIndexMax")
  186. config.writeReference(nb, maxvals,"MinVals")
  187. config.writeInputS16(nb, indexes,"MinIndexes")
  188. return(nb+1)
  189. def averageTest(format,data):
  190. return(np.average(data))
  191. def powerTest(format,data):
  192. if format == 31:
  193. return(np.dot(data,data) / 2**15) # CMSIS is 2.28 format
  194. elif format == 15:
  195. return(np.dot(data,data) / 2**33) # CMSIS is 34.30 format
  196. elif format == 7:
  197. return(np.dot(data,data) / 2**17) # CMSIS is 18.14 format
  198. else:
  199. return(np.dot(data,data))
  200. def rmsTest(format,data):
  201. return(math.sqrt(np.dot(data,data)/data.size))
  202. def stdTest(format,data):
  203. return(np.std(data,ddof=1))
  204. def varTest(format,data):
  205. return(np.var(data,ddof=1))
  206. def generateFuncTests(config,nb,format,data,func,name):
  207. funcvals=[]
  208. nbiters = Tools.loopnb(format,Tools.TAILONLY)
  209. funcvalue=func(format,data[0:nbiters])
  210. funcvals.append(funcvalue)
  211. nbiters = Tools.loopnb(format,Tools.BODYONLY)
  212. funcvalue=func(format,data[0:nbiters])
  213. funcvals.append(funcvalue)
  214. nbiters = Tools.loopnb(format,Tools.BODYANDTAIL)
  215. funcvalue=func(format,data[0:nbiters])
  216. funcvals.append(funcvalue)
  217. nbiters = 100
  218. funcvalue=func(format,data[0:nbiters])
  219. funcvals.append(funcvalue)
  220. config.writeReference(nb, funcvals,name)
  221. return(nb+1)
  222. def generatePowerTests(config,nb,format,data):
  223. funcvals=[]
  224. nbiters = Tools.loopnb(format,Tools.TAILONLY)
  225. funcvalue=powerTest(format,data[0:nbiters])
  226. funcvals.append(funcvalue)
  227. nbiters = Tools.loopnb(format,Tools.BODYONLY)
  228. funcvalue=powerTest(format,data[0:nbiters])
  229. funcvals.append(funcvalue)
  230. nbiters = Tools.loopnb(format,Tools.BODYANDTAIL)
  231. funcvalue=powerTest(format,data[0:nbiters])
  232. funcvals.append(funcvalue)
  233. if format==31 or format==15:
  234. config.writeReferenceQ63(nb, funcvals,"PowerVals")
  235. elif format==7:
  236. config.writeReferenceQ31(nb, funcvals,"PowerVals")
  237. else:
  238. config.writeReference(nb, funcvals,"PowerVals")
  239. return(nb+1)
  240. def writeTests(config,nb,format):
  241. NBSAMPLES = 300
  242. data1=np.random.randn(NBSAMPLES)
  243. data2=np.random.randn(NBSAMPLES)
  244. data1 = Tools.normalize(data1)
  245. data2 = np.abs(data1)
  246. # Force quantization so that computation of indexes
  247. # in min/max is coherent between Python and CMSIS.
  248. # Otherwise there will be normal differences and the test
  249. # will be displayed as failed.
  250. if format==31:
  251. data1=floatRound(data1,31)
  252. if format==15:
  253. data1=floatRound(data1,15)
  254. if format==7:
  255. data1=floatRound(data1,7)
  256. config.writeInput(1, data1,"Input")
  257. config.writeInput(2, data2,"Input")
  258. nb=generateMaxTests(config,nb,format,data1)
  259. nb=generateFuncTests(config,nb,format,data2,averageTest,"MeanVals")
  260. nb=generateMinTests(config,nb,format,data1)
  261. nb=generatePowerTests(config,nb,format,data1)
  262. nb=generateFuncTests(config,nb,format,data1,rmsTest,"RmsVals")
  263. nb=generateFuncTests(config,nb,format,data1,stdTest,"StdVals")
  264. nb=generateFuncTests(config,nb,format,data1,varTest,"VarVals")
  265. return(nb)
  266. def generatePatterns():
  267. PATTERNDIR = os.path.join("Patterns","DSP","Stats","Stats")
  268. PARAMDIR = os.path.join("Parameters","DSP","Stats","Stats")
  269. configf32=Tools.Config(PATTERNDIR,PARAMDIR,"f32")
  270. configf16=Tools.Config(PATTERNDIR,PARAMDIR,"f16")
  271. configf64=Tools.Config(PATTERNDIR,PARAMDIR,"f64")
  272. configq31=Tools.Config(PATTERNDIR,PARAMDIR,"q31")
  273. configq15=Tools.Config(PATTERNDIR,PARAMDIR,"q15")
  274. configq7 =Tools.Config(PATTERNDIR,PARAMDIR,"q7")
  275. nb=writeTests(configf32,1,0)
  276. nb=writeF32OnlyTests(configf32,22)
  277. writeF64OnlyTests(configf64,22)
  278. writeTests(configq31,1,31)
  279. writeTests(configq15,1,15)
  280. writeTests(configq7,1,7)
  281. nb=writeTests(configf16,1,16)
  282. if __name__ == '__main__':
  283. generatePatterns()