StatsTestsQ7.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  1. #include "arm_math.h"
  2. #include "StatsTestsQ7.h"
  3. #include <stdio.h>
  4. #include "Error.h"
  5. #include "Test.h"
  6. //#include <cstdio>
  7. #define SNR_THRESHOLD 20
  8. /*
  9. Reference patterns are generated with
  10. a double precision computation.
  11. */
  12. #define ABS_ERROR_Q7 ((q7_t)20)
  13. #define ABS_ERROR_Q31 ((q31_t)(1<<15))
  14. void StatsTestsQ7::test_max_q7()
  15. {
  16. const q7_t *inp = inputA.ptr();
  17. q7_t result;
  18. uint32_t indexval;
  19. q7_t *refp = ref.ptr();
  20. int16_t *refind = maxIndexes.ptr();
  21. q7_t *outp = output.ptr();
  22. int16_t *ind = index.ptr();
  23. arm_max_q7(inp,
  24. inputA.nbSamples(),
  25. &result,
  26. &indexval);
  27. outp[0] = result;
  28. ind[0] = indexval;
  29. ASSERT_EQ(result,refp[this->refOffset]);
  30. ASSERT_EQ((int16_t)indexval,refind[this->refOffset]);
  31. }
  32. /*
  33. May fail on the inded. It depends on the values generated by Python.
  34. If the values are too close and thus equal with q7 accuracy
  35. then the index computed by Python and by the q7 implementation
  36. will be different.
  37. Python code must be tuned to change this.
  38. */
  39. void StatsTestsQ7::test_min_q7()
  40. {
  41. const q7_t *inp = inputA.ptr();
  42. q7_t result;
  43. uint32_t indexval;
  44. q7_t *refp = ref.ptr();
  45. int16_t *refind = minIndexes.ptr();
  46. q7_t *outp = output.ptr();
  47. int16_t *ind = index.ptr();
  48. arm_min_q7(inp,
  49. inputA.nbSamples(),
  50. &result,
  51. &indexval);
  52. outp[0] = result;
  53. ind[0] = indexval;
  54. ASSERT_EQ(result,refp[this->refOffset]);
  55. ASSERT_EQ((int16_t)indexval,refind[this->refOffset]);
  56. }
  57. void StatsTestsQ7::test_mean_q7()
  58. {
  59. const q7_t *inp = inputA.ptr();
  60. q7_t result;
  61. q7_t *refp = ref.ptr();
  62. q7_t *outp = output.ptr();
  63. arm_mean_q7(inp,
  64. inputA.nbSamples(),
  65. &result);
  66. outp[0] = result;
  67. ASSERT_SNR(result,refp[this->refOffset],(float32_t)5);
  68. ASSERT_NEAR_EQ(result,refp[this->refOffset],ABS_ERROR_Q7);
  69. }
  70. void StatsTestsQ7::test_power_q7()
  71. {
  72. const q7_t *inp = inputA.ptr();
  73. q31_t result;
  74. q31_t *refp = refPower.ptr();
  75. q31_t *outp = outputPower.ptr();
  76. arm_power_q7(inp,
  77. inputA.nbSamples(),
  78. &result);
  79. outp[0] = result;
  80. ASSERT_SNR(result,refp[this->refOffset],(float32_t)SNR_THRESHOLD);
  81. ASSERT_NEAR_EQ(result,refp[this->refOffset],(q31_t)ABS_ERROR_Q31);
  82. }
  83. #if 0
  84. /*
  85. Those functions do not yet exist in CMSIS-DSP.
  86. But the tests are kept for when they will be available.
  87. */
  88. void StatsTestsQ7::test_rms_q7()
  89. {
  90. const q7_t *inp = inputA.ptr();
  91. q7_t result;
  92. q7_t *refp = ref.ptr();
  93. q7_t *outp = output.ptr();
  94. arm_rms_q7(inp,
  95. inputA.nbSamples(),
  96. &result);
  97. outp[0] = result;
  98. ASSERT_SNR(result,refp[this->refOffset],(float32_t)SNR_THRESHOLD);
  99. ASSERT_NEAR_EQ(result,refp[this->refOffset],ABS_ERROR_Q7);
  100. }
  101. void StatsTestsQ7::test_std_q7()
  102. {
  103. const q7_t *inp = inputA.ptr();
  104. q7_t result;
  105. q7_t *refp = ref.ptr();
  106. q7_t *outp = output.ptr();
  107. arm_std_q7(inp,
  108. inputA.nbSamples(),
  109. &result);
  110. outp[0] = result;
  111. ASSERT_SNR(result,refp[this->refOffset],(float32_t)SNR_THRESHOLD);
  112. ASSERT_NEAR_EQ(result,refp[this->refOffset],ABS_ERROR_Q7);
  113. }
  114. void StatsTestsQ7::test_var_q7()
  115. {
  116. const q7_t *inp = inputA.ptr();
  117. q7_t result;
  118. q7_t *refp = ref.ptr();
  119. q7_t *outp = output.ptr();
  120. arm_var_q7(inp,
  121. inputA.nbSamples(),
  122. &result);
  123. outp[0] = result;
  124. ASSERT_SNR(result,refp[this->refOffset],(float32_t)SNR_THRESHOLD);
  125. ASSERT_NEAR_EQ(result,refp[this->refOffset],ABS_ERROR_Q7);
  126. }
  127. #endif
  128. void StatsTestsQ7::setUp(Testing::testID_t id,std::vector<Testing::param_t>& paramsArgs,Client::PatternMgr *mgr)
  129. {
  130. switch(id)
  131. {
  132. case StatsTestsQ7::TEST_MAX_Q7_1:
  133. {
  134. inputA.reload(StatsTestsQ7::INPUT1_Q7_ID,mgr,15);
  135. maxIndexes.reload(StatsTestsQ7::MAXINDEXES_S16_ID,mgr);
  136. ref.reload(StatsTestsQ7::MAXVALS_Q7_ID,mgr);
  137. output.create(1,StatsTestsQ7::OUT_Q7_ID,mgr);
  138. index.create(1,StatsTestsQ7::OUT_S16_ID,mgr);
  139. refOffset = 0;
  140. }
  141. break;
  142. case StatsTestsQ7::TEST_MAX_Q7_2:
  143. {
  144. inputA.reload(StatsTestsQ7::INPUT1_Q7_ID,mgr,32);
  145. maxIndexes.reload(StatsTestsQ7::MAXINDEXES_S16_ID,mgr);
  146. ref.reload(StatsTestsQ7::MAXVALS_Q7_ID,mgr);
  147. output.create(1,StatsTestsQ7::OUT_Q7_ID,mgr);
  148. index.create(1,StatsTestsQ7::OUT_S16_ID,mgr);
  149. refOffset = 1;
  150. }
  151. break;
  152. case StatsTestsQ7::TEST_MAX_Q7_3:
  153. {
  154. inputA.reload(StatsTestsQ7::INPUT1_Q7_ID,mgr,47);
  155. maxIndexes.reload(StatsTestsQ7::MAXINDEXES_S16_ID,mgr);
  156. ref.reload(StatsTestsQ7::MAXVALS_Q7_ID,mgr);
  157. output.create(1,StatsTestsQ7::OUT_Q7_ID,mgr);
  158. index.create(1,StatsTestsQ7::OUT_S16_ID,mgr);
  159. refOffset = 2;
  160. }
  161. break;
  162. /*
  163. For MEAN tests, INPUT2 pattern is used.
  164. It contains only positive values and prevent the average
  165. value from being too close to zero which make the estimation
  166. of the errors difficult.
  167. */
  168. case StatsTestsQ7::TEST_MEAN_Q7_4:
  169. {
  170. inputA.reload(StatsTestsQ7::INPUT2_Q7_ID,mgr,15);
  171. ref.reload(StatsTestsQ7::MEANVALS_Q7_ID,mgr);
  172. output.create(1,StatsTestsQ7::OUT_Q7_ID,mgr);
  173. refOffset = 0;
  174. }
  175. break;
  176. case StatsTestsQ7::TEST_MEAN_Q7_5:
  177. {
  178. inputA.reload(StatsTestsQ7::INPUT2_Q7_ID,mgr,32);
  179. ref.reload(StatsTestsQ7::MEANVALS_Q7_ID,mgr);
  180. output.create(1,StatsTestsQ7::OUT_Q7_ID,mgr);
  181. refOffset = 1;
  182. }
  183. break;
  184. case StatsTestsQ7::TEST_MEAN_Q7_6:
  185. {
  186. inputA.reload(StatsTestsQ7::INPUT2_Q7_ID,mgr,47);
  187. ref.reload(StatsTestsQ7::MEANVALS_Q7_ID,mgr);
  188. output.create(1,StatsTestsQ7::OUT_Q7_ID,mgr);
  189. refOffset = 2;
  190. }
  191. break;
  192. case StatsTestsQ7::TEST_MIN_Q7_7:
  193. {
  194. inputA.reload(StatsTestsQ7::INPUT1_Q7_ID,mgr,15);
  195. minIndexes.reload(StatsTestsQ7::MININDEXES_S16_ID,mgr);
  196. ref.reload(StatsTestsQ7::MINVALS_Q7_ID,mgr);
  197. output.create(1,StatsTestsQ7::OUT_Q7_ID,mgr);
  198. index.create(1,StatsTestsQ7::OUT_S16_ID,mgr);
  199. refOffset = 0;
  200. }
  201. break;
  202. case StatsTestsQ7::TEST_MIN_Q7_8:
  203. {
  204. inputA.reload(StatsTestsQ7::INPUT1_Q7_ID,mgr,32);
  205. minIndexes.reload(StatsTestsQ7::MININDEXES_S16_ID,mgr);
  206. ref.reload(StatsTestsQ7::MINVALS_Q7_ID,mgr);
  207. output.create(1,StatsTestsQ7::OUT_Q7_ID,mgr);
  208. index.create(1,StatsTestsQ7::OUT_S16_ID,mgr);
  209. refOffset = 1;
  210. }
  211. break;
  212. case StatsTestsQ7::TEST_MIN_Q7_9:
  213. {
  214. inputA.reload(StatsTestsQ7::INPUT1_Q7_ID,mgr,47);
  215. minIndexes.reload(StatsTestsQ7::MININDEXES_S16_ID,mgr);
  216. ref.reload(StatsTestsQ7::MINVALS_Q7_ID,mgr);
  217. output.create(1,StatsTestsQ7::OUT_Q7_ID,mgr);
  218. index.create(1,StatsTestsQ7::OUT_S16_ID,mgr);
  219. refOffset = 2;
  220. }
  221. break;
  222. case StatsTestsQ7::TEST_POWER_Q7_10:
  223. {
  224. inputA.reload(StatsTestsQ7::INPUT1_Q7_ID,mgr,15);
  225. refPower.reload(StatsTestsQ7::POWERVALS_Q31_ID,mgr);
  226. outputPower.create(1,StatsTestsQ7::OUT_Q7_ID,mgr);
  227. refOffset = 0;
  228. }
  229. break;
  230. case StatsTestsQ7::TEST_POWER_Q7_11:
  231. {
  232. inputA.reload(StatsTestsQ7::INPUT1_Q7_ID,mgr,32);
  233. refPower.reload(StatsTestsQ7::POWERVALS_Q31_ID,mgr);
  234. outputPower.create(1,StatsTestsQ7::OUT_Q7_ID,mgr);
  235. refOffset = 1;
  236. }
  237. break;
  238. case StatsTestsQ7::TEST_POWER_Q7_12:
  239. {
  240. inputA.reload(StatsTestsQ7::INPUT1_Q7_ID,mgr,47);
  241. refPower.reload(StatsTestsQ7::POWERVALS_Q31_ID,mgr);
  242. outputPower.create(1,StatsTestsQ7::OUT_Q7_ID,mgr);
  243. refOffset = 2;
  244. }
  245. break;
  246. #if 0
  247. /*
  248. Those functions do not yet exist in CMSIS-DSP.
  249. But the tests are kept for when they will be available.
  250. */
  251. case StatsTestsQ7::TEST_RMS_Q7_13:
  252. {
  253. inputA.reload(StatsTestsQ7::INPUT1_Q7_ID,mgr,15);
  254. ref.reload(StatsTestsQ7::RMSVALS_Q7_ID,mgr);
  255. output.create(1,StatsTestsQ7::OUT_Q7_ID,mgr);
  256. refOffset = 0;
  257. }
  258. break;
  259. case StatsTestsQ7::TEST_RMS_Q7_14:
  260. {
  261. inputA.reload(StatsTestsQ7::INPUT1_Q7_ID,mgr,32);
  262. ref.reload(StatsTestsQ7::RMSVALS_Q7_ID,mgr);
  263. output.create(1,StatsTestsQ7::OUT_Q7_ID,mgr);
  264. refOffset = 1;
  265. }
  266. break;
  267. case StatsTestsQ7::TEST_RMS_Q7_15:
  268. {
  269. inputA.reload(StatsTestsQ7::INPUT1_Q7_ID,mgr,47);
  270. ref.reload(StatsTestsQ7::RMSVALS_Q7_ID,mgr);
  271. output.create(1,StatsTestsQ7::OUT_Q7_ID,mgr);
  272. refOffset = 2;
  273. }
  274. break;
  275. case StatsTestsQ7::TEST_STD_Q7_16:
  276. {
  277. inputA.reload(StatsTestsQ7::INPUT1_Q7_ID,mgr,15);
  278. ref.reload(StatsTestsQ7::STDVALS_Q7_ID,mgr);
  279. output.create(1,StatsTestsQ7::OUT_Q7_ID,mgr);
  280. refOffset = 0;
  281. }
  282. break;
  283. case StatsTestsQ7::TEST_STD_Q7_17:
  284. {
  285. inputA.reload(StatsTestsQ7::INPUT1_Q7_ID,mgr,32);
  286. ref.reload(StatsTestsQ7::STDVALS_Q7_ID,mgr);
  287. output.create(1,StatsTestsQ7::OUT_Q7_ID,mgr);
  288. refOffset = 1;
  289. }
  290. break;
  291. case StatsTestsQ7::TEST_STD_Q7_18:
  292. {
  293. inputA.reload(StatsTestsQ7::INPUT1_Q7_ID,mgr,47);
  294. ref.reload(StatsTestsQ7::STDVALS_Q7_ID,mgr);
  295. output.create(1,StatsTestsQ7::OUT_Q7_ID,mgr);
  296. refOffset = 2;
  297. }
  298. break;
  299. case StatsTestsQ7::TEST_VAR_Q7_19:
  300. {
  301. inputA.reload(StatsTestsQ7::INPUT1_Q7_ID,mgr,15);
  302. ref.reload(StatsTestsQ7::VARVALS_Q7_ID,mgr);
  303. output.create(1,StatsTestsQ7::OUT_Q7_ID,mgr);
  304. refOffset = 0;
  305. }
  306. break;
  307. case StatsTestsQ7::TEST_VAR_Q7_20:
  308. {
  309. inputA.reload(StatsTestsQ7::INPUT1_Q7_ID,mgr,32);
  310. ref.reload(StatsTestsQ7::VARVALS_Q7_ID,mgr);
  311. output.create(1,StatsTestsQ7::OUT_Q7_ID,mgr);
  312. refOffset = 1;
  313. }
  314. break;
  315. case StatsTestsQ7::TEST_VAR_Q7_21:
  316. {
  317. inputA.reload(StatsTestsQ7::INPUT1_Q7_ID,mgr,47);
  318. ref.reload(StatsTestsQ7::VARVALS_Q7_ID,mgr);
  319. output.create(1,StatsTestsQ7::OUT_Q7_ID,mgr);
  320. refOffset = 2;
  321. }
  322. break;
  323. #endif
  324. case StatsTestsQ7::TEST_MAX_Q7_13:
  325. {
  326. inputA.reload(StatsTestsQ7::MAXINDEXMAX_Q7_ID,mgr,280);
  327. maxIndexes.reload(StatsTestsQ7::MAXINDEXES_S16_ID,mgr);
  328. ref.reload(StatsTestsQ7::MAXVALS_Q7_ID,mgr);
  329. output.create(1,StatsTestsQ7::OUT_Q7_ID,mgr);
  330. index.create(1,StatsTestsQ7::OUT_S16_ID,mgr);
  331. refOffset = 3;
  332. }
  333. break;
  334. case StatsTestsQ7::TEST_MIN_Q7_14:
  335. {
  336. inputA.reload(StatsTestsQ7::MININDEXMAX_Q7_ID,mgr,280);
  337. minIndexes.reload(StatsTestsQ7::MININDEXES_S16_ID,mgr);
  338. ref.reload(StatsTestsQ7::MINVALS_Q7_ID,mgr);
  339. output.create(1,StatsTestsQ7::OUT_Q7_ID,mgr);
  340. index.create(1,StatsTestsQ7::OUT_S16_ID,mgr);
  341. refOffset = 3;
  342. }
  343. break;
  344. }
  345. }
  346. void StatsTestsQ7::tearDown(Testing::testID_t id,Client::PatternMgr *mgr)
  347. {
  348. switch(id)
  349. {
  350. case StatsTestsQ7::TEST_MAX_Q7_1:
  351. case StatsTestsQ7::TEST_MAX_Q7_2:
  352. case StatsTestsQ7::TEST_MAX_Q7_3:
  353. case StatsTestsQ7::TEST_MIN_Q7_7:
  354. case StatsTestsQ7::TEST_MIN_Q7_8:
  355. case StatsTestsQ7::TEST_MIN_Q7_9:
  356. case StatsTestsQ7::TEST_MAX_Q7_13:
  357. case StatsTestsQ7::TEST_MIN_Q7_14:
  358. index.dump(mgr);
  359. output.dump(mgr);
  360. break;
  361. case TEST_POWER_Q7_10:
  362. case TEST_POWER_Q7_11:
  363. case TEST_POWER_Q7_12:
  364. outputPower.dump(mgr);
  365. break;
  366. default:
  367. output.dump(mgr);
  368. }
  369. }