⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hmath.c

📁 该压缩包为最新版htk的源代码,htk是现在比较流行的语音处理软件,请有兴趣的朋友下载使用
💻 C
📖 第 1 页 / 共 3 页
字号:
}/* EXPORT->CovInvert: puts inverse of c in invc, returns log(Det(c)) *//*          Note that c must be positive definite */LogFloat CovInvert(TriMat c, Matrix invc){   DMatrix l;     /* Lower Tri Choleski Matrix */   DVector x,y;   /* for f/b substitution */   LogFloat ldet = 0.0;   int i,j,n;   Boolean isTri;      n = TriMatSize(c); isTri = IsTriMat(invc);   l = CreateDMatrix(&gstack,n,n);   x = CreateDVector(&gstack,n);   y = CreateDVector(&gstack,n);   if (Choleski(c,l)){      for (j=1; j<=n; j++){         MSolve(l,j,x,y);         for (i=isTri?j:1; i<=n; i++)            invc[i][j] = x[i];         ldet += log(l[j][j]);      }   } else      HError(5220,"CovInvert: [%f ...] not invertible",c[1][1]);   FreeDMatrix(&gstack,l);    /* cut back stack to entry state */   return 2.0*ldet;}/* EXPORT->CovDet: Returns log(Det(c)), c must be positive definite */LogFloat CovDet(TriMat c){   DMatrix l;  /* Lower Tri Choleski Matrix */   LogFloat ldet = 0.0;   int j,n;      n = TriMatSize(c);   l = CreateDMatrix(&gstack,n,n);   if (Choleski(c,l)){      for (j=1; j<=n; j++)         ldet += log(l[j][j]);   } else      HError(5220,"CovDet: [%f ...] not invertible",c[1][1]);   FreeDMatrix(&gstack,l);   return 2.0*ldet;}/* Quadratic prod of a full square matrix C and an arbitry full matrix transform A */void LinTranQuaProd(Matrix Prod, Matrix A, Matrix C){   int i,j,k;   float tempElem;   Matrix tempMatrix_A_mult_C;      if (NumRows(C) != NumCols(C)){      HError(999,"HMath: LinTranQuaProd: Matrix C is not square!\n");   }   else {      tempMatrix_A_mult_C = CreateMatrix(&gstack,NumRows(A),NumCols(C));      ZeroMatrix(tempMatrix_A_mult_C);            for (i=1;i<=NumRows(tempMatrix_A_mult_C);i++){         for (j=1;j<=NumCols(tempMatrix_A_mult_C);j++){            tempElem = 0.0;            for (k=1;k<=NumCols(A);k++){               tempElem += A[i][k]*C[j][k];            }            tempMatrix_A_mult_C[i][j] = tempElem;         }      }            for (i=1;i<=NumRows(Prod);i++){         for (j=1;j<=i;j++){            tempElem = 0.0;            for (k=1;k<=NumCols(tempMatrix_A_mult_C);k++){               tempElem += tempMatrix_A_mult_C[i][k]*A[j][k];            }            Prod[i][j] = tempElem;         }      }            for (i=1;i<=NumRows(Prod);i++){         for (j=1;j>i;j++){            Prod[i][j] = Prod[j][i];         }      }            FreeMatrix(&gstack,tempMatrix_A_mult_C);   }}/* ------------- Singular Value Decomposition --------------- *//************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** **                          Meschach Library **  ** This Meschach Library is provided "as is" without any express  ** or implied warranty of any kind with respect to this software.  ** In particular the authors shall not be liable for any direct,  ** indirect, special, incidental or consequential damages arising  ** in any way from use of the software.** ** Everyone is granted permission to copy, modify and redistribute this** Meschach Library, provided:**  1.  All copies contain this copyright notice.**  2.  All modified copies shall carry a notice stating who**      made the last modification and the date of such modification.**  3.  No charge is made for this software or works derived from it.  **      This clause shall not be construed as constraining other software**      distributed on the same medium as this software, nor is a**      distribution fee considered a charge.****  Modifications made to conform with HTK formats by **  Daniel Kershaw, Entropic Ltd, Cambridge, England.*****************************************************************************/#define MACHEPS 2.22045e-16#define FZERO 1.0e-6#define sgn(x)  ((x) >= 0 ? 1 : -1)#define minab(a,b) ((a) > (b) ? (b) : (a))#define MAX_STACK       100/* Givens -- returns c,s parameters for Givens rotation to   eliminate y in the vector [ x y ]' */static void Givens(double x, double y, double *c, double *s){   double norm;     norm = sqrt(x*x+y*y);   if ( norm == 0.0 ) {      *c = 1.0;      *s = 0.0;          }       /* identity */   else {      *c = x/norm;      *s = y/norm;   }}/* RotRows -- premultiply mat by givens rotation described by c,s */static void RotRows(DMatrix M, int i, int k,                     double c, double s){   int   j, n;   double temp;     n = NumDRows(M);     if (i > n || k > n)      HError(1, "RotRows: Index tooo big i=%d k=%d\n", i, k);       for ( j=1; j<=n; j++ ) {      temp = c*M[i][j] + s*M[k][j];      M[k][j] = -s*M[i][j] + c*M[k][j];      M[i][j] = temp;   }  }/* FixSVD -- fix minor details about SVD make singular values non-negative   -- sort singular values in decreasing order */static void FixSVD(DVector d, DMatrix U, DMatrix V){     int  i, j, n;     n = DVectorSize(d);   /* make singular values non-negative */   for (i = 1; i <= n; i++) {      if ( d[i] < 0.0 ) {         d[i] = - d[i];         for ( j = 1; j <= NumDRows(U); j++ )            U[i][j] = - U[i][j];      }   }   return;#if 0 /* #### ge: what is this code after return supposed to do here? */   {      int  k, l, r, stack[MAX_STACK], sp;      double tmp, v;   /* sort singular values */   sp = -1;   l = 1;          r = n;   for ( ; ; ) {      while ( r >= l ) {         /* i = partition(d->ve,l,r) */         v = d[r];         i = l-1;                    j = r;         for ( ; ; ) {            /* inequalities are "backwards" for **decreasing** order */            while ( d[++i] > v );            while ( d[--j] < v );            if ( i >= j )               break;            /* swap entries in d->ve */            tmp = d[i];               d[i] = d[j];            d[j] = tmp;            /* swap rows of U & V as well */            for ( k = 1; k <= DVectorSize(U[1]); k++ ) {               tmp = U[i][k];               U[i][k] = U[j][k];               U[j][k] = tmp;            }            for ( k = 1; k <= DVectorSize(V[1]); k++ ) {               tmp = V[i][k];               V[i][k] = V[j][k];               V[j][k] = tmp;            }         }         tmp = d[i];         d[i] = d[r];         d[r] = tmp;         for ( k = 1; k <= DVectorSize(U[1]); k++ ) {            tmp = U[i][k];            U[i][k] = U[r][k];            U[r][k] = tmp;         }         for ( k = 1; k <= DVectorSize(V[1]); k++ ) {            tmp = V[i][k];            V[i][k] = V[r][k];            V[r][k] = tmp;         }         /* end i = partition(...) */         if ( i - l > r - i ) {            stack[++sp] = l;                stack[++sp] = i-1;            l = i+1;             }         else {            stack[++sp] = i+1;            stack[++sp] = r;            r = i-1;             }      }      if ( sp < 0 )         break;      r = stack[sp--];      l = stack[sp--];   }   }#endif}/* BiSvd -- svd of a bidiagonal m x n matrix represented by d (diagonal) and   f (super-diagonals) */static void BiSVD(DVector d, DVector f, DMatrix U, DMatrix V){   int i, j, n;   int i_min, i_max, split;   double c, s, shift, size, z;   double d_tmp, diff, t11, t12, t22;   if ( ! d || ! f )      HError(1,"BiSVD: Vectors are null!");   if ( DVectorSize(d) != DVectorSize(f) + 1 )      HError(1, "BiSVD: Error with the vector sizes!");    n = DVectorSize(d);     if ( ( U && DVectorSize(U[1]) < n ) || ( V && NumDRows(V) < n ) )      HError(1, "BiSVD: Error Matrix sizes!");   if ( ( U && NumDRows(U) != DVectorSize(U[1])) ||         ( V && NumDRows(V) != DVectorSize(V[1])) )      HError(1, "BiSVD: One of the matrices must be square");       if ( n == 1 )      return;       s = 0.0;   for ( i = 1; i <= n; i++)      s += d[i]*d[i];   size = sqrt(s);   s = 0.0;   for ( i = 1; i < n; i++)      s += f[i]*f[i];   size += sqrt(s);   s = 0.0;     i_min = 1;   while ( i_min <= n ) {   /* outer while loop */      /* find i_max to suit;         submatrix i_min..i_max should be irreducible */      i_max = n;      for ( i = i_min; i < n; i++ )         if ( d[i] == 0.0 || f[i] == 0.0 ) {            i_max = i;            if ( f[i] != 0.0 ) {               /* have to ``chase'' f[i] element out of matrix */               z = f[i];               f[i] = 0.0;               for ( j = i; j < n && z != 0.0; j++ ) {                  Givens(d[j+1],z, &c, &s);                  s = -s;                  d[j+1] =  c*d[j+1] - s*z;                  if ( j+1 < n ) {                     z      = s*f[j+1];                     f[j+1] = c*f[j+1];                  }                  RotRows(U,i,j+1,c,s);               }            }            break;         }            if ( i_max <= i_min ) {         i_min = i_max + 1;         continue;      }      split = FALSE;      while ( ! split ) {         /* compute shift */         t11 = d[i_max-1]*d[i_max-1] +            (i_max > i_min+1 ? f[i_max-2]*f[i_max-2] : 0.0);         t12 = d[i_max-1]*f[i_max-1];         t22 = d[i_max]*d[i_max] + f[i_max-1]*f[i_max-1];         /* use e-val of [[t11,t12],[t12,t22]] matrix            closest to t22 */         diff = (t11-t22)/2;         shift = t22 - t12*t12/(diff +                                sgn(diff)*sqrt(diff*diff+t12*t12));               /* initial Givens' rotation */         Givens(d[i_min]*d[i_min]-shift,                d[i_min]*f[i_min], &c, &s);               /* do initial Givens' rotations */         d_tmp      = c*d[i_min] + s*f[i_min];         f[i_min]   = c*f[i_min] - s*d[i_min];         d[i_min]   = d_tmp;         z          = s*d[i_min+1];         d[i_min+1] = c*d[i_min+1];         RotRows(V,i_min,i_min+1,c,s);         /* 2nd Givens' rotation */         Givens(d[i_min],z, &c, &s);         d[i_min]   = c*d[i_min] + s*z;         d_tmp      = c*d[i_min+1] - s*f[i_min];         f[i_min]   = s*d[i_min+1] + c*f[i_min];         d[i_min+1] = d_tmp;         if ( i_min+1 < i_max ) {            z          = s*f[i_min+1];            f[i_min+1] = c*f[i_min+1];         }         RotRows(U,i_min,i_min+1,c,s);               for ( i = i_min+1; i < i_max; i++ ) {            /* get Givens' rotation for zeroing z */            Givens(f[i-1],z, &c, &s);            f[i-1] = c*f[i-1] + s*z;            d_tmp  = c*d[i] + s*f[i];            f[i]   = c*f[i] - s*d[i];            d[i]   = d_tmp;            z      = s*d[i+1];            d[i+1] = c*d[i+1];            RotRows(V,i,i+1,c,s);            /* get 2nd Givens' rotation */            Givens(d[i],z, &c, &s);            d[i]   = c*d[i] + s*z;            d_tmp  = c*d[i+1] - s*f[i];            f[i]   = c*f[i] + s*d[i+1];            d[i+1] = d_tmp;            if ( i+1 < i_max ) {               z      = s*f[i+1];               f[i+1] = c*f[i+1];            }            RotRows(U,i,i+1,c,s);         }         /* should matrix be split? */         for ( i = i_min; i < i_max; i++ )            if ( fabs(f[i]) <                 MACHEPS*(fabs(d[i])+fabs(d[i+1])) )               {                  split = TRUE;                  f[i] = 0.0;               }            else if ( fabs(d[i]) < MACHEPS*size )               {                  split = TRUE;                  d[i] = 0.0;               }      }   }}/* HholdVec -- calulates Householder vector to eliminate all entries after the   i0 entry of the vector vec. It is returned as out. May be in-situ */static void HholdVec(DVector tmp, int i0, int size,                     double *beta, double *newval){   int i;   double norm = 0.0;   for (i = i0; i <= size; i++) {      norm += tmp[i]*tmp[i];   }   norm = sqrt(norm);   if ( norm <= 0.0 ) {      *beta = 0.0;   }   else {      *beta = 1.0/(norm * (norm+fabs(tmp[i0])));      if ( tmp[i0] > 0.0 )         *newval = -norm;      else         *newval = norm;      tmp[i0] -= *newval;   }}/* HholdTrRows -- transform a matrix by a Householder vector by rows   starting at row i0 from column j0 -- in-situ */static void HholdTrRows(DMatrix M, int i0, int j0, DVector hh, double beta){   double ip, scale;   int i, j;   int m,n;   m = NumDRows(M);   n = DVectorSize(M[1]);   if ( M==NULL || hh==NULL )      HError(1,"HholdTrRows: matrix or vector is NULL!");   if ( DVectorSize(hh) != n )      HError(1,"HholdTrRows: hh vector size must = number of M columns");   if ( i0 > m+1 || j0 > n+1 )      HError(1,"HholdTrRows: Bounds matrix/vec size error i=%d j=%d m=%d n=%d",             i0, j0, m, n);     if ( beta != 0.0 ) {      /* for each row ... */      for ( i = i0; i <= m; i++ )         {              /* compute inner product */            /* ip = __ip__(&(M->me[i][j0]),&(hh->ve[j0]),(int)(M->n-j0));*/            ip = 0.0;            for ( j = j0; j <= n; j++ )               ip += M[i][j]*hh[j];            scale = beta*ip;            if ( scale == 0.0 )               continue;            /* __mltadd__(&(M->me[i][j0]),&(hh->ve[j0]),-scale,               (int)(M->n-j0)); */            for ( j = j0; j <= n; j++ )               M[i][j] -= scale*hh[j];         }   }}/* HholdTrCols -- transform a matrix by a Householder vector by columns   starting at row i0 from column j0 -- in-situ */static void HholdTrCols(DMatrix M, int i0, int j0,                         DVector hh, double beta, DVector w){   int i, j;   int n;   n = NumDRows(M);   if ( M==NULL || hh==NULL )      HError(1,"HholdTrCols: matrix or vector is NULL!");   if ( DVectorSize(hh) != n )      HError(1,"HholdTrCols: hh vector size must = number of M columns");   if ( i0 > n+1 || j0 > n+1 )      HError(1,"HholdTrCols: Bounds matrix/vec size error i=%d j=%d n=%d",             i0, j0, n);   ZeroDVector(w);   if ( beta != 0.0 ) {      for ( i = i0; i <= n; i++ )         if ( hh[i] != 0.0 )            for ( j = j0; j <= n; j++ )               w[j] += M[i][j]*hh[i];      for ( i = i0; i <= n; i++ )         if ( hh[i] != 0.0 )            for ( j = j0; j <= n; j++ )               M[i][j] -= w[j]*beta*hh[i];   }}/* copy a row from a matrix into  a vector */static void CopyDRow(DMatrix M, int k, DVector v) {   int i, size;   DVector w;   if (v == NULL)      HError(1, "CopyDRow: Vector is NULL");   size = DVectorSize(v);   w = M[k];   for (i = 1; i <= size; i++)      v[i] = w[i];}/* copy a column from a matrix into  a vector */static void CopyDColumn(DMatrix M, int k, DVector v) {   int i, size;   if (v == NULL)      HError(1, "CopyDColumn: Vector is NULL");   size = DVectorSize(v);   for (i = 1; i <= size; i++)      v[i] = M[i][k];}/* BiFactor -- perform preliminary factorisation for bisvd   -- updates U and/or V, which ever is not NULL */static void BiFactor(DMatrix A, DMatrix U, DMatrix V){   int n, k;   DVector tmp1, tmp2, tmp3;   double beta;   n = NumDRows(A);   tmp1 = CreateDVector(&gstack, n);   tmp2 = CreateDVector(&gstack, n);   tmp3 = CreateDVector(&gstack, n);   for ( k = 1; k <= n; k++ ) {      CopyDColumn(A,k,tmp1);      HholdVec(tmp1,k,n,&beta,&(A[k][k]));      HholdTrCols(A,k,k+1,tmp1,beta,tmp3);      if ( U )         HholdTrCols(U,k,1,tmp1,beta,tmp3);      if ( k+1 > n )         continue;      CopyDRow(A,k,tmp2);      HholdVec(tmp2,k+1,n,&beta,&(A[k][k+1]));      HholdTrRows(A,k+1,k+1,tmp2,beta);      if ( V )         HholdTrCols(V,k+1,1,tmp2,beta,tmp3);   }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -