libcm is a C development framework with an emphasis on audio signal processing applications.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

cmVectOpsRICode.h 29KB

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