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

📄 bls1.c

📁 求矩阵奇异分解svd算法
💻 C
📖 第 1 页 / 共 5 页
字号:
   }   /* compute alpha[0] */   alpha[0] = enorm(m, t);   for (j = 0; j < nn; j++) {      if (alpha[j] != ZERO) {	 	 /* compute Q[j] := T[j] / alpha[j] */	 ptr = uup[j];         for (i = 0; i < m; i++) {	    q[i] = t[i] / alpha[j];	    *ptr++ = q[i];	 }	 if (j == nn - 1) return(CONTINUE);	 /* compute Z[j] := A^T * Q[J] - alpha[j] * P[j] */	 opat(n, q, z);	 daxpy(n, -alpha[j], p, 1, z, 1);	 if (!j) {	    if ((znm = enorm(n, z)) <= tol) {	       ptr = &u0[iconv * m];               for (i = 0; i < m; i++) *ptr++ = q[i];	       ptr = &v0[iconv * n];               for (i = 0; i < n; i++) *ptr++ = p[i];	       sing[iconv] = alpha[0];	       res[iconv] = znm;	       iconv += 1;               *k -= 1;	       if (!*k) {		  iter -= 1;		  return(DONE);	       }            }	 }         convpj = iconv + j;	 ptr = v0;	 /* orthogonalize Z w.r.t. converged right S-vectors and 	  * previous VV's */	 for (jj = 0; jj < iconv; jj++)	    for (i = 0; i < n; i++)	       uvtmpp[jj][i] = *ptr++;	 ptr = vv;	 for (jj = iconv; jj <= convpj; jj++)	    for (i = 0; i < n; i++)	       uvtmpp[jj][i] = *ptr++;         if (convpj) {	    ptr = uvtmpp[convpj + 1];	    for (i = 0; i < n; i++) *ptr++ = z[i];	    orthg(1, convpj + 1, n, wp, uvtmpp, temp);	    ptr = uvtmpp[convpj + 1];	    for (i = 0; i < n; i++) z[i] = *ptr++;	 }	 else {	    dum = -ddot(n, uvtmp, 1, z, 1);	    daxpy(n, dum, uvtmp, 1, z, 1);	 }	 beta[j] = enorm(n,z);	 if (beta[j] != ZERO) {	    /* compute P[j+1] := Z[j] / beta[j] */	    ptr = vvp[j + 1];            for (i = 0; i < n; i++) {	       p[i] = z[i] /beta[j];	       *ptr++ = p[i];	    }	    /* compute T[j+1] := A * P[j+1] - beta[j] * Q[j] */	    opa(m, n, p, t);	    daxpy(m, -beta[j], q, 1, t, 1);	    /* orthogonalize T w.r.t. converged left S-vectors and 	     * previous UU's */            convpj = iconv + j;	    ptr = u0;	    for (jj = 0; jj < iconv; jj++)	       for (i = 0; i < m; i++)	          uvtmpp[jj][i] = *ptr++;	    ptr = uu;	    for (jj = iconv; jj <= convpj; jj++)	       for (i = 0; i < m; i++)	          uvtmpp[jj][i] = *ptr++;            if (convpj) {	       ptr = uvtmpp[convpj + 1];	       for (i = 0; i < m; i++) *ptr++ = t[i];	       orthg(1, convpj + 1, m, wp, uvtmpp, temp);	       ptr = uvtmpp[convpj + 1];	       for (i = 0; i < m; i++) t[i] = *ptr++;	    }	    else {	       dum = -ddot(m, uvtmp, 1, t, 1);	       daxpy(m, dum, uvtmp, 1, t, 1);	    }	    alpha[j + 1] = enorm(m, t);         }	 else return(CONTINUE);      }      else return(CONTINUE);   }}#include <stdio.h>#include <fcntl.h>#define  NCMAX  5200#define  NZMAX  800000#define  ZERO   0.0/*********************************************************************** *								       * *		              validate()			       * *								       * ***********************************************************************//***********************************************************************   Description   -----------   Function validates input parameters and returns error code (long)     Arguments    ---------  (input)  fp_out1   pointer to output file  nnzero    number of nonzero elements in input sparse matrix A  nrow      row dimension of A  ncol      column dimension of A  maxsubsp  maximum dimension of Krylov subspace allowed  blksize   initial block size  nums      number of singular values desired  tol       user-specified tolerance for approximate singular triplets ***********************************************************************/long validate(FILE *fp_out1, long nnzero, long nrow, long ncol,	      long maxsubsp, long blksize, long nums, double tol){   long error_index;   char *error[8];   error_index = 0;   error[1] = " ***** SORRY, YOUR MATRIX IS TOO BIG *****";   error[2] = " ***** NCOL MUST NOT BE GREATER THAN NROW *****";   error[3] = " ***** TOLERANCE IS INVALID *****";   error[4] = " ***** MAXIMUM SUBSPACE DIMENSION IS INVALID *****";   error[5] = " ***** INITIAL BLOCK SIZE MUST BE GREATER THAN 1 *****";   error[6] = " ***** NUMBER OF SINGULAR VALUES DESIRED IS INVALID *****";   error[7] = " ***** INIT BLK SIZE MUST BE LESS THAN NO. OF S-VALUES DESIRED *****";   if (ncol > NCMAX || nnzero > NZMAX)           error_index = 1;   else if (ncol > nrow)                         error_index = 2;   else if (tol < ZERO)                          error_index = 3;   else if (maxsubsp > ncol || maxsubsp <= 0)    error_index = 4;   else if (blksize <= 1 || blksize > maxsubsp)  error_index = 5;   else if (nums > maxsubsp || nums <= 0)        error_index = 6;   else if (blksize > nums)                      error_index = 7;   if (error_index) fprintf(fp_out1, "%s\n", error[error_index]);   return(error_index);}#define       ZERO    0.0extern long mxvcount;extern long *pointr, *rowind;extern double *value;/************************************************************** *                                                            * * multiplication of matrix A by vector x, where A is m by n  * * (m >> n) and is stored using the Harwell-Boeing compressed * * column sparse matrix format.  y stores product vector.     * *                                                            * **************************************************************/void opa(long m, long n, double *x, double *y){   long end,i,j;      mxvcount += 1;   for (i = 0; i < m; i++) y[i] = ZERO;   for (i = 0; i < n; i++) {      end = pointr[i+1];      for (j = pointr[i]; j < end; j++)	 y[rowind[j]] += value[j] * x[i];    }   return;}#define       ZERO    0.0extern long mtxvcount;extern long *pointr, *rowind;extern double *value;/************************************************************** *                                                            * * multiplication of an n by m matrix A' by a vector X, store * * in Y.                                                      * *                                                            * **************************************************************/void opat(long n, double *x, double *y){   long end,i,j;      mtxvcount += 1;   for (i = 0; i < n; i++) y[i] = ZERO;   for (i = 0; i < n; i++) {      end = pointr[i+1];      for (j = pointr[i]; j < end; j++)	 y[i] += value[j] * x[rowind[j]];    }   return;}double fsign(double a,double b)/**************************************************************  * returns |a| if b is positive; else fsign returns -|a|      * **************************************************************/ {   if ((a>=0.0 && b>=0.0) || (a<0.0 && b<0.0))return(a);   if  ((a<0.0 && b>=0.0) || (a>=0.0 && b<0.0))return(-a);}double dmax(double a, double b)/**************************************************************  * returns the larger of two double precision numbers         * **************************************************************/ {   if (a > b) return(a);   else return(b);}double dmin(double a, double b)/**************************************************************  * returns the smaller of two double precision numbers        * **************************************************************/ {   if (a < b) return(a);   else return(b);}long imin(long a, long b)/**************************************************************  * returns the smaller of two integers                        * **************************************************************/ {   if (a < b) return(a);   else return(b);}long imax(long a,long b)/**************************************************************  * returns the larger of two integers                         * **************************************************************/ {   if (a > b) return(a);   else return(b);}#include <math.h>#include <stdio.h>#define		TRUE	 1#define		FALSE  	 0#define		TRANSP   1#define		NTRANSP  0#define		ZERO	 0.0#define		ONE	 1.0#define		CONST    100.0void   dgemv(long, long, long, double, double **, double *, double, double *);double ddot(long, double *,long, double *, long);void   dscal(long, double, double *,long);void   daxpy(long, double, double *,long, double *, long);void   dcopy(long, double *, long, double *, long);/*********************************************************************** *                                                                     * *                        orthg()                                      * *         Gram-Schmidt orthogonalization procedure                    * *                                                                     * ***********************************************************************//***********************************************************************   Description   -----------   The p by n matrix Z stored row-wise in rows f to (f+p-1) of   array X is reorthogonalized w.r.t. the first f rows of array X.   The resulting matrix Z is then factored into the product of a   p by n orthonormal matrix (stored over matrix Z) and a p by p   upper-triangular matrix (stored in the first p rows and columns    of array B).  (Based on orthog from Rutishauser)    Parameters   ----------   (input)   p           number of consecutive vectors of array x (stored row-wise)	       to be orthogonalized   f           number of rows against which the next p rows are to be	       orthogonalized   n           column dimension of x   x           2-dimensional array whose p rows are to be orthogonalized	       against its first f rows   temp        work array   (output)   x           output matrix whose f+p rows are orthonormalized   b           p by p upper-triangular matrix   Functions called   --------------   BLAS         dgemv, ddot, dscal, daxpy, dcopy ***********************************************************************/void orthg(long p, long f, long n, double **b, double **x, double *temp){   long fp, k, km1;   long orig, small;   double t, s;   if (!p) return;   if (f == 0 && p > n) {      fprintf(stderr,"%s\n",         "*** ON ENTRY TO ORTHG, MATRIX TO BE ORTHONORMALIZED IS SINGULAR");      exit(-1);   }   fp = f + p;   for (k = f; k < fp; k++) {      km1 = k - 1;      orig = TRUE;      while(TRUE) {         t = ZERO;	 if (km1 >= 0) {	    if (km1 > 0) {	       dgemv(NTRANSP, k, n, ONE, x, x[k], ZERO, temp);	       t += ddot(k, temp, 1, temp, 1);	    }	    else {	       temp[0] = ddot(n, x[0], 1, x[k], 1);	       t += temp[0] * temp[0];	    }	    if (orig && km1 >= f)                dcopy(k - f, &temp[f], 1, &b[k - f][0], 1);             if (km1 > 0) 	       dgemv(TRANSP, k, n, -ONE, x, temp, ONE, &x[k][0]);            else	       daxpy(n, -temp[0], x[0], 1, x[k], 1);         }	 if (km1 < 0 || p != 1) {	    s = ddot(n, x[k], 1, x[k], 1);	    t += s;	    if (s > t/CONST) {	       small = FALSE;	       s = sqrt(s);               b[k - f][k - f] = s;	       if (s != ZERO) s = ONE/s;	       dscal(n, s, x[k], 1);	    }	    else {	       small = TRUE;	       orig  = FALSE;	    }	 }	 if (small == FALSE || p == 1) break;      }   }}#include <stdio.h>#define		TRANSP   1#define		NTRANSP  0#define		ZERO	 0.0#define		ONE	 1.0/*********************************************************************** *                                                                     * *                         dgemv()                                     * * A C-translation of the level 2 BLAS routine DGEMV by Dongarra,      * * du Croz, and Hammarling, and Hanson (see LAPACK Users' Guide).      * *                                                                     * ***********************************************************************//***********************************************************************   Description   -----------   dgemv() performs one of the matrix-vector operations   y := alpha * A * x + beta * y  or  y := alpha * A' * x + beta * y   where alpha and beta are scalars, X, Y are vectors and A is an   m by n matrix.void dgemv(long transa, long m, long n,            double alpha, double **a, double *x, double beta, double *y)   Parameters

⌨️ 快捷键说明

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