libcm is a C development framework with an emphasis on audio signal processing applications.
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

cmVectOpsRICode.h 30KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270
  1. //| Copyright: (C) 2009-2020 Kevin Larke <contact AT larke DOT org>
  2. //| License: GNU GPL version 3.0 or above. See the accompanying LICENSE file.
  3. #ifdef cmVectOpsRICode_h
  4. VECT_OP_TYPE* VECT_OP_FUNC(Col)( VECT_OP_TYPE* m, unsigned ci, unsigned rn, unsigned cn )
  5. {
  6. assert(ci<cn);
  7. return m + (ci*rn);
  8. }
  9. VECT_OP_TYPE* VECT_OP_FUNC(Row)( VECT_OP_TYPE* m, unsigned ri, unsigned rn, unsigned cn )
  10. {
  11. assert(ri<rn);
  12. return m + ri;
  13. }
  14. VECT_OP_TYPE* VECT_OP_FUNC(ElePtr)( VECT_OP_TYPE* m, unsigned ri, unsigned ci, unsigned rn, unsigned cn )
  15. {
  16. assert(ri<rn && ci<cn);
  17. return m + (ci*rn) + ri;
  18. }
  19. VECT_OP_TYPE VECT_OP_FUNC(Ele)( VECT_OP_TYPE* m, unsigned ri, unsigned ci, unsigned rn, unsigned cn )
  20. { return *VECT_OP_FUNC(ElePtr)(m,ri,ci,rn,cn); }
  21. void VECT_OP_FUNC(Set)( VECT_OP_TYPE* m, unsigned ri, unsigned ci, unsigned rn, unsigned cn, VECT_OP_TYPE v )
  22. { *(VECT_OP_FUNC(ElePtr)(m,ri,ci,rn,cn)) = v; }
  23. const VECT_OP_TYPE* VECT_OP_FUNC(CCol)( const VECT_OP_TYPE* m, unsigned ci, unsigned rn, unsigned cn )
  24. {
  25. assert(ci<cn);
  26. return m + (ci*rn);
  27. }
  28. const VECT_OP_TYPE* VECT_OP_FUNC(CRow)( const VECT_OP_TYPE* m, unsigned ri, unsigned rn, unsigned cn )
  29. {
  30. assert(ri<rn);
  31. return m + ri;
  32. }
  33. const VECT_OP_TYPE* VECT_OP_FUNC(CElePtr)( const VECT_OP_TYPE* m, unsigned ri, unsigned ci, unsigned rn, unsigned cn )
  34. {
  35. assert(ri<rn && ci<cn);
  36. return m + (ci*rn) + ri;
  37. }
  38. VECT_OP_TYPE VECT_OP_FUNC(CEle)( const VECT_OP_TYPE* m, unsigned ri, unsigned ci, unsigned rn, unsigned cn )
  39. { return *VECT_OP_FUNC(CElePtr)(m,ri,ci,rn,cn); }
  40. VECT_OP_TYPE* VECT_OP_FUNC(Diag)( VECT_OP_TYPE* dbp, unsigned n, const VECT_OP_TYPE* sbp )
  41. {
  42. unsigned i,j;
  43. for(i=0,j=0; i<n && j<n; ++i,++j)
  44. dbp[ (i*n) + j ] = sbp[i];
  45. return dbp;
  46. }
  47. VECT_OP_TYPE* VECT_OP_FUNC(DiagZ)(VECT_OP_TYPE* dbp, unsigned n, const VECT_OP_TYPE* sbp )
  48. {
  49. VECT_OP_FUNC(Fill)(dbp,n*n,0);
  50. return VECT_OP_FUNC(Diag)(dbp,n,sbp);
  51. }
  52. VECT_OP_TYPE* VECT_OP_FUNC(Identity)( VECT_OP_TYPE* dbp, unsigned rn, unsigned cn )
  53. {
  54. unsigned i,j;
  55. for(i=0,j=0; i<cn && j<rn; ++i,++j)
  56. dbp[ (i*rn) + j ] = 1;
  57. return dbp;
  58. }
  59. VECT_OP_TYPE* VECT_OP_FUNC(IdentityZ)( VECT_OP_TYPE* dbp, unsigned rn, unsigned cn )
  60. {
  61. VECT_OP_FUNC(Fill)(dbp,rn*cn,0);
  62. return VECT_OP_FUNC(Identity)(dbp,rn,cn);
  63. }
  64. VECT_OP_TYPE* VECT_OP_FUNC(Transpose)( VECT_OP_TYPE* dbp, const VECT_OP_TYPE* sp, unsigned srn, unsigned scn )
  65. {
  66. VECT_OP_TYPE* dp = dbp;
  67. const VECT_OP_TYPE* dep = dbp + (srn*scn);
  68. while( dbp < dep )
  69. {
  70. const VECT_OP_TYPE* sbp = sp++;
  71. const VECT_OP_TYPE* sep = sbp + (srn*scn);
  72. for(; sbp < sep; sbp+=srn )
  73. *dbp++ = *sbp;
  74. }
  75. return dp;
  76. }
  77. VECT_OP_TYPE* VECT_OP_FUNC(Fill)( VECT_OP_TYPE* dbp, unsigned dn, VECT_OP_TYPE value )
  78. {
  79. const VECT_OP_TYPE* dep = dbp + dn;
  80. VECT_OP_TYPE* dp = dbp;
  81. if( value == 0 )
  82. memset(dbp,0,(dep-dbp)*sizeof(VECT_OP_TYPE));
  83. else
  84. {
  85. while( dbp < dep )
  86. *dbp++ = value;
  87. }
  88. return dp;
  89. }
  90. VECT_OP_TYPE* VECT_OP_FUNC(Zero)( VECT_OP_TYPE* dbp, unsigned dn )
  91. {
  92. memset( dbp, 0, sizeof(VECT_OP_TYPE)*dn);
  93. return dbp;
  94. }
  95. VECT_OP_TYPE* VECT_OP_FUNC(Move)( VECT_OP_TYPE* bp, unsigned bn, const VECT_OP_TYPE* sp )
  96. {
  97. memmove(bp,sp,sizeof(VECT_OP_TYPE)*bn);
  98. return bp;
  99. }
  100. VECT_OP_TYPE* VECT_OP_FUNC(Copy)( VECT_OP_TYPE* bp, unsigned bn, const VECT_OP_TYPE* sp )
  101. {
  102. memcpy(bp,sp,sizeof(VECT_OP_TYPE)*bn);
  103. return bp;
  104. }
  105. VECT_OP_TYPE* VECT_OP_FUNC(CopyN)( VECT_OP_TYPE* bp, unsigned bn, unsigned d_stride, const VECT_OP_TYPE* sp, unsigned s_stride )
  106. {
  107. VECT_OP_TYPE* dbp = bp;
  108. const VECT_OP_TYPE* ep = bp + (bn*d_stride);
  109. for(; bp < ep; bp += d_stride, sp += s_stride )
  110. *bp = *sp;
  111. return dbp;
  112. }
  113. VECT_OP_TYPE* VECT_OP_FUNC(CopyU)( VECT_OP_TYPE* bp, unsigned bn, const unsigned* sp )
  114. {
  115. VECT_OP_TYPE* dbp = bp;
  116. const VECT_OP_TYPE* ep = bp + bn;
  117. VECT_OP_TYPE* dp = bp;
  118. while( dp < ep )
  119. *dp++ = (VECT_OP_TYPE)*sp++;
  120. return dbp;
  121. }
  122. VECT_OP_TYPE* VECT_OP_FUNC(CopyI)( VECT_OP_TYPE* dbp, unsigned dn, const int* sp )
  123. {
  124. const VECT_OP_TYPE* dep = dbp + dn;
  125. VECT_OP_TYPE* dp = dbp;
  126. while( dp < dep )
  127. *dp++ = (VECT_OP_TYPE)*sp++;
  128. return dbp;
  129. }
  130. VECT_OP_TYPE* VECT_OP_FUNC(CopyF)( VECT_OP_TYPE* dbp, unsigned dn, const float* sp )
  131. {
  132. const VECT_OP_TYPE* dep = dbp + dn;
  133. VECT_OP_TYPE* dp = dbp;
  134. while( dp < dep )
  135. *dp++ = (VECT_OP_TYPE)*sp++;
  136. return dbp;
  137. }
  138. VECT_OP_TYPE* VECT_OP_FUNC(CopyD)( VECT_OP_TYPE* dbp, unsigned dn, const double* sp )
  139. {
  140. const VECT_OP_TYPE* dep = dbp + dn;
  141. VECT_OP_TYPE* dp = dbp;
  142. while( dp < dep )
  143. *dp++ = (VECT_OP_TYPE)*sp++;
  144. return dbp;
  145. }
  146. VECT_OP_TYPE* VECT_OP_FUNC(CopyS)( VECT_OP_TYPE* dbp, unsigned dn, const cmSample_t* sp )
  147. {
  148. const VECT_OP_TYPE* dep = dbp + dn;
  149. VECT_OP_TYPE* dp = dbp;
  150. while( dp < dep )
  151. *dp++ = (VECT_OP_TYPE)*sp++;
  152. return dbp;
  153. }
  154. VECT_OP_TYPE* VECT_OP_FUNC(CopyR)( VECT_OP_TYPE* dbp, unsigned dn, const cmReal_t* sp )
  155. {
  156. const VECT_OP_TYPE* dep = dbp + dn;
  157. VECT_OP_TYPE* dp = dbp;
  158. while( dp < dep )
  159. *dp++ = (VECT_OP_TYPE)*sp++;
  160. return dbp;
  161. }
  162. VECT_OP_TYPE* VECT_OP_FUNC(CopyStride)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sp, unsigned srcStride )
  163. {
  164. const VECT_OP_TYPE* dep = dbp + dn;
  165. VECT_OP_TYPE* dp = dbp;
  166. for(; dp < dep; sp += srcStride )
  167. *dp++ = *sp;
  168. return dbp;
  169. }
  170. VECT_OP_TYPE* VECT_OP_FUNC(Shrink)( VECT_OP_TYPE* s, unsigned sn, const VECT_OP_TYPE* t, unsigned tn )
  171. {
  172. assert( s <= t && t <= (s+sn) );
  173. assert( s <= (t+tn) && (t+tn) <= (s+sn));
  174. //VECT_OP_FUNC(Move)(s,sn - ((t - s) + tn),t+tn);
  175. VECT_OP_FUNC(Move)((VECT_OP_TYPE*)t,(sn - ((t+tn)-s)) + 1,t+tn);
  176. return s;
  177. }
  178. VECT_OP_TYPE* VECT_OP_FUNC(Expand)( VECT_OP_TYPE* s, unsigned sn, const VECT_OP_TYPE* t, unsigned tn )
  179. {
  180. assert( s <= t && t <= s+sn );
  181. unsigned i = t - s;
  182. s = cmMemResizeP(VECT_OP_TYPE,s,sn+tn);
  183. t = s + i;
  184. assert( t + tn + sn - i == s + sn + tn );
  185. VECT_OP_FUNC(Move)(((VECT_OP_TYPE*)t)+tn,sn-i,t);
  186. return s;
  187. }
  188. VECT_OP_TYPE* VECT_OP_FUNC(Replace)(VECT_OP_TYPE* s, unsigned* sn, const VECT_OP_TYPE* t, unsigned tn, const VECT_OP_TYPE* u, unsigned un )
  189. {
  190. // if s is empty and t[tn] is empty
  191. if( s == NULL && tn == 0 )
  192. {
  193. if( un == 0 )
  194. return s;
  195. s = cmMemAllocZ(VECT_OP_TYPE,un);
  196. VECT_OP_FUNC(Copy)(s,un,u);
  197. if( sn != NULL )
  198. *sn = un;
  199. return s;
  200. }
  201. assert( s!=NULL && t != NULL );
  202. assert( (u!=NULL && un>0) || (u==NULL && un==0) );
  203. if( (tn==0 && un==0) || (t==NULL && u==NULL))
  204. return s;
  205. // if the area to replace is greater than the area to insert ...
  206. if( tn > un )
  207. {
  208. VECT_OP_FUNC(Shrink)(s,*sn,t+un,tn-un); // ... then shrink the buffer
  209. *sn -= tn-un;
  210. }
  211. else
  212. // if the area to insert is greater than the area to replace ...
  213. if( un > tn )
  214. {
  215. unsigned offs = t - s;
  216. s = VECT_OP_FUNC(Expand)(s,*sn,t+tn,un-tn); // ... then expand the buffer
  217. t = s + offs;
  218. *sn += un-tn;
  219. }
  220. assert(t+un <= s+(*sn));
  221. if( u!=NULL )
  222. VECT_OP_FUNC(Copy)((VECT_OP_TYPE*)t,un,u);
  223. return s;
  224. }
  225. VECT_OP_TYPE* VECT_OP_FUNC(Rotate)( VECT_OP_TYPE* v, unsigned n, int i )
  226. {
  227. int c, j;
  228. if(v == NULL || n <= 0)
  229. return NULL;
  230. if(i < 0 || i >= n)
  231. {
  232. i %= n;
  233. if (i < 0)
  234. i += n;
  235. }
  236. if(i == 0)
  237. return 0;
  238. c = 0;
  239. for(j = 0; c < n; j++)
  240. {
  241. int t = j, k = j + i;
  242. VECT_OP_TYPE tmp = v[j];
  243. c++;
  244. while( k != j )
  245. {
  246. v[t] = v[k];
  247. t = k;
  248. k += i;
  249. if( k >= n )
  250. k -= n;
  251. c++;
  252. }
  253. v[t] = tmp;
  254. }
  255. return v;
  256. }
  257. VECT_OP_TYPE* VECT_OP_FUNC(RotateM)( VECT_OP_TYPE* dbp, unsigned drn, unsigned dcn, const VECT_OP_TYPE* sbp, int rShiftCnt, int cShiftCnt )
  258. {
  259. int j;
  260. while( rShiftCnt < 0 )
  261. rShiftCnt += drn;
  262. while( cShiftCnt < 0 )
  263. cShiftCnt += dcn;
  264. int m = rShiftCnt % drn;
  265. int n = cShiftCnt % dcn;
  266. for(j=0; j<dcn; ++j,++n)
  267. {
  268. if(n==dcn)
  269. n = 0;
  270. // cnt from dst position to end of column
  271. unsigned cn = drn - m;
  272. // copy from top of src col to bottom of dst column
  273. VECT_OP_FUNC(Copy)(dbp + (n*drn) + m, cn, sbp );
  274. sbp+=cn;
  275. if( cn < drn )
  276. {
  277. // copy from bottom of src col to top of dst column
  278. VECT_OP_FUNC(Copy)(dbp + (n*drn), drn-cn, sbp );
  279. sbp += drn-cn;
  280. }
  281. }
  282. return dbp;
  283. }
  284. VECT_OP_TYPE* VECT_OP_FUNC(Shift)( VECT_OP_TYPE* dbp, unsigned dn, int shiftCnt, VECT_OP_TYPE fillValue )
  285. {
  286. VECT_OP_TYPE* dep = dbp + dn;
  287. VECT_OP_TYPE* rp = dbp;
  288. unsigned n = dep - dbp;
  289. if( shiftCnt == 0 )
  290. return dbp;
  291. if( abs(shiftCnt) >= n )
  292. return VECT_OP_FUNC(Fill)(dbp,dn,fillValue);
  293. if( shiftCnt > 0 )
  294. {
  295. const VECT_OP_TYPE* sbp = dep - (shiftCnt+1);
  296. const VECT_OP_TYPE* sep = dbp;
  297. VECT_OP_TYPE* dp = dbp + (n-1);
  298. while( sbp >= sep )
  299. *dp-- = *sbp--;
  300. while(dbp <= dp )
  301. *dbp++ = fillValue;
  302. }
  303. else
  304. {
  305. const VECT_OP_TYPE* sbp = dbp + abs(shiftCnt);
  306. while( sbp < dep )
  307. *dbp++ = *sbp++;
  308. while(dbp<dep)
  309. *dbp++ = fillValue;
  310. }
  311. return rp;
  312. }
  313. VECT_OP_TYPE* VECT_OP_FUNC(Flip)( VECT_OP_TYPE* dbp, unsigned dn)
  314. {
  315. VECT_OP_TYPE* p0 = dbp;
  316. VECT_OP_TYPE* p1 = dbp + dn - 1;
  317. while( p0 < p1 )
  318. {
  319. VECT_OP_TYPE t = *p0;
  320. *p0++ = *p1;
  321. *p1-- = t;
  322. }
  323. return dbp;
  324. }
  325. VECT_OP_TYPE VECT_OP_FUNC(Seq)( VECT_OP_TYPE* dbp, unsigned dn, VECT_OP_TYPE beg, VECT_OP_TYPE incr )
  326. {
  327. const VECT_OP_TYPE* dep = dbp + dn;
  328. unsigned i = 0;
  329. for(; dbp<dep; ++i)
  330. *dbp++ = beg + (incr*i);
  331. return beg + (incr*i);
  332. }
  333. VECT_OP_TYPE* VECT_OP_FUNC(SubVS)( VECT_OP_TYPE* bp, unsigned n, VECT_OP_TYPE v )
  334. {
  335. const VECT_OP_TYPE* ep = bp + n;
  336. VECT_OP_TYPE* dp = bp;
  337. while( dp < ep )
  338. *dp++ -= v;
  339. return bp;
  340. }
  341. VECT_OP_TYPE* VECT_OP_FUNC(SubVV)( VECT_OP_TYPE* bp, unsigned n, const VECT_OP_TYPE* v )
  342. {
  343. const VECT_OP_TYPE* ep = bp + n;
  344. VECT_OP_TYPE* dp = bp;
  345. while( dp < ep )
  346. *dp++ -= *v++;
  347. return bp;
  348. }
  349. VECT_OP_TYPE* VECT_OP_FUNC(SubVVS)( VECT_OP_TYPE* bp, unsigned n, const VECT_OP_TYPE* v, VECT_OP_TYPE s )
  350. {
  351. const VECT_OP_TYPE* ep = bp + n;
  352. VECT_OP_TYPE* dp = bp;
  353. while( dp < ep )
  354. *dp++ = *v++ - s;
  355. return bp;
  356. }
  357. VECT_OP_TYPE* VECT_OP_FUNC(SubVVNN)(VECT_OP_TYPE* dp, unsigned dn, unsigned dnn, const VECT_OP_TYPE* v, unsigned n )
  358. {
  359. const VECT_OP_TYPE* ep = dp + (dn*dnn);
  360. VECT_OP_TYPE* dbp = dp;
  361. for(; dp < ep; dp+=dnn, v+=n )
  362. *dp -= *v;
  363. return dbp;
  364. }
  365. VECT_OP_TYPE* VECT_OP_FUNC(SubVVV)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sb0p, const VECT_OP_TYPE* sb1p )
  366. {
  367. const VECT_OP_TYPE* dep = dbp + dn;
  368. VECT_OP_TYPE* dp = dbp;
  369. while( dbp < dep )
  370. *dbp++ = *sb0p++ - *sb1p++;
  371. return dp;
  372. }
  373. VECT_OP_TYPE* VECT_OP_FUNC(SubVSV)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE s0, const VECT_OP_TYPE* sb1p )
  374. {
  375. const VECT_OP_TYPE* dep = dbp + dn;
  376. VECT_OP_TYPE* dp = dbp;
  377. while( dbp < dep )
  378. *dbp++ = s0 - *sb1p++;
  379. return dp;
  380. }
  381. VECT_OP_TYPE* VECT_OP_FUNC(AddVS)( VECT_OP_TYPE* bp, unsigned n, VECT_OP_TYPE v )
  382. {
  383. const VECT_OP_TYPE* ep = bp + n;
  384. VECT_OP_TYPE* dp = bp;
  385. while( dp < ep )
  386. *dp++ += v;
  387. return bp;
  388. }
  389. VECT_OP_TYPE* VECT_OP_FUNC(AddVV)( VECT_OP_TYPE* bp, unsigned bn, const VECT_OP_TYPE* v )
  390. {
  391. const VECT_OP_TYPE* ep = bp + bn;
  392. VECT_OP_TYPE* dp = bp;
  393. while( dp < ep )
  394. *dp++ += *v++;
  395. return bp;
  396. }
  397. VECT_OP_TYPE* VECT_OP_FUNC(AddVVS)( VECT_OP_TYPE* bp, unsigned bn, const VECT_OP_TYPE* v, VECT_OP_TYPE s )
  398. {
  399. const VECT_OP_TYPE* ep = bp + bn;
  400. VECT_OP_TYPE* dp = bp;
  401. while( dp < ep )
  402. *dp++ = *v++ + s;
  403. return bp;
  404. }
  405. VECT_OP_TYPE* VECT_OP_FUNC(AddVVNN)(VECT_OP_TYPE* dp, unsigned dn, unsigned dnn, const VECT_OP_TYPE* v, unsigned n )
  406. {
  407. const VECT_OP_TYPE* ep = dp + (dn*dnn);
  408. VECT_OP_TYPE* dbp = dp;
  409. for(; dp < ep; v+=n, dp+=dnn )
  410. *dp += *v;
  411. return dbp;
  412. }
  413. VECT_OP_TYPE* VECT_OP_FUNC(AddVVV)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sb0p, const VECT_OP_TYPE* sb1p )
  414. {
  415. const VECT_OP_TYPE* dep = dbp + dn;
  416. VECT_OP_TYPE* dp = dbp;
  417. while( dbp < dep )
  418. *dbp++ = *sb0p++ + *sb1p++;
  419. return dp;
  420. }
  421. VECT_OP_TYPE* VECT_OP_FUNC(MultVVV)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sb0p, const VECT_OP_TYPE* sb1p )
  422. {
  423. const VECT_OP_TYPE* dep = dbp + dn;
  424. VECT_OP_TYPE* dp = dbp;
  425. while( dbp < dep )
  426. *dbp++ = *sb0p++ * *sb1p++;
  427. return dp;
  428. }
  429. VECT_OP_TYPE* VECT_OP_FUNC(MultVV)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sbp )
  430. {
  431. const VECT_OP_TYPE* dep = dbp + dn;
  432. VECT_OP_TYPE* dp = dbp;
  433. while( dbp < dep )
  434. *dbp++ *= *sbp++;
  435. return dp;
  436. }
  437. VECT_OP_TYPE* VECT_OP_FUNC(MultVVNN)(VECT_OP_TYPE* dp, unsigned dn, unsigned dnn, const VECT_OP_TYPE* v, unsigned n )
  438. {
  439. const VECT_OP_TYPE* ep = dp + (dn*dnn);
  440. VECT_OP_TYPE* dbp = dp;
  441. for(; dp < ep; v+=n, dp+=dnn )
  442. *dp *= *v;
  443. return dbp;
  444. }
  445. VECT_OP_TYPE* VECT_OP_FUNC(MultVS)( VECT_OP_TYPE* dbp, unsigned dn, VECT_OP_TYPE s )
  446. {
  447. const VECT_OP_TYPE* dep = dbp + dn;
  448. VECT_OP_TYPE* dp = dbp;
  449. while( dbp < dep )
  450. *dbp++ *= s;
  451. return dp;
  452. }
  453. VECT_OP_TYPE* VECT_OP_FUNC(MultVVS)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sbp, VECT_OP_TYPE s )
  454. {
  455. const VECT_OP_TYPE* dep = dbp + dn;
  456. VECT_OP_TYPE* dp = dbp;
  457. while( dbp < dep )
  458. *dbp++ = *sbp++ * s;
  459. return dp;
  460. }
  461. VECT_OP_TYPE* VECT_OP_FUNC(MultVaVS)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sbp, VECT_OP_TYPE s )
  462. {
  463. const VECT_OP_TYPE* dep = dbp + dn;
  464. VECT_OP_TYPE* dp = dbp;
  465. while( dbp < dep )
  466. *dbp++ += *sbp++ * s;
  467. return dp;
  468. }
  469. VECT_OP_TYPE* VECT_OP_FUNC(MultSumVVS)(VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sbp, VECT_OP_TYPE s )
  470. {
  471. const VECT_OP_TYPE* dep = dbp + dn;
  472. VECT_OP_TYPE* dp = dbp;
  473. while( dbp < dep )
  474. *dbp++ += *sbp++ * s;
  475. return dp;
  476. }
  477. VECT_OP_TYPE* VECT_OP_FUNC(DivVVS)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sb0p, VECT_OP_TYPE s1 )
  478. {
  479. const VECT_OP_TYPE* dep = dbp + dn;
  480. VECT_OP_TYPE* dp = dbp;
  481. while( dbp < dep )
  482. *dbp++ = *sb0p++ / s1;
  483. return dp;
  484. }
  485. VECT_OP_TYPE* VECT_OP_FUNC(DivVV)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sb0p )
  486. {
  487. const VECT_OP_TYPE* dep = dbp + dn;
  488. VECT_OP_TYPE* dp = dbp;
  489. while( dbp < dep )
  490. *dbp++ /= *sb0p++;
  491. return dp;
  492. }
  493. VECT_OP_TYPE* VECT_OP_FUNC(DivVVV)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sb0p, const VECT_OP_TYPE* sb1p )
  494. {
  495. const VECT_OP_TYPE* dep = dbp + dn;
  496. VECT_OP_TYPE* dp = dbp;
  497. while( dbp < dep )
  498. *dbp++ = *sb0p++ / *sb1p++;
  499. return dp;
  500. }
  501. VECT_OP_TYPE* VECT_OP_FUNC(DivVVNN)(VECT_OP_TYPE* dp, unsigned dn, unsigned dnn, const VECT_OP_TYPE* v, unsigned n )
  502. {
  503. const VECT_OP_TYPE* ep = dp + (dn*dnn);
  504. VECT_OP_TYPE* dbp = dp;
  505. for(; dp < ep; v+=n, dp+=dnn )
  506. *dp /= *v;
  507. return dbp;
  508. }
  509. VECT_OP_TYPE* VECT_OP_FUNC(DivVS)( VECT_OP_TYPE* dbp, unsigned dn, VECT_OP_TYPE s )
  510. {
  511. const VECT_OP_TYPE* dep = dbp + dn;
  512. VECT_OP_TYPE* dp = dbp;
  513. while( dbp < dep )
  514. *dbp++ /= s;
  515. return dp;
  516. }
  517. VECT_OP_TYPE* VECT_OP_FUNC(DivVSV)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE s0, const VECT_OP_TYPE* sb1p )
  518. {
  519. const VECT_OP_TYPE* dep = dbp + dn;
  520. VECT_OP_TYPE* dp = dbp;
  521. while( dbp < dep )
  522. *dbp++ = s0 / *sb1p++;
  523. return dp;
  524. }
  525. VECT_OP_TYPE* VECT_OP_FUNC(DivVVZ)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sb0p )
  526. {
  527. const VECT_OP_TYPE* dep = dbp + dn;
  528. VECT_OP_TYPE* dp = dbp;
  529. for(; dbp < dep; ++sb0p )
  530. if( *sb0p == 0 )
  531. *dbp++ = 0;
  532. else
  533. *dbp++ /= *sb0p;
  534. return dp;
  535. }
  536. VECT_OP_TYPE* VECT_OP_FUNC(DivVVVZ)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sb0p, const VECT_OP_TYPE* sb1p )
  537. {
  538. const VECT_OP_TYPE* dep = dbp + dn;
  539. VECT_OP_TYPE* dp = dbp;
  540. for(; dbp < dep; ++sb0p,++sb1p )
  541. if( *sb1p == 0 )
  542. *dbp++ = 0;
  543. else
  544. *dbp++ = *sb0p / *sb1p;
  545. return dp;
  546. }
  547. VECT_OP_TYPE* VECT_OP_FUNC(DivMS)( VECT_OP_TYPE* dp, unsigned drn, unsigned dcn, const VECT_OP_TYPE* sp )
  548. {
  549. unsigned i;
  550. for(i=0; i<dcn; ++i)
  551. VECT_OP_FUNC(DivVS)( dp + i*drn, drn, sp[i] );
  552. return dp;
  553. }
  554. VECT_OP_TYPE VECT_OP_FUNC(Sum)( const VECT_OP_TYPE* bp, unsigned n )
  555. {
  556. const VECT_OP_TYPE* ep = bp + n;
  557. VECT_OP_TYPE s = 0;
  558. while( bp < ep )
  559. s += *bp++;
  560. return s;
  561. }
  562. VECT_OP_TYPE VECT_OP_FUNC(SumN)( const VECT_OP_TYPE* bp, unsigned n, unsigned stride )
  563. {
  564. const VECT_OP_TYPE* ep = bp + (n*stride);
  565. VECT_OP_TYPE s = 0;
  566. for(; bp < ep; bp += stride )
  567. s += *bp;
  568. return s;
  569. }
  570. VECT_OP_TYPE* VECT_OP_FUNC(SumM)(const VECT_OP_TYPE* sp, unsigned srn, unsigned scn, VECT_OP_TYPE* dp )
  571. {
  572. unsigned i;
  573. for(i=0; i<scn; ++i)
  574. dp[i] = VECT_OP_FUNC(Sum)(sp + (i*srn), srn );
  575. return dp;
  576. }
  577. VECT_OP_TYPE* VECT_OP_FUNC(SumMN)(const VECT_OP_TYPE* sp, unsigned srn, unsigned scn, VECT_OP_TYPE* dp )
  578. {
  579. unsigned i;
  580. for(i=0; i<srn; ++i)
  581. dp[i] = VECT_OP_FUNC(SumN)(sp + i, scn, srn );
  582. return dp;
  583. }
  584. // mi is a target value - it holds the number of elements in ap[an] which must be be less than the median value.
  585. // If the initial array contains an even number of values then the median value is formed by averaging the two center values.
  586. // In this case *evenFlPtr is set and used to indicate that the center-upper value must be found during undwinding.
  587. VECT_OP_TYPE VECT_OP_FUNC(MedianSearch)( unsigned mi, const VECT_OP_TYPE* ap, unsigned an, bool* evenFlPtr )
  588. {
  589. VECT_OP_TYPE x = ap[0]; // pick a random value as a potential median value
  590. VECT_OP_TYPE a1[ an ]; // values below x
  591. VECT_OP_TYPE a3[ an ]; // values above x
  592. unsigned a1n = 0;
  593. unsigned a2n = 0; // values equal to x
  594. unsigned a3n = 0;
  595. const VECT_OP_TYPE* abp = ap;
  596. const VECT_OP_TYPE* aep = abp + an;
  597. for(; abp < aep; ++abp )
  598. {
  599. if( *abp < x )
  600. a1[a1n++] = *abp;
  601. else
  602. {
  603. if( *abp > x )
  604. a3[a3n++] = *abp;
  605. else
  606. ++a2n;
  607. }
  608. }
  609. //printf("%i : %i %i %i\n",mi,a1n,a2n,a3n);
  610. // there are more values below x (mi remains the target split point)
  611. if( a1n > mi )
  612. {
  613. x = VECT_OP_FUNC(MedianSearch)(mi,a1,a1n,evenFlPtr);
  614. }
  615. else
  616. {
  617. // the target was located
  618. if( a1n+a2n >= mi )
  619. {
  620. // if a1n alone matches mi then the max value in a1[] holds the median value otherwise x is the median
  621. if(a1n>=1 && a1n==mi)
  622. {
  623. VECT_OP_TYPE mv = VECT_OP_FUNC(Max)(a1,a1n,1);
  624. x = *evenFlPtr ? (mv+x)/2 : mv;
  625. *evenFlPtr = false;
  626. }
  627. // if the evenFl is set then the closest value above the median (x) must be located
  628. if( *evenFlPtr )
  629. {
  630. // if the next greater value is in a2[]
  631. if( a2n > 1 && (a1n+a2n) > mi )
  632. *evenFlPtr = false;
  633. else
  634. // if the next greater value is in a3[]
  635. if( a3n > 1 )
  636. {
  637. x = (x + VECT_OP_FUNC(Min)(a3,a3n,1))/2;
  638. *evenFlPtr = false;
  639. }
  640. }
  641. // no need for unwind processing - all the possibilities at this level have been exhausted
  642. return x;
  643. }
  644. else
  645. {
  646. // There are more values above x - the median must therefore be in a3[].
  647. // Reset mi cmcounting for the fact that we know that there are
  648. // a1n+a2n values below the lowest value in a3.
  649. x = VECT_OP_FUNC(MedianSearch)(mi - (a1n+a2n), a3, a3n, evenFlPtr );
  650. }
  651. }
  652. if( *evenFlPtr )
  653. {
  654. // find the first value greater than x
  655. while( ap < aep && *ap <= x )
  656. ++ap;
  657. if( ap < aep )
  658. {
  659. VECT_OP_TYPE v = *ap++;
  660. // find the nearest value greater than x
  661. for(; ap < aep; ++ap )
  662. if( *ap > x && ((*ap - x) < (v-x)))
  663. v = *ap;
  664. x = (v + x)/2;
  665. *evenFlPtr = false;
  666. }
  667. }
  668. return x;
  669. }
  670. VECT_OP_TYPE VECT_OP_FUNC(Median)( const VECT_OP_TYPE* bp, unsigned n )
  671. {
  672. bool evenFl = cmIsEvenU(n);
  673. unsigned medIdx = evenFl ? n/2 : (n+1)/2;
  674. return VECT_OP_FUNC(MedianSearch)( medIdx, bp, n, &evenFl );
  675. }
  676. unsigned VECT_OP_FUNC(MinIndex)( const VECT_OP_TYPE* bp, unsigned n, unsigned stride )
  677. {
  678. const VECT_OP_TYPE* ep = bp + (n*stride);
  679. if( bp >= ep )
  680. return cmInvalidIdx;
  681. const VECT_OP_TYPE* p = bp;
  682. const VECT_OP_TYPE* mp = bp;
  683. bp+=stride;
  684. for(; bp < ep; bp+=stride )
  685. if( *bp < *mp )
  686. mp = bp;
  687. return (mp - p)/stride;
  688. }
  689. unsigned VECT_OP_FUNC(MaxIndex)( const VECT_OP_TYPE* bp, unsigned n, unsigned stride )
  690. {
  691. const VECT_OP_TYPE* ep = bp + (n*stride);
  692. if( bp >= ep )
  693. return cmInvalidIdx;
  694. const VECT_OP_TYPE* p = bp;
  695. const VECT_OP_TYPE* mp = bp;
  696. bp+=stride;
  697. for(; bp < ep; bp+=stride )
  698. if( *bp > *mp )
  699. mp = bp;
  700. return (mp - p)/stride;
  701. }
  702. VECT_OP_TYPE VECT_OP_FUNC(Min)( const VECT_OP_TYPE* bp, unsigned n, unsigned stride )
  703. {
  704. unsigned i;
  705. if((i = VECT_OP_FUNC(MinIndex)(bp,n,stride)) == cmInvalidIdx )
  706. {
  707. assert(0);
  708. return 0;
  709. }
  710. return bp[i*stride];
  711. }
  712. VECT_OP_TYPE VECT_OP_FUNC(Max)( const VECT_OP_TYPE* bp, unsigned n, unsigned stride )
  713. {
  714. unsigned i;
  715. if((i = VECT_OP_FUNC(MaxIndex)(bp,n,stride)) == cmInvalidIdx )
  716. {
  717. assert(0);
  718. return 0;
  719. }
  720. return bp[i*stride];
  721. }
  722. VECT_OP_TYPE* VECT_OP_FUNC(MinVV)( VECT_OP_TYPE* dp, unsigned dn, const VECT_OP_TYPE* sp )
  723. {
  724. unsigned i;
  725. for(i=0; i<dn; ++i)
  726. if( sp[i] < dp[i] )
  727. dp[i] = sp[i];
  728. return dp;
  729. }
  730. VECT_OP_TYPE* VECT_OP_FUNC(MaxVV)( VECT_OP_TYPE* dp, unsigned dn, const VECT_OP_TYPE* sp )
  731. {
  732. unsigned i;
  733. for(i=0; i<dn; ++i)
  734. if( sp[i] > dp[i] )
  735. dp[i] = sp[i];
  736. return dp;
  737. }
  738. unsigned* VECT_OP_FUNC(MinIndexM)( unsigned* dp, const VECT_OP_TYPE* sp, unsigned srn, unsigned scn )
  739. {
  740. unsigned i = 0;
  741. for(i=0; i<scn; ++i)
  742. dp[i] = VECT_OP_FUNC(MinIndex)(sp + (i*srn), srn, 1 );
  743. return dp;
  744. }
  745. unsigned* VECT_OP_FUNC(MaxIndexM)( unsigned* dp, const VECT_OP_TYPE* sp, unsigned srn, unsigned scn )
  746. {
  747. unsigned i = 0;
  748. for(i=0; i<scn; ++i)
  749. dp[i] = VECT_OP_FUNC(MaxIndex)(sp + (i*srn), srn, 1 );
  750. return dp;
  751. }
  752. VECT_OP_TYPE VECT_OP_FUNC(Mode)( const VECT_OP_TYPE* sp, unsigned sn )
  753. {
  754. unsigned n[sn];
  755. VECT_OP_TYPE v[sn];
  756. unsigned i,j,k = 0;
  757. unsigned n0 = 0; // idx of most freq occurring ele
  758. unsigned n1 = -1; // idx of 2nd most freq occurring ele
  759. for(i=0; i<sn; ++i)
  760. {
  761. // find sp[i] in v[]
  762. for(j=0; j<k; ++j)
  763. if( sp[i] == v[j] )
  764. {
  765. ++n[j];
  766. break;
  767. }
  768. // sp[i] was not found in v[]
  769. if( k == j )
  770. {
  771. v[j] = sp[i];
  772. n[j] = 1;
  773. ++k;
  774. }
  775. // n[j] holds frq of sp[i]
  776. // do nothing if j is already most freq
  777. if( j != n0 )
  778. {
  779. // if j is new most freq
  780. if( n[j] > n[n0] )
  781. {
  782. n1 = n0;
  783. n0 = j;
  784. }
  785. else
  786. // if j is 2nd most freq
  787. if( (n1==-1) || (n[j] > n[n1]) )
  788. n1 = j;
  789. }
  790. // if diff between two most freq is greater than remaining ele's
  791. if( (n1!=-1) && (n[n0]-n[n1]) >= (sn-i) )
  792. break;
  793. }
  794. // if there are no ele's with same count
  795. if( n[n0] > n[n1] )
  796. return v[n0];
  797. // break tie between ele's with same count be returning min value
  798. // (this is the same as Matlab tie break criteria)
  799. j = 0;
  800. for(i=1; i<k; ++i)
  801. if( (n[i] > n[j]) || (n[i] == n[j] && v[i] < v[j]) )
  802. j=i;
  803. return v[j];
  804. }
  805. VECT_OP_TYPE* VECT_OP_FUNC(Abs)( VECT_OP_TYPE* dbp, unsigned dn )
  806. {
  807. unsigned i;
  808. for(i=0; i<dn; ++i)
  809. if( dbp[i]<0 )
  810. dbp[i] = -dbp[i];
  811. return dbp;
  812. }
  813. VECT_OP_TYPE* VECT_OP_FUNC(HalfWaveRectify)(VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sp )
  814. {
  815. VECT_OP_TYPE* dp = dbp;
  816. VECT_OP_TYPE* ep = dbp + dn;
  817. for(; dp < ep; ++dp,++sp )
  818. *dp = *sp < 0 ? 0 : *sp;
  819. return dbp;
  820. }
  821. bool VECT_OP_FUNC(IsEqual)( const VECT_OP_TYPE* s0p, const VECT_OP_TYPE* s1p, unsigned sn )
  822. {
  823. const VECT_OP_TYPE* ep = s0p + sn;
  824. for(; s0p < ep; ++s0p,++s1p )
  825. if( *s0p != *s1p )
  826. return false;
  827. return true;
  828. }
  829. bool VECT_OP_FUNC(IsClose)( const VECT_OP_TYPE* s0p, const VECT_OP_TYPE* s1p, unsigned sn, double eps )
  830. {
  831. const VECT_OP_TYPE* ep = s0p + sn;
  832. for(; s0p < ep; ++s0p,++s1p )
  833. {
  834. if( !cmIsClose(*s0p,*s1p,eps) )
  835. return false;
  836. }
  837. return true;
  838. }
  839. unsigned VECT_OP_FUNC(Find)( const VECT_OP_TYPE* sp, unsigned sn, VECT_OP_TYPE key )
  840. {
  841. const VECT_OP_TYPE* sbp = sp;
  842. const VECT_OP_TYPE* ep = sp + sn;
  843. while( sp<ep )
  844. if( *sp++ == key )
  845. break;
  846. if( sp==ep )
  847. return cmInvalidIdx;
  848. return (sp-1) - sbp;
  849. }
  850. unsigned VECT_OP_FUNC(Count)( const VECT_OP_TYPE* sp, unsigned sn, VECT_OP_TYPE key )
  851. {
  852. unsigned cnt = 0;
  853. const VECT_OP_TYPE* ep = sp + sn;
  854. while( sp<ep )
  855. if( *sp++ == key )
  856. ++cnt;
  857. return cnt;
  858. }
  859. VECT_OP_TYPE* VECT_OP_FUNC(ReplaceLte)( VECT_OP_TYPE* dp, unsigned dn, const VECT_OP_TYPE* sp, VECT_OP_TYPE lteKeyVal, VECT_OP_TYPE replaceVal )
  860. {
  861. VECT_OP_TYPE* rp = dp;
  862. const VECT_OP_TYPE* ep = dp + dn;
  863. for(; dp < ep; ++sp )
  864. *dp++ = *sp <= lteKeyVal ? replaceVal : *sp;
  865. return rp;
  866. }
  867. void VECT_OP_FUNC(FnThresh)( const VECT_OP_TYPE* xV, unsigned xN, unsigned wndN, VECT_OP_TYPE* yV, unsigned yStride, VECT_OP_TYPE (*fnPtr)(const VECT_OP_TYPE*, unsigned) )
  868. {
  869. int i0 = cmIsOddU(wndN) ? (wndN-1)/2 : wndN/2;
  870. int i1 = cmIsOddU(wndN) ? (wndN-1)/2 : wndN/2 - 1;
  871. int i,j;
  872. i0 = -i0;
  873. if( fnPtr == NULL )
  874. fnPtr = &(VECT_OP_FUNC(Median));
  875. for(i=0; i<xN; ++i,++i0,++i1)
  876. {
  877. j = (i*yStride);
  878. if( i0 < 0 )
  879. if( i1 >= xN )
  880. yV[j] = (*fnPtr)(xV,xN);
  881. else
  882. yV[j] = (*fnPtr)(xV,i1+1);
  883. else if( i1 >= xN )
  884. yV[j] = (*fnPtr)(xV+i0,xN-i0);
  885. else
  886. yV[j] = (*fnPtr)(xV+i0,wndN);
  887. }
  888. }
  889. void VECT_OP_FUNC(MedianFilt)( const VECT_OP_TYPE* xV, unsigned xN, unsigned wndN, VECT_OP_TYPE* yV, unsigned yStride )
  890. {
  891. int i0 = cmIsOddU(wndN) ? (wndN-1)/2 : wndN/2;
  892. int i1 = cmIsOddU(wndN) ? (wndN-1)/2 : wndN/2 - 1;
  893. int i,j;
  894. VECT_OP_TYPE tV[ wndN ];
  895. i0 = -i0;
  896. VECT_OP_FUNC(Fill)(tV,wndN,0);
  897. for(i=0; i<xN; ++i,++i0,++i1)
  898. {
  899. j = (i*yStride);
  900. // note that the position of the zero padding in tV[]
  901. // does not matter because the median calcluation does
  902. // not make any assumptions about the order of the argument
  903. // vector.
  904. if( i0 < 0 )
  905. {
  906. VECT_OP_FUNC(Copy)(tV,wndN+i0,xV);
  907. VECT_OP_FUNC(Fill)(tV+wndN+i0,labs(i0),0);
  908. //VECT_OP_FUNC(Print)(NULL,1,wndN,tV,-1,-1);
  909. yV[j] = VECT_OP_FUNC(Median)(tV,wndN);
  910. continue;
  911. }
  912. if( i1 >= xN )
  913. {
  914. VECT_OP_FUNC(Copy)(tV,wndN-(i1-xN+1),xV+i0);
  915. VECT_OP_FUNC(Fill)(tV+wndN-(i1-xN+1),i1-xN+1,0);
  916. //VECT_OP_FUNC(Print)(NULL,1,wndN,tV,-1,-1);
  917. yV[j] = VECT_OP_FUNC(Median)(tV,wndN);
  918. continue;
  919. }
  920. //VECT_OP_FUNC(Print)(NULL,1,wndN,xV+i0,-1,-1);
  921. yV[j] = VECT_OP_FUNC(Median)(xV+i0,wndN);
  922. }
  923. }
  924. unsigned* VECT_OP_FUNC(LevEditDistAllocMtx)(unsigned maxN)
  925. {
  926. maxN += 1;
  927. unsigned* m = cmMemAllocZ(unsigned,maxN*maxN);
  928. unsigned* p = m;
  929. unsigned i;
  930. // initialize the comparison matrix with the default costs in the
  931. // first row and column
  932. // (Note that this matrix is not oriented in column major order like most 'cm' matrices.)
  933. for(i=0; i<maxN; ++i)
  934. {
  935. p[i] = i; // 0th row
  936. p[ i * maxN ] = i; // 0th col
  937. }
  938. return m;
  939. }
  940. double VECT_OP_FUNC(LevEditDist)(unsigned mtxMaxN, unsigned* m, const VECT_OP_TYPE* s0, int n0, const VECT_OP_TYPE* s1, int n1, unsigned maxN )
  941. {
  942. mtxMaxN += 1;
  943. assert( n0 < mtxMaxN && n1 < mtxMaxN );
  944. int v = 0;
  945. unsigned i;
  946. // Note that m[maxN,maxN] is not oriented in column major order like most 'cm' matrices.
  947. for(i=1; i<n0+1; ++i)
  948. {
  949. unsigned ii = i * mtxMaxN; // current row
  950. unsigned i_1 = ii - mtxMaxN; // previous row
  951. unsigned j;
  952. for( j=1; j<n1+1; ++j)
  953. {
  954. int cost = s0[i-1] == s1[j-1] ? 0 : 1;
  955. //m[i][j] = min( m[i-1][j] + 1, min( m[i][j-1] + 1, m[i-1][j-1] + cost ) );
  956. m[ ii + j ] = v = cmMin( m[ i_1 + j] + 1, cmMin( m[ ii + j - 1] + 1, m[ i_1 + j - 1 ] + cost ) );
  957. }
  958. }
  959. return (double) v / maxN;
  960. }
  961. double VECT_OP_FUNC(LevEditDistWithCostThresh)( int mtxMaxN, unsigned* m, const VECT_OP_TYPE* s0, int n0, const VECT_OP_TYPE* s1, int n1, double maxCost, unsigned maxN )
  962. {
  963. mtxMaxN += 1;
  964. int v = 0;
  965. maxCost = cmMin(1.0,cmMax(0.0,maxCost));
  966. int iMaxCost = ceil( maxCost * maxN );
  967. assert( iMaxCost > 0 && maxCost > 0 );
  968. // If the two strings are different lengths and the min possible distance is
  969. // greater than the threshold then return the threshold as the cost.
  970. // (Note: For strings of different length the min possible distance is the
  971. // difference in length between the two strings).
  972. if( abs(n0-n1) > iMaxCost )
  973. return maxCost;
  974. int i;
  975. // for each row in the matrix ...
  976. for(i=1; i<n0+1; ++i)
  977. {
  978. int ii = i * mtxMaxN; // current row
  979. int i_1 = ii - mtxMaxN; // previous row
  980. // Limit the row to (2*iMaxCost)+1 diagnal strip.
  981. // This strip is based on the idea that the best case can be precomputed for
  982. // all matrix elements in advance - where the best case for position i,j is:
  983. // abs(i-j). This can be justified based on the idea that the least possible
  984. // distance between two strings of length i and j is abs(i-1). The minimum least
  985. // possible distance is therefore found on the matrix diagnal and grows as the
  986. // distance from the diagnal increases.
  987. int ji = cmMax( 1, i - iMaxCost );
  988. int jn = cmMin(iMaxCost + i, n1) + 1;
  989. int j;
  990. // fill in (max cost + 1) as the value in the column before the starting column
  991. // (it will be referred to during the first computation in this row)
  992. if( ji >= 2 )
  993. m[ ii + (ji-1) ] = iMaxCost + 1;
  994. // for each column in the diagnal stripe - beginning with the leftmost column.
  995. for( j=ji; j<jn; ++j)
  996. {
  997. int cost = s0[i-1] == s1[j-1] ? 0 : 1;
  998. m[ ii + j ] = v = cmMin( m[ i_1 + j] + 1, cmMin( m[ ii + j - 1] + 1, m[ i_1 + j - 1 ] + cost ) );
  999. }
  1000. // fill in (max cost + 1) in the column following the last column
  1001. // (it will be referred to during computation of the following row)
  1002. if( j < n1+1 )
  1003. m[ii + j] = iMaxCost + 1;
  1004. }
  1005. assert( v >= 0 );
  1006. return cmMin( maxCost , (double) v / maxN);
  1007. }
  1008. #endif