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

📄 las1.c

📁 求矩阵奇异分解svd算法
💻 C
📖 第 1 页 / 共 5 页
字号:
   r = wptr[0];   alf = wptr[6];   eta = wptr[7];   oldeta = wptr[8];   bet = wptr[9];   wrk = wptr[5];   j = 0;   /* take the first step */   stpone(n, wptr);   if (!rnm || ierr) return;   eta[0] = eps1;   oldeta[0] = eps1;   ll = 0;   first = 1;   last = imin(maxprs + imax(8,maxprs), lanmax);   ENOUGH = FALSE;   id1 = 0;   while (id1 < maxprs && !ENOUGH) {      if (rnm <= tol) rnm = 0.0;      /* the actual lanczos loop */      lanczos_step(n, first, last, wptr, alf, eta, oldeta, bet, &ll,		   &ENOUGH);      if (ENOUGH) j = j - 1;      else j = last - 1;      first = j + 1;      bet[j+1] = rnm;      /* analyze T */      l = 0;      for (id2 = 0; id2 < j; id2++) {	 if (l > j) break;         for (i = l; i <= j; i++) if (!bet[i+1]) break;	 if (i > j) i = j;	 /* now i is at the end of an unreduced submatrix */	 dcopy(i-l+1, &alf[l],   1, &ritz[l],  -1);	 dcopy(i-l,   &bet[l+1], 1, &wrk[l+1], -1);	 imtqlb(i-l+1, &ritz[l], &wrk[l], &bnd[l]);	 if (ierr) {	    printf("IMTQLB FAILED TO CONVERGE (IERR = %d)\n",		    ierr);	    printf("L = %d    I = %d\n", l, i);            for (id3 = l; id3 <= i; id3++) 	       printf("%d  %g  %g  %g\n",	       id3, ritz[id3], wrk[id3], bnd[id3]);	 }         for (id3 = l; id3 <= i; id3++) 	    bnd[id3] = rnm * fabs(bnd[id3]);	 l = i + 1;      }      /* sort eigenvalues into increasing order */      dsort2((j+1) / 2, j + 1, ritz, bnd);      /* massage error bounds for very close ritz values */      error_bound(&ENOUGH, endl, endr, ritz, bnd);      /* should we stop? */      if (neig < maxprs) {	 if (!neig) last = first + 9;	 else last = first + imax(3, 1 + ((j-5) * (maxprs-neig)) / neig);	 last = imin(last, lanmax);      }      else ENOUGH = TRUE;      ENOUGH = ENOUGH || first >= lanmax;      id1++;   }   store(n, STORQ, j, wptr[1]);   return;}#include <math.h>#define STORQ 1#define RETRQ 2#define STORP 3#define RETRP 4#define TRUE  1#define FALSE 0#define MAXLL 2extern float rnm, anorm, tol, eps, eps1, reps, eps34;extern int ierr, j;float ddot(int, float *,int, float *, int);void   dscal(int, float, float *,int);void   daxpy(int, float, float *,int, float *, int);void   datx(int, float, float *,int, float *, int);void   dcopy(int, float *, int, float *, int);void   purge(int, int, float *, float *, float *, float *,	     float *, float *, float *);void   ortbnd(float *, float *, float *, float *);float startv(int, float *[]);void   store(int, int, int, float *);int   imin(int, int);int   imax(int, int);/*********************************************************************** *                                                                     * *			lanczos_step()                                 * *                                                                     * ***********************************************************************//***********************************************************************   Description   -----------   Function embodies a single Lanczos step   Arguments    ---------   (input)   n        dimension of the eigenproblem for matrix B   first    start of index through loop				         last     end of index through loop				        wptr	    array of pointers pointing to work space		       alf	    array to hold diagonal of the tridiagonal matrix T   eta      orthogonality estimate of Lanczos vectors at step j      oldeta   orthogonality estimate of Lanczos vectors at step j-1   bet      array to hold off-diagonal of T                        ll       number of intitial Lanczos vectors in local orthog.               (has value of 0, 1 or 2)			   enough   stop flag			   Functions used   --------------   BLAS		ddot, dscal, daxpy, datx, dcopy   USER		store   LAS		purge, ortbnd, startv   UTILITY	imin, imax ***********************************************************************/void lanczos_step(int n, int first, int last, float *wptr[],		  float *alf, float *eta, float *oldeta,		  float *bet, int *ll, int *enough){   float t, *mid;   int i;   for (j=first; j<last; j++) {      mid     = wptr[2];      wptr[2] = wptr[1];      wptr[1] = mid;      mid     = wptr[3];      wptr[3] = wptr[4];      wptr[4] = mid;      store(n, STORQ, j-1, wptr[2]);      if (j-1 < MAXLL) store(n, STORP, j-1, wptr[4]);      bet[j] = rnm;      /* restart if invariant subspace is found */      if (!bet[j]) {	 rnm = startv(n, wptr);	 if (ierr) return;	 if (!rnm) *enough = TRUE;      }      if (*enough) break;      /* take a lanczos step */      t = 1.0 / rnm;      datx(n, t, wptr[0], 1, wptr[1], 1);      dscal(n, t, wptr[3], 1);      opb(n, wptr[3], wptr[0]);      daxpy(n, -rnm, wptr[2], 1, wptr[0], 1);      alf[j] = ddot(n, wptr[0], 1, wptr[3], 1);      daxpy(n, -alf[j], wptr[1], 1, wptr[0], 1);      /* orthogonalize against initial lanczos vectors */      if (j <= MAXLL && (fabs(alf[j-1]) > 4.0 * fabs(alf[j])))	 *ll = j;        for (i=0; i < imin(*ll, j-1); i++) {	 store(n, RETRP, i, wptr[5]);	 t = ddot(n, wptr[5], 1, wptr[0], 1);	 store(n, RETRQ, i, wptr[5]);         daxpy(n, -t, wptr[5], 1, wptr[0], 1);	 eta[i] = eps1;	 oldeta[i] = eps1;      }      /* extended local reorthogonalization */      t = ddot(n, wptr[0], 1, wptr[4], 1);      daxpy(n, -t, wptr[2], 1, wptr[0], 1);      if (bet[j] > 0.0) bet[j] = bet[j] + t;      t = ddot(n, wptr[0], 1, wptr[3], 1);      daxpy(n, -t, wptr[1], 1, wptr[0], 1);      alf[j] = alf[j] + t;      dcopy(n, wptr[0], 1, wptr[4], 1);      rnm = sqrt(ddot(n, wptr[0], 1, wptr[4], 1));      anorm = bet[j] + fabs(alf[j]) + rnm;      tol = reps * anorm;      /* update the orthogonality bounds */      ortbnd(alf, eta, oldeta, bet);      /* restore the orthogonality state when needed */      purge(n,*ll,wptr[0],wptr[1],wptr[4],wptr[3],wptr[5],eta,oldeta);      if (rnm <= tol) rnm = 0.0;   }   return;}extern float rnm, eps, eps1, reps, eps34;extern int j;void   dswap(int, float *, int, float *, int);/*********************************************************************** *                                                                     * *                          ortbnd()                                   * *                                                                     * ***********************************************************************//***********************************************************************   Description   -----------   Funtion updates the eta recurrence   Arguments    ---------   (input)   alf      array to hold diagonal of the tridiagonal matrix T            eta      orthogonality estimate of Lanczos vectors at step j           oldeta   orthogonality estimate of Lanczos vectors at step j-1        bet      array to hold off-diagonal of T                             n        dimension of the eigenproblem for matrix B		       j        dimension of T					     rnm	    norm of the next residual vector			    eps1	    roundoff estimate for dot product of two unit vectors   (output)   eta      orthogonality estimate of Lanczos vectors at step j+1        oldeta   orthogonality estimate of Lanczos vectors at step j           Functions used   --------------   BLAS		dswap ***********************************************************************/void ortbnd(float *alf, float *eta, float *oldeta, float *bet){   int i;   if (j < 1) return;   if (rnm) {      if (j > 1) {	 oldeta[0] = (bet[1] * eta[1] + (alf[0]-alf[j]) * eta[0] -		      bet[j] * oldeta[0]) / rnm + eps1;      }      for (i=1; i<=j-2; i++) 	 oldeta[i] = (bet[i+1] * eta[i+1] + (alf[i]-alf[j]) * eta[i] +		      bet[i] * eta[i-1] - bet[j] * oldeta[i])/rnm + eps1;   }   oldeta[j-1] = eps1;   dswap(j, oldeta, 1, eta, 1);     eta[j] = eps1;   return;}#include <math.h>#define STORQ 1#define RETRQ 2#define STORP 3#define RETRP 4#define TRUE  1#define FALSE 0extern float tol, rnm, eps, eps1, reps, eps34;extern int j;void   store(int, int, int, float *);void   daxpy(int, float, float *, int, float *, int);void   dcopy(int, float *, int, float *, int);int   idamax(int, float *, int);float ddot(int, float *, int, float *, int);/*********************************************************************** *                                                                     * *				purge()                                * *                                                                     * ***********************************************************************//***********************************************************************   Description   -----------   Function examines the state of orthogonality between the new Lanczos   vector and the previous ones to decide whether re-orthogonalization    should be performed   Arguments    ---------   (input)   n        dimension of the eigenproblem for matrix B		          ll       number of intitial Lanczos vectors in local orthog.          r        residual vector to become next Lanczos vector               q        current Lanczos vector			              ra       previous Lanczos vector   qa       previous Lanczos vector   wrk      temporary vector to hold the previous Lanczos vector   eta      state of orthogonality between r and prev. Lanczos vectors    oldeta   state of orthogonality between q and prev. Lanczos vectors   j        current Lanczos step				        (output)   r	    residual vector orthogonalized against previous Lanczos 	      vectors   q        current Lanczos vector orthogonalized against previous ones   Functions used   --------------   BLAS		daxpy,  dcopy,  idamax,  ddot   USER		store ***********************************************************************/void purge(int n, int ll, float *r, float *q, float *ra,  	   float *qa, float *wrk, float *eta, float *oldeta){   float t, tq, tr, reps1;   int k, iteration, flag, i;   if (j < ll+2) return;    k = idamax(j - (ll+1), &eta[ll], 1) + ll;   if (fabs(eta[k]) > reps) {      reps1 = eps1 / reps;      iteration = 0;      flag = TRUE;      while (iteration < 2 && flag) {	 if (rnm > tol) {	    /* bring in a lanczos vector t and orthogonalize both 	     * r and q against it */	    tq = 0.0;	    tr = 0.0;            for (i = ll; i < j; i++) {	       store(n,  RETRQ,  i,  wrk);	       t   = -ddot(n, qa, 1, wrk, 1);	       tq += fabs(t);	       daxpy(n,  t,  wrk,  1,  q,  1);	       t   = -ddot(n, ra, 1, wrk, 1);	       tr += fabs(t);	       daxpy(n, t, wrk, 1, r, 1);	    }	    dcopy(n, q, 1, qa, 1);	    t   = -ddot(n, r, 1, qa, 1);	    tr += fabs(t);	    daxpy(n, t, q, 1, r, 1);	    dcopy(n, r, 1, ra, 1);	    rnm = sqrt(ddot(n, ra, 1, r, 1));	    if (tq <= reps1 && tr <= reps1 * rnm) flag = FALSE;	 }	 iteration++;      }      for (i = ll; i <= j; i++) { 	 eta[i] = eps1;	 oldeta[i] = eps1;      }   }   return;}#include <math.h>extern float rnm, anorm, tol, eps, reps;extern int j, ierr;void   daxpy(int, float, float *,int, float *, int);void   datx(int, float, float *,int, float *, int);void   dcopy(int, float *, int, float *, int);float ddot(int, float *,int, float *, int);void   dscal(int, float, float *,int);float startv(int, float *[]);void   opb(int, float *, float *);void   store(int, int, int, float *);/*********************************************************************** *                                                                     * *                         stpone()                                    * *                                                                     * ***********************************************************************//***********************************************************************   Description   -----------   Function performs the first step of the Lanczos algorithm.  It also   does a step of extended local re-orthogonalization.   Arguments    ---------   (input)   n      dimension of the eigenproblem for matrix B   (output)   ierr   error flag   wptr   array of pointers that point to work space that contains	    wptr[0]             r[j]	    wptr[1]             q[j]	    wptr[2]             q[j-1]	    wptr[3]             p	    wptr[4]             p[j-1]	    wptr[6]             diagonal elements of matrix T    Functions used   --------------   BLAS		daxpy, datx, dcopy, ddot, dscal   USER		store, opb   LAS		startv ***********************************************************************/

⌨️ 快捷键说明

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