Esempio n. 1
0
//{{CGEN_FCCF
INT16 CFFTproc::OnOrderChanged()
{
    m_nLen=(INT16)dlm_pow(2,m_nOrder);
    m_nOutDim = m_nLen/2;

	return O_K;
}
Esempio n. 2
0
/**
 * 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 &le; <code>k</code> &lt;
 *          <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                              */
}
Esempio n. 3
0
/**
 * <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;
}
Esempio n. 4
0
/**
 * <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&lt;nW2</code></td><td>Less than <sup>1)</sup>               </td></tr>
 *   <tr><td><code>OP_GREATER</code></td><td><code>nW1&gt;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.;
  }
}