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

📄 las1.c

📁 求矩阵奇异分解svd算法
💻 C
📖 第 1 页 / 共 5 页
字号:
		  r = (d[i] - g) * s + 2.0 * c * b;		  p = s * r;		  d[i+1] = g + p;		  g = c * r - b;		  f = bnd[i+1];		  bnd[i+1] = s * bnd[i] + c * f;		  bnd[i] = c * bnd[i] - s * f;		  i--;	       }	    }       /* end while (underflow != FALSE && i >= l) */	    /*........ recover from underflow .........*/	    if (underflow) {	       d[i+1] -= p;	       e[m] = 0.0;	    }	    else {	       d[l] -= p;	       e[l] = g;	       e[m] = 0.0;	    }	 } 		       		   /* end if (m != l) */	 else {            /* order the eigenvalues */	    exchange = TRUE;	    if (l != 0) {	       i = l;	       while (i >= 1 && exchange == TRUE) {	          if (p < d[i-1]) {		     d[i] = d[i-1];		     bnd[i] = bnd[i-1];	             i--;	          }	          else exchange = FALSE;	       }	    }	    if (exchange) i = 0;	    d[i] = p;	    bnd[i] = f; 	    iteration = 31;	 }      }			       /* end while (iteration <= 30) */   }				   /* end for (l=0; l<n; l++) */   return;}						  /* end main */#include <math.h>#define		TRUE	1#define		FALSE	0extern int ierr;float fsign(float, float);float pythag(float, float);/*********************************************************************** *                                                                     * *				imtql2()			       * *                                                                     * ***********************************************************************//***********************************************************************   Description   -----------   imtql2() is a translation of a Fortran version of the Algol   procedure IMTQL2, Num. Math. 12, 377-383(1968) by Martin and    Wilkinson, as modified in Num. Math. 15, 450(1970) by Dubrulle.     Handbook for Auto. Comp., vol.II-Linear Algebra, 241-248(1971).     See also B. T. Smith et al, Eispack Guide, Lecture Notes in    Computer Science, Springer-Verlag, (1976).   This function finds the eigenvalues and eigenvectors of a symmetric   tridiagonal matrix by the implicit QL method.   Arguments   ---------   (input)                                                                nm     row dimension of the symmetric tridiagonal matrix              n      order of the matrix                                           d      contains the diagonal elements of the input matrix           e      contains the subdiagonal elements of the input matrix in its            last n-1 positions.  e[0] is arbitrary	                z      contains the identity matrix				                                                                          (output)                                                          d      contains the eigenvalues in ascending order.  if an error            exit is made, the eigenvalues are correct but unordered for            for indices 0,1,...,ierr.				      e      has been destroyed.					     z      contains orthonormal eigenvectors of the symmetric               tridiagonal (or full) matrix.  if an error exit is made,            z contains the eigenvectors associated with the stored           eigenvalues.					   ierr   set to zero for normal return, j if the j-th eigenvalue has            not been determined after 30 iterations.		       Functions used   --------------   UTILITY	fsign   MISC		pythag ***********************************************************************/void imtql2(int nm, int n, float d[], float e[], float z[]){   int index, nnm, j, last, l, m, i, k, iteration, convergence, underflow;   float b, test, g, r, s, c, p, f;   if (n == 1) return;   ierr = 0;   last = n - 1;   for (i = 1; i < n; i++) e[i-1] = e[i];   e[last] = 0.0;   nnm = n * nm;   for (l = 0; l < n; l++) {      iteration = 0;      /* look for small sub-diagonal element */      while (iteration <= 30) {	 for (m = l; m < n; m++) {	    convergence = FALSE;	    if (m == last) break;	    else {	       test = fabs(d[m]) + fabs(d[m+1]);	       if (test + fabs(e[m]) == test) convergence = TRUE;	    }	    if (convergence) break;	 }	 if (m != l) {	    /* set error -- no convergence to an eigenvalue after	     * 30 iterations. */     	    if (iteration == 30) {	       ierr = l;	       return;	    }	    p = d[l]; 	    iteration += 1;	    /* form shift */	    g = (d[l+1] - p) / (2.0 * e[l]);	    r = pythag(g, 1.0);	    g = d[m] - p + e[l] / (g + fsign(r, g));	    s = 1.0;	    c = 1.0;	    p = 0.0;	    underflow = FALSE;	    i = m - 1;	    while (underflow == FALSE && i >= l) {	       f = s * e[i];	       b = c * e[i];	       r = pythag(f, g);	       e[i+1] = r;	       if (r == 0.0) underflow = TRUE;	       else {		  s = f / r;		  c = g / r;		  g = d[i+1] - p;		  r = (d[i] - g) * s + 2.0 * c * b;		  p = s * r;		  d[i+1] = g + p;		  g = c * r - b;		  /* form vector */		  for (k = 0; k < nnm; k += n) {		     index = k + i;		     f = z[index+1];		     z[index+1] = s * z[index] + c * f;		     z[index] = c * z[index] - s * f;		  } 		  i--;	       }	    }   /* end while (underflow != FALSE && i >= l) */	    /*........ recover from underflow .........*/	    if (underflow) {	       d[i+1] -= p;	       e[m] = 0.0;	    }	    else {	       d[l] -= p;	       e[l] = g;	       e[m] = 0.0;	    }	 }	 else break;      }		/*...... end while (iteration <= 30) .........*/   }		/*...... end for (l=0; l<n; l++) .............*/   /* order the eigenvalues */   for (l = 1; l < n; l++) {      i = l - 1;      k = i;      p = d[i];      for (j = l; j < n; j++) {	 if (d[j] < p) {	    k = j;	    p = d[j];	 }      }      /* ...and corresponding eigenvectors */      if (k != i) {	 d[k] = d[i];	 d[i] = p;	  for (j = 0; j < nnm; j += n) {	     p = z[j+i];	     z[j+i] = z[j+k];	     z[j+k] = p;	  }      }      }   return;}		/*...... end main ............................*/#include <math.h>extern float eps;/*********************************************************************** *                                                                     * *				machar()			       * *                                                                     * ***********************************************************************//***********************************************************************   Description   -----------   This function is a partial translation of a Fortran-77 subroutine    written by W. J. Cody of Argonne National Laboratory.   It dynamically determines the listed machine parameters of the   floating-point arithmetic.  According to the documentation of   the Fortran code, "the determination of the first three uses an   extension of an algorithm due to M. Malcolm, ACM 15 (1972),    pp. 949-951, incorporating some, but not all, of the improvements   suggested by M. Gentleman and S. Marovich, CACM 17 (1974),    pp. 276-277."  The complete Fortran version of this translation is   documented in W. J. Cody, "Machar: a Subroutine to Dynamically    Determine Determine Machine Parameters," TOMS 14, December, 1988.   Parameters reported    -------------------   ibeta     the radix for the floating-point representation          it        the number of base ibeta digits in the floating-point               significand					    irnd      0 if floating-point addition chops		                   1 if floating-point addition rounds, but not in the                  ieee style					             2 if floating-point addition rounds in the ieee style             3 if floating-point addition chops, and there is                     partial underflow				             4 if floating-point addition rounds, but not in the                 ieee style, and there is partial underflow                 5 if floating-point addition rounds in the ieee style,                 and there is partial underflow                      machep    the largest negative integer such that                               1.0+float(ibeta)**machep .ne. 1.0, except that                  machep is bounded below by  -(it+3)             negeps    the largest negative integer such that                           1.0-float(ibeta)**negeps .ne. 1.0, except that                  negeps is bounded below by  -(it+3)	        ***********************************************************************/void machar(int *ibeta, int *it, int *irnd, int *machep, int *negep){   float beta, betain, betah, a, b, ZERO, ONE, TWO, temp, tempa, temp1;   int i, itemp;   ONE = (float) 1;   TWO = ONE + ONE;   ZERO = ONE - ONE;   a = ONE;   temp1 = ONE;   while (temp1 - ONE == ZERO) {      a = a + a;      temp = a + ONE;      temp1 = temp - a;   }   b = ONE;   itemp = 0;   while (itemp == 0) {      b = b + b;      temp = a + b;      itemp = (int)(temp - a);   }   *ibeta = itemp;   beta = (float) *ibeta;   *it = 0;   b = ONE;   temp1 = ONE;   while (temp1 - ONE == ZERO) {      *it = *it + 1;      b = b * beta;      temp = b + ONE;      temp1 = temp - b;   }   *irnd = 0;    betah = beta / TWO;    temp = a + betah;   if (temp - a != ZERO) *irnd = 1;   tempa = a + beta;   temp = tempa + betah;   if ((*irnd == 0) && (temp - tempa != ZERO)) *irnd = 2;   *negep = *it + 3;   betain = ONE / beta;   a = ONE;   for (i = 0; i < *negep; i++) a = a * betain;   b = a;   temp = ONE - a;   while (temp-ONE == ZERO) {      a = a * beta;      *negep = *negep - 1;      temp = ONE - a;   }   *negep = -(*negep);   *machep = -(*it) - 3;   a = b;   temp = ONE + a;   while (temp - ONE == ZERO) {      a = a * beta;      *machep = *machep + 1;      temp = ONE + a;   }   eps = a;   return;}#include <stdio.h>#define MAXLL 2#define STORQ 1#define RETRQ 2#define STORP 3#define RETRP 4extern float *a;void   dcopy(int, float *, int, float *, int);/*********************************************************************** *                                                                     * *                     store()                                         * *                                                                     * ***********************************************************************//***********************************************************************   Description   -----------   store() is a user-supplied function which, based on the input   operation flag, stores to or retrieves from memory a vector.   Arguments    ---------   (input)   n       length of vector to be stored or retrieved   isw     operation flag:	     isw = 1 request to store j-th Lanczos vector q(j)	     isw = 2 request to retrieve j-th Lanczos vector q(j)	     isw = 3 request to store q(j) for j = 0 or 1	     isw = 4 request to retrieve q(j) for j = 0 or 1   s	   contains the vector to be stored for a "store" request    (output)   s	   contains the vector retrieved for a "retrieve" request    Functions used   --------------   BLAS		dcopy ***********************************************************************/void store(int n, int isw, int j, float *s){   switch(isw) {   case STORQ:	dcopy(n, s, 1, &a[(j+MAXLL) * n], 1);		break;   case RETRQ:	dcopy(n, &a[(j+MAXLL) * n], 1, s, 1);		break;   case STORP:	if (j >= MAXLL) {		   fprintf(stderr,"store: (STORP) j >= MAXLL \n");		   break;		}		dcopy(n, s, 1, &a[j*n], 1);		break;   case RETRP:	if (j >= MAXLL) {		   fprintf(stderr,"store: (RETRP) j >= MAXLL \n");		   break;		}   		dcopy(n, &a[j*n], 1, s, 1);		break;   }   return;}float fsign(float a,float 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);}float dmax(float a, float b)/**************************************************************  * returns the larger of two float precision numbers         * **************************************************************/ {   if (a > b) return(a);   else return(b);}float dmin(float a, float b)/**************************************************************  * returns the smaller of two

⌨️ 快捷键说明

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