//{{CGEN_FCCF INT16 CFFTproc::OnOrderChanged() { m_nLen=(INT16)dlm_pow(2,m_nOrder); m_nOutDim = m_nLen/2; return O_K; }
/** * Updates the statistics with one vector. There are no checks performed! * * @param _this * Pointer to this CStatistics instance * @param lpX * Pointer to a buffer containing the vector to update the statistics * with (is expected to contain <i>N</i> = <code>{@link dat}.dim</code> * double values) * @param c * Index of class this vector belongs to (0 ≤ <code>k</code> < * <i>C</i> = <code>{@link dat}.nblock</code>) */ INT16 CGEN_PROTECTED CStatistics_UpdateVector ( CStatistics* _this, FLOAT64* lpX, INT32 c, FLOAT64 w ) { INT32 i = 0; /* Mixed sum index */ INT32 k = 0; /* Order loop counter (for k>2) */ INT32 n = 0; /* 1st dimension loop couner */ INT32 m = 0; /* 2nd dimension loop couner */ INT32 K = 0; /* Statistics order */ INT32 N = 0; /* Statistics dimensionality */ FLOAT64* lpSsz = NULL; /* Ptr. to class' c sample size */ FLOAT64* lpMin = NULL; /* Ptr. to class' c minimum vector */ FLOAT64* lpMax = NULL; /* Ptr. to class' c maximum vector */ FLOAT64* lpSum = NULL; /* Ptr. to class' c sum vector */ FLOAT64* lpMsm = NULL; /* Ptr. to class' c mixed sum matrix */ FLOAT64* lpKsm = NULL; /* Ptr. to class' c k-th ord.sum vec.*/ /* Validate */ /* --- DEBUG ONLY ------------------ */ DLPASSERT(_this); /* Check this pointer */ DLPASSERT(_this->m_idDat); /* Check statistics data table */ DLPASSERT((INT32)(dlp_size(lpX)/sizeof(FLOAT64)) == CStatistics_GetDim(_this)); /* Check update vector buffer */ DLPASSERT(c>=0 && c<CStatistics_GetNClasses(_this)); /* Check class index */ /* Initialize */ /* --------------------------------- */ K = CStatistics_GetOrder(_this); /* Get statistics order */ N = CStatistics_GetDim(_this); /* Get statistics dimensionality */ DLPASSERT((lpSsz = CStatistics_GetPtr(_this,c,STA_DAI_SSIZE))); /* Get ptr. to class' c sample size */ DLPASSERT((lpMin = CStatistics_GetPtr(_this,c,STA_DAI_MIN ))); /* Get ptr. to class' c min. vector */ DLPASSERT((lpMax = CStatistics_GetPtr(_this,c,STA_DAI_MAX ))); /* Get ptr. to class' c max. vector */ DLPASSERT((lpSum = CStatistics_GetPtr(_this,c,STA_DAI_SUM ))); /* Get ptr. to class' c sum vector */ DLPASSERT((lpMsm = CStatistics_GetPtr(_this,c,STA_DAI_MSUM ))); /* Get ptr. to class' c mix.sum.matr.*/ DLPASSERT((lpKsm = CStatistics_GetPtr(_this,c,STA_DAI_KSUM )) || K<=2); /* Get ptr. to class' c k-th ord.sum.*/ /* Update */ /* --------------------------------- */ (*lpSsz)+=w; /* Increment sample size */ for (n=0,i=0; n<N; n++) /* Loop over dimensions */ { /* >> */ if (lpMin[n] > lpX[n]) lpMin[n] = lpX[n]; /* Track minimum */ if (lpMax[n] < lpX[n]) lpMax[n] = lpX[n]; /* Track maximum */ lpSum[n] += lpX[n]*w; /* Update sum */ for (m=0; m<N; m++,i++) lpMsm[i] += lpX[n]*lpX[m]*w; /* Update mixed sum */ for (k=3; k<=K; k++) lpKsm[(k-3)*N+n] += dlm_pow(lpX[n],k)*w; /* Update k-th order sums */ } /* << */ return O_K; /* Done */ }
/** * <p>Calculates roots by tracking from known roots using homotopy method by * Alexander, Stonick, 1993, ICASSP - Fast Adaptive Polynomial Root Tracking * Using A Homotopy Continuation Method.</p> * * @param poly1 * Polynomial of predecessor * @param rtr1 * Real part of roots of predecessor. * @param rti1 * Imaginary part of roots of predecessor. * @param poly2 * Polynomial of successor where the roots are calculated from. * @param rtr2 * Real part of roots of successor to be calculated. * @param rti2 * Imaginary part of roots of successor to be calculated. * @param m * Number of roots, i.e. size of <CODE>rtr[12]</CODE> and <CODE>rti[12]</CODE>. * @param n_step * Number of interim points on the path from old to new roots * @param n_iter * Maximum number of iterations of newtons method per interim point * @param eps * Maximum error used for breaking condition at newtons method * @return <code>O_K</code> if successful, a (negative) error code otherwise */ INT16 dlm_roots_track_homotopy(FLOAT64 poly1[], FLOAT64 rtr1[], FLOAT64 rti1[], FLOAT64 poly2[], FLOAT64 rtr2[], FLOAT64 rti2[], INT16 m, INT16 n_step, INT16 n_iter, FLOAT64 eps) { INT16 i_step = 0; INT16 i_iter = 0; INT16 i = 0; INT16 j = 0; FLOAT64 pos = 0.0; FLOAT64 F1[2] = { 0.0, 0.0 }; FLOAT64 F2[2] = { 0.0, 0.0 }; FLOAT64 H[2] = { 0.0, 0.0 }; FLOAT64 dH[2] = { 0.0, 0.0 }; FLOAT64 delta[2] = { 0.0, 0.0 }; FLOAT64* dP1 = NULL; FLOAT64* dP2 = NULL; FLOAT64 tmp = 0.0; FLOAT64* trackLen = NULL; FLOAT64 alpha = 0.3; if (!poly1 || !poly2 || !rtr1 || !rti1 || !rtr2 || !rti2) return NOT_EXEC; dP1 = (FLOAT64*) dlp_calloc(3*m, sizeof(FLOAT64)); dP2 = dP1 + m; trackLen = dP2 + m; for (i = 0; i < m; i++) { rtr2[i] = sqrt(rtr1[i] * rtr1[i] + rti1[i] * rti1[i]); rti2[i] = atan2(rti1[i], rtr1[i]); dP1[i] = poly1[i] * (FLOAT64) (m - i); dP2[i] = poly2[i] * (FLOAT64) (m - i); } for (i_step = 1; i_step <= n_step; i_step++) { pos = (FLOAT64) i_step / (FLOAT64) n_step; for (i = 0; i < m; i++) { for (j = m, F1[0] = 0.0, F1[1] = 0.0, F2[0] = 0.0, F2[1] = 0.0; j >= 0; j--) { tmp = dlm_pow(rtr2[i], j); F1[0] += poly1[m - j] * tmp * cos(rti2[i] * (FLOAT64) j); F1[1] += poly1[m - j] * tmp * sin(rti2[i] * (FLOAT64) j); F2[0] += poly2[m - j] * tmp * cos(rti2[i] * (FLOAT64) j); F2[1] += poly2[m - j] * tmp * sin(rti2[i] * (FLOAT64) j); } H[0] = (1.0 - pos) * F1[0] + pos * F2[0]; H[1] = (1.0 - pos) * F1[1] + pos * F2[1]; tmp = H[0]; H[0] = sqrt(H[0] * H[0] + H[1] * H[1]); H[1] = atan2(H[1], tmp); i_iter = 0; while ((H[0] > eps) && (i_iter < n_iter)) { for (j = m, F1[0] = 0.0, F1[1] = 0.0, F2[0] = 0.0, F2[1] = 0.0; j > 0; j--) { tmp = dlm_pow(rtr2[i], j - 1); F1[0] += dP1[m - j] * tmp * cos(rti2[i] * (FLOAT64) (j - 1)); F1[1] += dP1[m - j] * tmp * sin(rti2[i] * (FLOAT64) (j - 1)); F2[0] += dP2[m - j] * tmp * cos(rti2[i] * (FLOAT64) (j - 1)); F2[1] += dP2[m - j] * tmp * sin(rti2[i] * (FLOAT64) (j - 1)); } dH[0] = (1.0 - pos) * F1[0] + pos * F2[0]; dH[1] = (1.0 - pos) * F1[1] + pos * F2[1]; tmp = dH[0]; dH[0] = sqrt(dH[0] * dH[0] + dH[1] * dH[1]); dH[1] = atan2(dH[1], tmp); delta[0] = H[0] / dH[0]; delta[1] = H[1] - dH[1]; trackLen[i] += delta[0]; tmp = rtr2[i]; rtr2[i] = rtr2[i] * cos(rti2[i]); rti2[i] = tmp * sin(rti2[i]); rtr2[i] -= alpha * delta[0] * cos(delta[1]); rti2[i] -= alpha * delta[0] * sin(delta[1]); tmp = rtr2[i]; rtr2[i] = sqrt(rtr2[i] * rtr2[i] + rti2[i] * rti2[i]); rti2[i] = atan2(rti2[i], tmp); for (j = m, F1[0] = 0.0, F1[1] = 0.0, F2[0] = 0.0, F2[1] = 0.0; j >= 0; j--) { tmp = dlm_pow(rtr2[i], j); F1[0] += poly1[m - j] * tmp * cos(rti2[i] * (FLOAT64) j); F1[1] += poly1[m - j] * tmp * sin(rti2[i] * (FLOAT64) j); F2[0] += poly2[m - j] * tmp * cos(rti2[i] * (FLOAT64) j); F2[1] += poly2[m - j] * tmp * sin(rti2[i] * (FLOAT64) j); } H[0] = (1.0 - pos) * F1[0] + pos * F2[0]; H[1] = (1.0 - pos) * F1[1] + pos * F2[1]; tmp = H[0]; H[0] = sqrt(H[0] * H[0] + H[1] * H[1]); H[1] = atan2(H[1], tmp); i_iter++; } if (i_iter == n_iter) { dlp_free(dP1); return NOT_EXEC; } } } for (i = 0; i < m; i++) { tmp = rtr2[i]; rtr2[i] = rtr2[i] * cos(rti2[i]); rti2[i] = tmp * sin(rti2[i]); } for (tmp = trackLen[0], i = 1; i < m; i++) tmp = MAX(tmp,trackLen[i]); dlp_free(dP1); if ((tmp * alpha) > 1.0) { return NOT_EXEC; } return O_K; }
/** * <p>Performs an arithmetic operation <code>OP(nW1,nW2)</code> depending on the * specified weight semiring type.</p> * * <p>The following operations are supported (parameter <code><b>nOpc</b></code>):</p> * <div class="indent"> * <table> * <tr><th><code>nOpc </code></th><th colspan="2">Description </th></tr> * <tr><td><code>OP_ADD </code></td><td><code>nW1(+)nW2 </code></td><td>Addition </td></tr> * <tr><td><code>OP_MULT </code></td><td><code>nW1(*)nW2 </code></td><td>Multiplication </td></tr> * <tr><td><code>OP_DIV </code></td><td><code>nW1(/)nW2 </code></td><td>Division (multiplicative residual) </td></tr> * <tr><td><code>OP_EQUAL </code></td><td><code>nW1==nW2 </code></td><td>Floating point comparison<sup>1)</sup></td></tr> * <tr><td><code>OP_LESS </code></td><td><code>nW1<nW2</code></td><td>Less than <sup>1)</sup> </td></tr> * <tr><td><code>OP_GREATER</code></td><td><code>nW1>nW2</code></td><td>Greater than<sup>1)</sup> </td></tr> * </table> * <p>1) Result is 1.0 if condition is true, 0.0 otherwise</p> * </div> * * <h3 style="color:red">Important Note:</h3> * <p>The method evaluates the field * <code>_this->{@link wsr m_nWsr}</code> to determine the semiring type. This * field is <em>not</em> maintained automatically, meaning you must ensure * <code>_this->{@link wsr m_nWsr}</code> to specify the correct semiring type * prior to calling <code>CFst_Wsr_Op</code>! You can determine the current * semiring type by calling {@link Wsr_GetType CFst_Wsr_GetType}.</p> * * @param _this Pointer to automaton instance * @param nW1 Operand 1 * @param nW2 Operand 2 * @param nOpc Operation code (see table above) * @return The result of the operation (<em>no</em> value is reserved for reporting errors!). * @see Wsr_GetType CFst_Wsr_GetType * @see Wsr_NeAdd CFst_Wsr_NeAdd * @see Wsr_NeMult CFst_Wsr_NeMult */ FST_WTYPE CGEN_PROTECTED CFst_Wsr_Op(CFst* _this, FST_WTYPE nW1, FST_WTYPE nW2, INT16 nOpc) { /* Validation */ CHECK_THIS_RV(0.); /* In case the user forgot: determine current semiring type if not yet set */ if (_this->m_nWsr<=0) _this->m_nWsr = CFst_Wsr_GetType(_this,NULL); /* Operations */ switch (nOpc) { /* Addition */ case OP_ADD: switch (_this->m_nWsr) { case FST_WSR_PROB: return nW1+nW2; case FST_WSR_LOG : return dlp_scalop(nW1,nW2,OP_LSADD); case FST_WSR_TROP: return nW1<nW2?nW1:nW2; case 0 : return 0.; /* Not weighted; just do nothing */ default : DLPASSERT(FMSG("Invalid weight semiring type")); } return 0.; /* Multiplication */ case OP_MULT: switch (_this->m_nWsr) { case FST_WSR_PROB: return nW1*nW2; case FST_WSR_LOG : return nW1+nW2; case FST_WSR_TROP: return nW1+nW2; case 0 : return 0.; /* Not weighted; just do nothing */ default : DLPASSERT(FMSG("Invalid weight semiring type")); } return 0.; /* Power */ case OP_POW: switch (_this->m_nWsr) { case FST_WSR_PROB: return dlm_pow(nW1,nW2); case FST_WSR_LOG : return nW1*nW2; case FST_WSR_TROP: return nW1*nW2; case 0 : return 0.; /* Not weighted; just do nothing */ default : DLPASSERT(FMSG("Invalid weight semiring type")); } return 0.; /* Division (multiplicative residual) */ case OP_DIV: switch (_this->m_nWsr) { case FST_WSR_PROB: return nW1/nW2; case FST_WSR_LOG : return nW1-nW2; case FST_WSR_TROP: return nW1-nW2; case 0 : return 0.; /* Not weighted; just do nothing */ default : DLPASSERT(FMSG("Invalid weight semiring type")); } return 0.; /* Floating point comparison */ case OP_EQUAL: if (fabs(nW1)<_this->m_nFtol) return (fabs(nW2)<_this->m_nFtol); else if (fabs(nW2)<_this->m_nFtol) return (fabs(nW1)<_this->m_nFtol); else return (fabs((nW1-nW2)/nW1)<_this->m_nFtol); /* Less than */ case OP_LESS: switch (_this->m_nWsr) { case FST_WSR_LOG : return (nW1>nW2); case FST_WSR_TROP: return (nW1>nW2); case FST_WSR_PROB: return (nW1<nW2); case 0 : return (nW1<nW2); default : DLPASSERT(FMSG("Invalid weight semiring type")); } return 0.; /* Greater than */ case OP_GREATER: switch (_this->m_nWsr) { case FST_WSR_LOG : return (nW1<nW2); case FST_WSR_TROP: return (nW1<nW2); case FST_WSR_PROB: return (nW1>nW2); case 0 : return (nW1>nW2); default : DLPASSERT(FMSG("Invalid weight semiring type")); } return 0.; /* Invalid opcode */ default: DLPASSERT(FMSG("Invalid weight semiring operation")); return 0.; } }