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

📄 svdpack.cc

📁 矩阵奇异分解(svd)最新c++版本
💻 CC
📖 第 1 页 / 共 5 页
字号:
	    y[k][i] += value[j] * ztempp[k][rowind[j]];      }   return;}/************************************************************** *                                                            * * multiplication of matrix B by vector x, where B = A'A,     * * and A is nrow by ncol (nrow >> ncol) and is stored using   * * the Harwell-Boeing compressed column sparse matrix format. * * Hence, B is of order n = ncol.  y stores product vector.   * *                                                            * **************************************************************/void svdpack::opb(long nrow, long ncol, double *x, double *y){   long i, j, end;      mxvcount += 1;   mtxvcount += 1;   for (i = 0; i < ncol; i++) y[i] = ZERO;   for (i = 0; i < nrow; i++) ztemp[i] = ZERO;   for (i = 0; i < ncol; i++) {      end = pointr[i+1];      for (j = pointr[i]; j < end; j++) 	 ztemp[rowind[j]] += value[j] * (*x);       x++;   }   for (i = 0; i < ncol; i++) {      end = pointr[i+1];      for (j = pointr[i]; j < end; j++) 	 *y += value[j] * ztemp[rowind[j]];      y++;   }   return;}/*********************************************************************  * Function sorts array1 and array2 into increasing order for array1 * *********************************************************************/void svdpack::dsort2(long igap,long n,double *array1,double *array2){    double temp;    long i, j, index;    if (!igap) return;    else {	for (i = igap; i < n; i++) {	    j = i - igap;	    index = i;	    while (j >= 0 && array1[j] > array1[index]) {		temp = array1[j];		array1[j] = array1[index];		array1[index] = temp;		temp = array2[j];		array2[j] = array2[index];		array2[index] = temp;	        j -= igap;		index = j + igap;	    }	}     }    dsort2(igap/2,n,array1,array2);}/************************************************************** * multiplication of matrix B by vector x, where B = A'A,     * * and A is nrow by ncol (nrow >> ncol). Hence, B is of order * * n = ncol (y stores product vector).		              * **************************************************************/void svdpack::opb(long n, double *x, double *y, bool flag){   long i, j, end;      mxvcount += 2;   for (i = 0; i < n; i++) y[i] = 0.0;   for (i = 0; i < nrow; i++) ztemp[i] = 0.0;   for (i = 0; i < ncol; i++) {      end = pointr[i+1];      for (j = pointr[i]; j < end; j++) 	 ztemp[rowind[j]] += value[j] * (*x);       x++;   }   for (i = 0; i < ncol; i++) {      end = pointr[i+1];      for (j = pointr[i]; j < end; j++) 	 *y += value[j] * ztemp[rowind[j]];      y++;   }   return;}double svdpack::norm_1(){/* find matrix 1-norm  */    double alpha,sum;    long i,j,last;    alpha = 0.0;    for (j=0; j<ncol; ++j) {        sum = 0.0;        last= pointr[j+1];        for (i=pointr[j]; i<last ; ++i)            sum += fabs(value[i]);        alpha = dmax(alpha,sum);    }    return(alpha);}/**************************************************************  * multiplication of 2-cyclic matrix B by a vector x, where   * *							      * * B = [0  A]						      * *     [A' 0] , where A is nrow by ncol (nrow >> ncol). Hence,* * B is of order n = nrow+ncol (y stores product vector).     * **************************************************************/ void svdpack::opb(long n,double *x, double *y){   long i, j, end;   double *tmp;      mxvcount += 2;   for (i = 0; i < n; i++) y[i] = 0.0;   tmp = &x[nrow];    for (i = 0; i < ncol; i++) {      end = pointr[i+1];      for (j = pointr[i]; j < end; j++) 	 y[rowind[j]] += value[j] * (*tmp);       tmp++;    }   for (i = nrow; i < n; i++) {      end = pointr[i-nrow+1];      for (j = pointr[i-nrow]; j < end; j++) 	 y[i] += value[j] * x[rowind[j]];   }   return;}/**************************************************************  * function scales a vector by a constant.	     	      * * Based on Fortran-77 routine from Linpack by J. Dongarra    * **************************************************************/ void svdpack::datx(long n,double da,double *dx,long incx,double *dy,long incy){   long i;   if (n <= 0 || incx == 0 || incy == 0 || da == 0.0) return;   if (incx == 1 && incy == 1)       for (i=0; i < n; i++) *dy++ = da * (*dx++);   else {      if (incx < 0) dx += (-n+1) * incx;      if (incy < 0) dy += (-n+1) * incy;      for (i=0; i < n; i++) {         *dy = da * (*dx);         dx += incx;         dy += incy;      }   }   return;}/*********************************************************************** *                                                                     * *                         dgemm3()                                    * *                                                                     * * A C-translation of the level 3 BLAS routine DGEMM by Dongarra,      * * Duff, du Croz, and Hammarling (see LAPACK Users' Guide).            * * In this version, the arrays which store the matrices used in this   * * matrix-matrix multiplication are accessed as two-dimensional arrays.* *                                                                     * ***********************************************************************//***********************************************************************   Description   -----------   dgemm3() performs one of the matrix-matrix operations	      C := alpha * op(A) * op(B) + beta * C,   where op(X) = X or op(X) = X', alpha and beta are scalars, and A, B   and C are matrices, with op(A) an m by k matrix, op(B) a k by n   matrix and C an m by n matrix.   Parameters   ----------   (input)   transa   TRANSP indicates op(A) = A' is to be used in the multiplication	    NTRANSP indicates op(A) = A is to be used in the multiplication   transb   TRANSP indicates op(B) = B' is to be used in the multiplication	    NTRANSP indicates op(B) = B is to be used in the multiplication   m        on entry, m specifies the number of rows of the matrix op(A)	    and of the matrix C.  m must be at least zero.  Unchanged	    upon exit.   n        on entry, n specifies the number of columns of the matrix op(B)	    and of the matrix C.  n must be at least zero.  Unchanged	    upon exit.   k        on entry, k specifies the number of columns of the matrix op(A)	    and the number of rows of the matrix B.  k must be at least 	    zero.  Unchanged upon exit.   alpha    a scalar multiplier   a        matrix A as a 2-dimensional array.  When transa = NTRANSP, the            leading m by k part of a must contain the matrix A. Otherwise,	    the leading k by m part of a must contain  the matrix A.   ira,ica  row and column indices of matrix a, where mxn part starts.   b        matrix B as a 2-dimensional array.  When transb = NTRANSP, the            leading k by n part of a must contain the matrix B. Otherwise,	    the leading n by k part of a must contain  the matrix B.   irb,icb  row and column indices of matrix b, where kxn starts.   beta     a scalar multiplier.  When beta is supplied as zero then C	    need not be set on input.   c        matrix C as a 2-dimensional array.  On entry, the leading	    m by n part of c must contain the matrix C, except when	    beta = 0.  In that case, c need not be set on entry. 	    On exit, c is overwritten by the m by n matrix	    (alpha * op(A) * op(B) + beta * C).   irc,icc  row and column indices of matrix c, where the mxn part is stored.***********************************************************************/void svdpack::dgemm3(long transa, long transb, long m, long n, long k,             double alpha, double **a, long ira, long ica, double **b,            long irb, long icb, double beta, double **c, long irc,            long icc){   long info;   long i, j, l, nrowa, ncola, nrowb, ncolb;   double temp;   info = 0;   if      ( transa != TRANSP && transa != NTRANSP ) info = 1;   else if ( transb != TRANSP && transb != NTRANSP ) info = 2;   else if ( m < 0 ) 				     info = 3;   else if ( n < 0 )				     info = 4;   else if ( k < 0 )        			     info = 5;   if (info) {      fprintf(stderr, "%s %1ld %s\n",      "*** ON ENTRY TO DGEMM3, PARAMETER NUMBER",info,"HAD AN ILLEGAL VALUE");      exit(info);   }   if (transa) {      nrowa = m;      ncola = k;   }   else {       nrowa = k;      ncola = m;   }   if (transb) {      nrowb = k;      ncolb = n;   }   else {      nrowb = n;      ncolb = k;   }   if (!m || !n || ((alpha == ZERO || !k) && beta == ONE))      return;   if (alpha == ZERO) {      if (beta == ZERO)          for (j = 0; j < n; j++)            for (i = 0; i < m; i++) c[icc+j][irc+i] = ZERO;      else          for (j = 0; j < n; j++)             for (i = 0; i < m; i++) c[icc+j][irc+i] *= beta;      return;   }   if (!transb) {       switch(transa) {	 /* form C := alpha * A * B + beta * C */	 case NTRANSP: for(j = 0; j < n; j++) {                          for(i=0; i<m; i++) c[icc+j][irc+i]=0.0;                          for(l=0; l<k; l++)                              if(b[icb+j][irb+l]!=0.0) {                               temp = alpha*b[icb+j][irb+l];                               for(i=0; i<m; i++)                                 c[icc+j][irc+i] += temp*a[ica+l][ira+i];      		  	      }                        }			break;	 /* form C := alpha * A' * B + beta * C */	 case TRANSP:   for(j = 0; j < n; j++) {                           for(i=0; i<m; i++) {                              temp = 0.0;      		  	      for(l = 0; l< k;l++)                                  temp += a[ica+i][ira+l]*b[icb+j][irb+l];                              if(beta==0.0) c[icc+j][irc+i]=alpha*temp;                               else                        c[icc+j][irc+i] = alpha*temp + beta*c[icc+j][irc+i];      		  	   }   	    		}			break;      }   }   else {       switch(transa) {	 /* form C := alpha * A * B' + beta * C */	 case NTRANSP: for(j=0; j<n; j++) {      		  	   for(i=0; i<m; i++) c[icc+j][irc+i]=ZERO;      		  	   for(l=0; l<k; l++) {	 	     	      temp = alpha*b[l+icb][j+irb];         	     	      for(i=0; i<m; i++) 	    			 c[j+icc][i+irc] += temp*a[l+ica][i+ira];      		  	   }   	    		}			break;	 /* form C := alpha * A' * B' + beta * C */	 case TRANSP:   for(j=0; j<n; j++) {			   for (i=0; i<m; i++) {      	       		      temp = ZERO;	 		      for(l=0; l<k; l++) 				 temp += a[i+ica][l+ira]*b[l+icb][j+irb];                              if(!beta) c[j+icc][i+irc] += alpha * temp;                              else                                  c[j+icc][i+irc]= alpha*temp+                                                  beta*c[j+icc][i+irc];			   }   	    		}			break;      }   }}void svdpack::opat(double *x, double *y){  /*  multiplication of transpose (nrow by ncol sparse matrix A)    by the vector x, store in y  */  long i,j,upper;  for(i=0; i<ncol; i++)     y[i]=ZERO;  for(i=0; i<ncol; i++) {     upper = pointr[i+1];     for(j=pointr[i]; j<upper; j++)        y[i] += value[j]*x[rowind[j]];  }  return;}double svdpack::dasum(long n, double *dx, long incx){  /**************************************************************   *  Function forms the sum of the absolute values.            *   *  Uses unrolled loops for increment equal to one.           *   *  Based on Fortran-77 routine from Linpack by J.Dongarra.   **************************************************************/  double dtemp,dsum;  long   i,ix,m,mp1;  dsum = ZERO;  dtemp = ZERO;  if(n <= 0) return 0;  if(incx != 1) {  /* code for increment not equal to 1 */    ix = 0;    if(incx < 0) ix = (-n+1)*incx + 1;    for(i=0; i<n; i++) {       dtemp += fabs(dx[ix]);       ix    += incx;    }    dsum = dtemp;    return(dsum);  }    /* code for increment equal to 1 */    /* clean-up loop */  m = n % 6;  if(m) {    for(i=0; i<m; i++)       dtemp += fabs(dx[i]);  }  if(n>=6) {    for(i=m; i<n; i+=6)       dtemp += fabs(dx[i]) + fabs(dx[i+1]) + fabs(dx[i+2]) +                fabs(dx[i+3]) + fabs(dx[i+4]) + fabs(dx[i+5]);  }  dsum = dtemp;  return(dsum);}/*********************************************************************** *                                                                     * *                              tred2()                                * *                                                                     * ***********************************************************************//***********************************************************************  Description  -----------    tred2() is a translation of the algol procedure TRED2, Num. Math. 11,   181-195 (1968) by Martin, Reinsch, and Wikinson.  Handbook for Auto.  Comp., Vol. II- Linear Algebra, 212-226 (1971)  This subroutine reduces a real symmetric matrix to a symmetric  tridiagonal matrix using and accumulating orthogonal similarity  transformations.  Arguments  ---------  (input)  offset index of the leading element of the matrix to be         tridiagonalized. The matrix tridiagonalized should be          stored in a[offset:n-1, offset:n-

⌨️ 快捷键说明

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