//| Copyright: (C) 2009-2020 Kevin Larke //| License: GNU GPL version 3.0 or above. See the accompanying LICENSE file. #ifdef cmVectOpsTemplateCode_h VECT_OP_TYPE* VECT_OP_FUNC(CumSum)(VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sbp) { VECT_OP_TYPE* dep = dbp + dn; VECT_OP_TYPE* rp = dbp; VECT_OP_TYPE sum = 0; while( dbp < dep ) { sum += *sbp++; *dbp++ = sum; } return rp; } bool VECT_OP_FUNC(Equal)( const VECT_OP_TYPE* s0p, const VECT_OP_TYPE* s1p, unsigned sn ) { const VECT_OP_TYPE* ep = s0p + sn; while( s0p < ep ) if( *s0p++ != *s1p++ ) return false; return true; } VECT_OP_TYPE* VECT_OP_FUNC(LinSpace)( VECT_OP_TYPE* dbp, unsigned dn, VECT_OP_TYPE base, VECT_OP_TYPE limit ) { unsigned i = 0; for(; i colCnt) cn = colCnt; if( colCnt > outColCnt ) { if( cmIsFlag(flags,cmPrintMatlabLabelsFl) ) VECT_OP_FUNC(VPrint)(rpt,"Columns:%i to %i\n",ci0,cn-1); else if( cmIsFlag(flags,cmPrintShortLabelsFl) ) VECT_OP_FUNC(VPrint)(rpt,"%3i: ",ci0); } if( rowCnt > 1 ) VECT_OP_FUNC(VPrint)(rpt,"\n"); for(ri=0; ri 0 ) VECT_OP_FUNC(VPrint)(rpt,"\n"); } } } void VECT_OP_FUNC(Print)( cmRpt_t* rpt, unsigned rn, unsigned cn, const VECT_OP_TYPE* sbp ) { VECT_OP_FUNC(Printf)(rpt,rn,cn,sbp,cmDefaultFieldWidth,cmDefaultDecPlCnt,"%*.*f ",cmPrintShortLabelsFl); } void VECT_OP_FUNC(PrintE)( cmRpt_t* rpt, unsigned rn, unsigned cn, const VECT_OP_TYPE* sbp ) { VECT_OP_FUNC(Printf)(rpt,rn,cn,sbp,cmDefaultFieldWidth,cmDefaultDecPlCnt,"%*.*e ",cmPrintShortLabelsFl); } void VECT_OP_FUNC(PrintLf)( const char* label, cmRpt_t* rpt, unsigned rn, unsigned cn, const VECT_OP_TYPE* dbp, unsigned fieldWidth, unsigned decPlCnt, const char* fmt ) { VECT_OP_FUNC(VPrint)( rpt, "%s\n", label ); VECT_OP_FUNC(Printf)( rpt, rn, cn, dbp, fieldWidth, decPlCnt,fmt,cmPrintShortLabelsFl ); } void VECT_OP_FUNC(PrintL)( const char* label, cmRpt_t* rpt, unsigned rn, unsigned cn, const VECT_OP_TYPE* dbp ) { VECT_OP_FUNC(VPrint)( rpt, "%s\n", label ); VECT_OP_FUNC(Printf)( rpt, rn, cn, dbp, cmDefaultFieldWidth,cmDefaultDecPlCnt,"%*.*f ",cmPrintShortLabelsFl ); } void VECT_OP_FUNC(PrintLE)( const char* label, cmRpt_t* rpt, unsigned rn, unsigned cn, const VECT_OP_TYPE* dbp ) { VECT_OP_FUNC(VPrint)( rpt, "%s\n", label ); VECT_OP_FUNC(Printf)( rpt, rn, cn, dbp, cmDefaultFieldWidth,cmDefaultDecPlCnt,"%*.*e ",cmPrintShortLabelsFl ); } VECT_OP_TYPE* VECT_OP_FUNC(NormalizeProbabilityVV)(VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sbp) { VECT_OP_TYPE sum = VECT_OP_FUNC(Sum)(sbp,dn); if( sum == 0 ) sum = 1; return VECT_OP_FUNC(DivVVS)(dbp,dn,sbp,sum); } VECT_OP_TYPE* VECT_OP_FUNC(NormalizeProbability)(VECT_OP_TYPE* dbp, unsigned dn) { return VECT_OP_FUNC(NormalizeProbabilityVV)(dbp,dn,dbp); } VECT_OP_TYPE* VECT_OP_FUNC(NormalizeProbabilityN)(VECT_OP_TYPE* dbp, unsigned dn, unsigned stride) { VECT_OP_TYPE sum = VECT_OP_FUNC(SumN)(dbp,dn,stride); if( sum == 0 ) return dbp; VECT_OP_TYPE* dp = dbp; VECT_OP_TYPE* ep = dp + (dn*stride); for(; dp < ep; dp+=stride ) *dp /= sum; return dbp; } VECT_OP_TYPE* VECT_OP_FUNC(StandardizeRows)( VECT_OP_TYPE* dbp, unsigned drn, unsigned dcn, VECT_OP_TYPE* uV, VECT_OP_TYPE* sdV ) { bool uFl = false; bool sFl = false; unsigned i; if( uV == NULL ) { uV = cmMemAllocZ(VECT_OP_TYPE,drn); uFl = true; } if( sdV == NULL ) { sdV = cmMemAllocZ(VECT_OP_TYPE,drn); sFl = true; } VECT_OP_FUNC(MeanM)(uV, dbp, drn, dcn, 1 ); VECT_OP_FUNC(VarianceM)(sdV, dbp, drn, dcn, uV, 1 ); for(i=0; imx ) { mi = i; mx = cmAbs(dp[i]); } VECT_OP_FUNC(MultVS)(dp,dn,fact/mx); return mi; } VECT_OP_TYPE VECT_OP_FUNC(Mean)( const VECT_OP_TYPE* bp, unsigned n ) { return VECT_OP_FUNC(Sum)(bp,n)/n; } VECT_OP_TYPE VECT_OP_FUNC(MeanN)( const VECT_OP_TYPE* bp, unsigned n, unsigned stride ) { return VECT_OP_FUNC(SumN)(bp,n,stride)/n; } VECT_OP_TYPE* VECT_OP_FUNC(MeanM)( VECT_OP_TYPE* dp, const VECT_OP_TYPE* sp, unsigned srn, unsigned scn, unsigned dim ) { unsigned i; unsigned cn = dim == 0 ? scn : srn; unsigned rn = dim == 0 ? srn : scn; unsigned inc = dim == 0 ? srn : 1; unsigned stride = dim == 0 ? 1 : srn; unsigned d0 = 0; for(i=0; i 1 ) { n = 0; for(i=0; i1 ) VECT_OP_FUNC(DivVS)( yM, D*D, n-1 ); } void VECT_OP_FUNC(GaussCovariance2)(VECT_OP_TYPE* yM, unsigned D, const VECT_OP_TYPE* (*srcFunc)(void* userPtr, unsigned idx), unsigned xN, void* userPtr, const VECT_OP_TYPE* uV, const unsigned* selIdxV, unsigned selKey ) { unsigned i,j,k = 0,n=0; VECT_OP_TYPE tV[ D ]; const VECT_OP_TYPE* sp; VECT_OP_FUNC(Fill)(yM,D*D,0); // if the mean was not given - then calculate it if( uV == NULL ) { VECT_OP_FUNC(Fill)(tV,D,0); n = 0; // sum each row of xM[] into uM[] for(i=0; i 1 ) VECT_OP_FUNC(DivVS)( yM, D*D, n-1 ); // fill in the lower triangle for(j=0; j= 0) != (*bp >= 0)) : 0 ; const VECT_OP_TYPE* ep = bp + bn; for(; bp= 0) != (*(bp+1) >= 0) ) ++n; if( delaySmpPtr != NULL ) *delaySmpPtr = *bp; return n; } VECT_OP_TYPE VECT_OP_FUNC(SquaredSum)( const VECT_OP_TYPE* bp, unsigned bn ) { VECT_OP_TYPE sum = 0; const VECT_OP_TYPE* ep = bp + bn; for(; bp < ep; ++bp ) sum += *bp * *bp; return sum; } VECT_OP_TYPE VECT_OP_FUNC(RMS)( const VECT_OP_TYPE* bp, unsigned bn, unsigned wndSmpCnt ) { const VECT_OP_TYPE* ep = bp + bn; if( bn==0 ) return 0; assert( bn <= wndSmpCnt ); double sum = 0; for(; bp < ep; ++bp ) sum += *bp * *bp; return (VECT_OP_TYPE)sqrt(sum/wndSmpCnt); } VECT_OP_TYPE* VECT_OP_FUNC(RmsV)( VECT_OP_TYPE* dp, unsigned dn, const VECT_OP_TYPE* sp, unsigned sn, unsigned wndSmpCnt, unsigned hopSmpCnt ) { const VECT_OP_TYPE* dep = dp + dn; const VECT_OP_TYPE* sep = sp + sn; VECT_OP_TYPE* rp = dp; for(; dp 0 ); if( dM == NULL ) { dM = cmMemAllocZ( VECT_OP_TYPE, srn*selIdxN ); freeFl = true; } // allocate distM[scn,selIdxN] to hold the distances from each selected column to all columns in sM[] VECT_OP_TYPE* distM = cmMemAllocZ( VECT_OP_TYPE, scn*selIdxN ); // sumV[] is a temp vector to hold the summed distances to from the selected columns to each column in sM[] VECT_OP_TYPE* sumV = cmMemAllocZ( VECT_OP_TYPE, scn ); // select a random point from sM[] and copy it to the first column of dM[] cmVOU_Random(&i,1,scn); VECT_OP_FUNC(Copy)(dM, srn, sM + (i*srn)); if( selIdxV != NULL ) selIdxV[0] = i; for(dcn=1; dcn= 10 ) { det1 /= 10; det2 += 1; } } // Here's where underflow or overflow might happen. // Enable floating point exception handling to trap. det1 *= pow(10.0,det2); return det1; } // take the inverse of a matrix factored via lapack dgetrf_() VECT_OP_TYPE* VECT_OP_FUNC(LUInverse)(VECT_OP_TYPE* dp, int_lap_t* ipiv, int drn ) { int_lap_t ispec = 1; int_lap_t rn = drn; int_lap_t n1 = drn; int_lap_t n2 = drn; int_lap_t n3 = drn; int_lap_t n4 = drn; char funcNameStr[] = {"DGETRI"}; // Calculate the NB factor for LWORK - // The two args are length of string args 'funcNameStr' and ' '. // It is not clear how many 'n' args are requred so all are passed set to 'drn' #ifdef OS_OSX int nb = ilaenv_(&ispec, funcNameStr, " ", &n1,&n2,&n3,&n4 ); #else int nb = ilaenv_(&ispec, funcNameStr, " ", &n1,&n2,&n3,&n4, strlen(funcNameStr), 1 ); #endif VECT_OP_TYPE w[drn * nb]; // allocate working memory int_lap_t info; // calculate inv(A) base on LU factorization VECT_OP_LAP_FUNC(getri_)(&rn,dp,&rn,ipiv,w,&rn,&info); assert(info==0); return info ==0 ? dp : NULL; } VECT_OP_TYPE VECT_OP_FUNC(DetM)( const VECT_OP_TYPE* sp, unsigned srn ) { int_lap_t arn = srn; VECT_OP_TYPE A[ arn * arn ]; int_lap_t ipiv[ arn ]; int_lap_t info; VECT_OP_FUNC(Copy)(A,arn*arn,sp); // PLU factor VECT_OP_LAP_FUNC(getrf_)(&arn,&arn,A,&arn,ipiv,&info); if( info == 0 ) return VECT_OP_FUNC(LUDet)(A,ipiv,arn); return 0; } VECT_OP_TYPE VECT_OP_FUNC(DetDiagM)( const VECT_OP_TYPE* sp, unsigned srn ) { return VECT_OP_FUNC(LUDet)(sp,NULL,srn); } VECT_OP_TYPE VECT_OP_FUNC(LogDetM)( const VECT_OP_TYPE* sp, unsigned srn ) { cmReal_t det = 0; unsigned ne2 = srn * srn; VECT_OP_TYPE U[ne2]; const VECT_OP_TYPE* up = U; const VECT_OP_TYPE* ep = up + ne2; VECT_OP_FUNC(Copy)(U,ne2,sp); VECT_OP_FUNC(Chol)(U,srn); for(; up0 && bii > 0 ) { cnt += begW; sum += begW * sbp[ bii-1 ]; } if( endW>0 && eii+1 < sn ) { cnt += endW; sum += endW * sbp[ eii+1 ]; } return (VECT_OP_TYPE)(sum / cnt); } VECT_OP_TYPE* VECT_OP_FUNC(DownSampleAvg)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sbp, unsigned sn ) { const VECT_OP_TYPE* dep = dbp + dn; VECT_OP_TYPE* rp = dbp; unsigned i = 0; double fact = (double)sn / dn; assert( sn >= dn ); for(i=0; dbp < dep; ++i ) *dbp++ = VECT_OP_FUNC(FracAvg)( fact*i, fact*(i+1), sbp, sn ); return rp; } VECT_OP_TYPE* VECT_OP_FUNC(UpSampleInterp)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sbp, unsigned sn ) { const VECT_OP_TYPE* dep = dbp + dn; const VECT_OP_TYPE* sep = sbp + sn; VECT_OP_TYPE* rp = dbp; double fact = (double)sn / dn; double phs = 0; assert( sn <= dn ); while( dbp 1.0 ) { phs -= 1.0; sbp++; } } return rp; } VECT_OP_TYPE* VECT_OP_FUNC(FitToSize)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sbp, unsigned sn ) { if( dn == sn ) return VECT_OP_FUNC(Copy)(dbp,dn,sbp); if( dn < sn ) return VECT_OP_FUNC(DownSampleAvg)(dbp,dn,sbp,sn); return VECT_OP_FUNC(UpSampleInterp)(dbp,dn,sbp,sn); } VECT_OP_TYPE* VECT_OP_FUNC(LinearMap)(VECT_OP_TYPE* dV, unsigned dn, VECT_OP_TYPE* sV, unsigned sn ) { if( dn == sn ) { memcpy(dV,sV,dn*sizeof(VECT_OP_TYPE)); return dV; } unsigned i,j,k; // if stretching if( dn > sn ) { VECT_OP_TYPE f_n = (VECT_OP_TYPE)dn/sn; VECT_OP_TYPE f_nn = f_n; unsigned i_n = floor(f_n); k = 0; i = 0; // for each set of ceiling(dn/sn) dst values while(1) { // repeat floor(dn/sn) src val into dst for(j=0; j 0 ) { unsigned i; // initialize the buffer with the fundamental VECT_OP_FUNC(SynthSine)( dbp, dn, phase, srate, hz ); otCnt *= 2; // sum in each additional harmonic for(i=3; i 0 ) { unsigned i; // initialize the buffer with the fundamental VECT_OP_FUNC(SynthCosine)( dbp, dn, phase, srate, hz ); otCnt *= 2; // sum in each additional harmonic for(i=3; i 0 ) { unsigned i; // initialize the buffer with the fundamental VECT_OP_FUNC(SynthSine)( dbp, dn, phase, srate, hz ); // sum in each additional harmonic for(i=2; i 0 ) { unsigned i; // initialize the buffer with the fundamental VECT_OP_FUNC(SynthCosine)( dbp, dn, phase, srate, hz ); // sum in each additional harmonic for(i=1; i= dn ) break; dbp[j] = 1; ++i; } // Note that returning an integer value here loses precision // since j was rounded to the nearest integer. return j - dn; } VECT_OP_TYPE VECT_OP_FUNC(SynthPinkNoise)( VECT_OP_TYPE* dbp, unsigned n, VECT_OP_TYPE delaySmp ) { const VECT_OP_TYPE* dep = dbp + n; VECT_OP_TYPE tmp[ n ]; VECT_OP_FUNC(Random)(tmp,n,-1.0,1.0); VECT_OP_TYPE* sp = tmp; VECT_OP_TYPE reg = delaySmp; for(; dbp < dep; ++sp) { *dbp++ = (*sp + reg)/2.0; reg = *sp; } return *sp; } VECT_OP_TYPE* VECT_OP_FUNC(AmplToDbVV)( VECT_OP_TYPE* dbp, unsigned dn, const VECT_OP_TYPE* sbp, VECT_OP_TYPE minDb ) { VECT_OP_TYPE minVal = pow(10.0,minDb/20.0); VECT_OP_TYPE* dp = dbp; VECT_OP_TYPE* ep = dp + dn; for(; dp 120.0) sidelobeRejectDb = 120.0; if( sidelobeRejectDb < 60.0 ) beta = (0.76609 * pow(sidelobeRejectDb - 13.26,0.4)) + (0.09834*(sidelobeRejectDb-13.26)); else beta = 0.12438 * (sidelobeRejectDb + 6.3); return (VECT_OP_TYPE)beta; } VECT_OP_TYPE VECT_OP_FUNC(KaiserFreqResolutionFactor)( double sidelobeRejectDb ) { return (6.0 * (sidelobeRejectDb + 12.0))/155.0; } VECT_OP_TYPE* VECT_OP_FUNC(Kaiser)( VECT_OP_TYPE* dbp, unsigned n, double beta ) { bool zeroFl = false; int M = 0; double den = cmBessel0(beta); // wnd func denominator int cnt = n; int i; assert( n >= 3 ); // force ele cnt to be odd if( cmIsEvenU(cnt) ) { cnt--; zeroFl = true; } // at this point cnt is odd and >= 3 // calc half the window length M = (int)((cnt - 1.0)/2.0); double Msqrd = M*M; for(i=0; i xn ) VECT_OP_FUNC(Fill)(y+i,yn-i,0); return y; } VECT_OP_TYPE* VECT_OP_FUNC(FilterFilter)(struct cmFilter_str* f, cmRC_t (*func)( struct cmFilter_str* f, const VECT_OP_TYPE* x, unsigned xn, VECT_OP_TYPE* y, unsigned yn ), const cmReal_t bb[], unsigned bn, const cmReal_t aa[], unsigned an, const VECT_OP_TYPE* x, unsigned xn, VECT_OP_TYPE* y, unsigned yn ) { int i,j; int nfilt = cmMax(bn,an); int nfact = 3*(nfilt-1); const cmReal_t* a = aa; const cmReal_t* b = bb; cmReal_t* m = NULL; cmReal_t* p; unsigned zn = (nfilt-1)*(nfilt-1); unsigned mn = 2*zn; // space for mtx z0 and z1 mn += nfilt; // space for zero padded coeff vector mn += 2*nfact; // space for begin/end sequences if( nfact >= xn ) { return cmOkRC; } m = cmMemAllocZ( cmReal_t, mn ); p = m; cmReal_t* z0 = p; p += zn; cmReal_t* z1 = p; p += zn; cmReal_t* s0 = p; p += nfact; cmReal_t* s1 = p; p += nfact; // zero pad the shorter coeff vect if( bn < nfilt ) { cmVOR_Copy(p,bn,bb); b = p; p += nfilt; } else if( an < nfilt ) { cmVOR_Copy(p,an,aa); a = p; p += nfilt; } // z0=eye(nfilt-1) cmVOR_Identity(z0,nfilt-1,nfilt-1); // z1=[eye(nfilt-1,nfilt-2); zeros(1,nfilt-1)]; cmVOR_Identity(z1,nfilt-1,nfilt-2); // z0(:,1) -= a(:) for(i=0; i maxHz ) maskMtx[mi] = 0; else { if( h <= ctrHz ) maskMtx[mi] = a * (h - minHz)/(ctrHz-minHz); else maskMtx[mi] = a * (maxHz - h)/(maxHz-ctrHz); sum += maskMtx[mi]; } } } if( cmIsFlag(flags,kNormalizeMelFl) ) VECT_OP_FUNC(DivVS)( maskMtx, (filterCnt*binCnt), sum ); return maskMtx; } unsigned VECT_OP_FUNC(BarkMap)(unsigned* binIdxV, unsigned* cntV, unsigned bandCnt, unsigned binCnt, double srate ) { if( bandCnt == 0 ) return 0; //zwicker & fastl: psychoacoustics 1999, page 159 double bandUprHz[] = { 100, 200, 300, 400, 510, 630, 770, 920, 1080, 1270, 1480, 1720, 2000, 2320, 2700, 3150, 3700, 4400, 5300, 6400, 7700, 9500, 12000, 15500 }; unsigned hn = sizeof(bandUprHz)/sizeof(double); unsigned i, bi = 0; bandCnt = cmMin(hn,bandCnt); binIdxV[0] = 0; cntV[0] = 1; for(i=1; bi < bandCnt && i 0 ) VECT_OP_FUNC(DivVS)(centroidM + (ki*D), D, n ); } } cmVOU_PrintL("class cnt:",NULL,1,K,nV); cmMemPtrFree(&nV); return iterCnt; } unsigned VECT_OP_FUNC(Kmeans2)( unsigned* classIdxV, // classIdxV[scn] - data point class assignments VECT_OP_TYPE* centroidM, // centroidM[srn,K] - cluster centroids unsigned K, // count of clusters const VECT_OP_TYPE* (*srcFunc)(void* userPtr, unsigned frmIdx ), unsigned srn, // dimensionality of each data point unsigned scn, // count of data points void* userSrcPtr, // callback data for srcFunc VECT_OP_TYPE (*distFunc)( void* userPtr, const VECT_OP_TYPE* s0V, const VECT_OP_TYPE* s1V, unsigned sn ), void* distUserPtr, int maxIterCnt, int deltaStopCnt ) { unsigned D = srn; // data dimensionality unsigned N = scn; // count of data points to cluster unsigned iterCnt = 0; unsigned ki; unsigned i = 0; const VECT_OP_TYPE* sp; assert(K=maxIterCnt ) break; // track the number of interations required to converge ++iterCnt; fprintf(stderr,"%i:%i (", iterCnt,changeCnt ); for(i=0; i 0 ) VECT_OP_FUNC(DivVS)(centroidM + (ki*D), D, n ); } } cmMemPtrFree(&nV); return iterCnt; } /// stateV[timeN] /// a[stateN,stateN], /// b[stateN,timeN] /// phi[stateN]. void VECT_OP_FUNC(DiscreteViterbi)(unsigned* stateV, unsigned tN, unsigned sN, const VECT_OP_TYPE* phi, const VECT_OP_TYPE* a, const VECT_OP_TYPE* b ) { unsigned* psiM = cmMemAlloc( unsigned, sN*tN ); // psi[sN,tN] VECT_OP_TYPE* dV = cmMemAlloc( VECT_OP_TYPE, 2*sN ); VECT_OP_TYPE* d0V = dV; VECT_OP_TYPE* d1V = dV + sN; int t,i,j; // calc the prob of starting in each state given the observations VECT_OP_FUNC(MultVVV)( d0V, sN, phi, b ); VECT_OP_FUNC(NormalizeProbability)( d0V, sN ); // scale to prevent underflow // for each time step for(t=1; t mv ) { mv = v; mi = i; } } // scale the prob of the most likely state by the prob of the obs given that state d1V[j] = mv * b[ (t*sN) + j ]; // store the most likely previous state given that the current state is j // (this is the key to understanding the backtracking step below) psiM[ (t*sN) + j ] = mi; } VECT_OP_FUNC(NormalizeProbability)( d1V, sN ); // scale to prevent underflow // swap d0V and d1V VECT_OP_TYPE* tmp = d0V; d0V = d1V; d1V = tmp; } // store the most likely ending state stateV[tN-1] = VECT_OP_FUNC(MaxIndex)( d0V, sN, 1 ); // given the most likely next step select the most likely previous step for(t=tN-2; t>=0; --t) stateV[t] = psiM[ ((t+1)*sN) + stateV[t+1] ]; cmMemPtrFree( &psiM ); cmMemPtrFree( &dV ); } VECT_OP_TYPE* VECT_OP_FUNC(CircleCoords)( VECT_OP_TYPE* dbp, unsigned dn, VECT_OP_TYPE x, VECT_OP_TYPE y, VECT_OP_TYPE varX, VECT_OP_TYPE varY ) { unsigned i; for(i=0; i *t1 ) return false; // update distance on line to point of intersection if( r > *t0 ) *t0 = r; } else // if travelling left/down { // travelling away from x1,y1 if( r < *t0 ) return false; // update distance on line to point of intersection if( r < *t1 ) *t1 = r; } } return true; } /// (Uses the Laing-Barsky clipping algorithm) /// From: http://www.skytopia.com/project/articles/compsci/clipping.html bool VECT_OP_FUNC(ClipLine)( VECT_OP_TYPE* x0, VECT_OP_TYPE* y0, VECT_OP_TYPE* x1, VECT_OP_TYPE* y1, VECT_OP_TYPE xMin, VECT_OP_TYPE yMin, VECT_OP_TYPE xMax, VECT_OP_TYPE yMax ) { VECT_OP_TYPE t0; VECT_OP_TYPE t1; if( VECT_OP_FUNC(ClipLine2)(*x0,*y0,*x1,*y1,xMin,yMin,xMax,yMax,&t0,&t1) ) { VECT_OP_TYPE dx = *x1 - *x0; VECT_OP_TYPE dy = *y1 - *y0; *x0 = *x0 + t0*dx; *x1 = *x0 + t1*dx; *y0 = *y0 + t0*dy; *y1 = *y0 + t1*dy; return true; } return false; } bool VECT_OP_FUNC(IsLineInRect)( VECT_OP_TYPE x0, VECT_OP_TYPE y0, VECT_OP_TYPE x1, VECT_OP_TYPE y1, VECT_OP_TYPE xMin, VECT_OP_TYPE yMin, VECT_OP_TYPE xMax, VECT_OP_TYPE yMax ) { VECT_OP_TYPE t0; VECT_OP_TYPE t1; return VECT_OP_FUNC(ClipLine2)(x0,y0,x1,y1,xMin,yMin,xMax,yMax,&t0,&t1); } VECT_OP_TYPE VECT_OP_FUNC(PtToLineDistance)( VECT_OP_TYPE x0, VECT_OP_TYPE y0, VECT_OP_TYPE x1, VECT_OP_TYPE y1, VECT_OP_TYPE px, VECT_OP_TYPE py) { // from:http://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line double normalLength = sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0)); if( normalLength <= 0 ) return 0; return (VECT_OP_TYPE)fabs((px - x0) * (y1 - y0) - (py - y0) * (x1 - x0)) / normalLength; } VECT_OP_TYPE VECT_OP_FUNC(ComplexDetect)(const VECT_OP_TYPE* mag0V, const VECT_OP_TYPE* mag1V, const VECT_OP_TYPE* phs0V, const VECT_OP_TYPE* phs1V, const VECT_OP_TYPE* phs2V, unsigned binCnt ) { double sum = 0; const VECT_OP_TYPE* ep = mag0V + binCnt; unsigned i = 0; for(; mag0V < ep; ++i ) { // calc phase deviation from expected double dev_rads = *phs0V++ - (2 * *phs1V++) + *phs2V++; // map deviation into range: -pi to pi //double dev_rads1 = mod(dev_rads0 + M_PI, -2*M_PI ) + M_PI; while( dev_rads > M_PI) dev_rads -= 2*M_PI; while( dev_rads < -M_PI) dev_rads += 2*M_PI; // convert into rect coord's double m1r = *mag1V++; double m0r = *mag0V * cos(dev_rads); double m0i = *mag0V++ * sin(dev_rads); // calc the combined amplitude and phase deviation // sum += hypot( m1 - (m0 * e^(-1*dev_rads))); sum += hypot( m1r-m0r, -m0i ); } return (VECT_OP_TYPE)sum; } VECT_OP_TYPE* VECT_OP_FUNC(DctMatrix)( VECT_OP_TYPE* dp, unsigned coeffCnt, unsigned filtCnt ) { VECT_OP_TYPE* dbp = dp; double c0 = 1.0/sqrt(filtCnt/2); // row 1-coeffCnt factor double c1 = c0 * sqrt(2)/2; // row 0 factor unsigned i,j; // for each column for(i=0; i *s2p) && (*s1p >= threshold) ) { *dbp++ = s1p - sbp; s0p = s2p++; s1p = s2p++; ++pkCnt; } else { s0p = s1p; s1p = s2p++; } } return pkCnt; } unsigned VECT_OP_FUNC(BinIndex)( const VECT_OP_TYPE* sbp, unsigned sn, VECT_OP_TYPE v ) { const VECT_OP_TYPE* sep = sbp + sn; const VECT_OP_TYPE* bp = sbp; sep--; for(; sbp < sep; ++sbp ) if( *sbp <= v && v < *(sbp+1) ) return sbp - bp; return cmInvalidIdx; } void VECT_OP_FUNC(Interp1)(VECT_OP_TYPE* y1, const VECT_OP_TYPE* x1, unsigned xy1N, const VECT_OP_TYPE* x0, const VECT_OP_TYPE* y0, unsigned xy0N ) { unsigned i,j; // for each output value for(i=0,j=0; i