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

📄 sis2.c

📁 svd 算法代码 This directory contains instrumented SVDPACKC Version 1.0 (ANSI-C) programs for compiling
💻 C
📖 第 1 页 / 共 4 页
字号:
     {       for (k=offset;k<=l;k++)        {         d[k]=d[k]/scale;         h+=d[k]*d[k];        }       f=d[l];       g=-fsign(sqrt(h), f);       e[i]=scale * g;       h-=f*g;       d[l]=f-g;          /* form A*u */         for (j=offset; j<=l; j++)          e[j]=ZERO;                    for (j=offset;j<=l;j++)            {             f=d[j];             z[j][i]=f;             g= e[j] + z[j][j] * f;                          jp1= j + 1;                if (l >= jp1)                  {                  for (k=jp1; k<=l; k++)                   {                     g+= z[k][j] * d[k];                     e[k] += z[k][j] * f;                   }                 };             e[j]=g;           }       /* form P */        f= ZERO;        for (j=offset; j<=l; j++)        {          e[j]=e[j]/h;          f+= e[j] * d[j];        }       hh= f/ (h+h);         /* form Q */        for (j=offset; j<=l; j++)       e[j] -= hh * d[j];      /* form reduced A */      for (j=offset; j<=l; j++)       {         f= d[j];         g = e[j];         for (k=j; k<=l; k++)          z[k][j]= z[k][j] - f * e[k] - g * d[k];         d[j]=z[l][j];         z[i][j]=ZERO;       }    }  /* end scale <> zero */    d[i]=h;   }   /* end for ii */   /*accumulation of transformation matrices */   for (i=offset + 1;i<n;i++)    {     l=i-1;     z[n-1][l] = z[l][l];     z[l][l] = ONE;     h=d[i];     if (h != ZERO)        {        for (k=offset; k<=l; k++)          d[k]= z[k][i]/h;        for (j=offset; j<=l; j++)         {           g= ZERO;                      for (k=offset;k<=l; k++)            g+= z[k][i]*z[k][j];	   for (k=offset;k<=l;k++)            z[k][j] -= g * d[k];         }       }       for (k=offset;k<=l;k++) z[k][i]=ZERO;     }       for (i=offset;i<n;i++)       {        d[i]=z[n-1][i];        z[n-1][i]=ZERO;       }     z[n-1][n-1]=ONE;     e[0]=ZERO;/*preparation for tql2.c.. reorder e[]*/for (i=1+offset;i<n;i++) e[i-1]=e[i]; /*preparation for tql2.c.. z has to be transposed for   tql2 to give correct eigenvectors */for (ii=offset; ii<n; ii++) for (jj=ii; jj<n; jj++) {   tmp=z[ii][jj];  z[ii][jj]=z[jj][ii];  z[jj][ii]=tmp; }     return;}                   #include <math.h>double fsign(double, double);double pythag(double, double);/*********************************************************************** *                                                                     * *				tql2()   			       * *                                                                     * ***********************************************************************//***********************************************************************   Description   -----------   tql2() is a translation of a Fortran version of the Algol   procedure TQL2, Num. Math. 11, 293-306(1968) by Dowdler, Martin,    Reinsch and Wilkinson.   Handbook for Auto. Comp., vol.II-Linear Algebra, 227-240(1971).     This function finds the eigenvalues and eigenvectors of a symmetric   tridiagonal matrix by the QL method.   Arguments   ---------   (input)                                                                offset the index of the leading element  of the input(full) matrix          to be factored.   n      order of the symmetric tridiagonal matrix              d      contains the diagonal elements of the input matrix           e      contains the subdiagonal elements of the input matrix in its            first n-1 positions.   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.		    	  (return value)   Functions used   --------------   UTILITY	fsign   MISC		pythag ***********************************************************************/long tql2(long offset, long n, double *d, double *e, double **z){   long j, last, l, l1, l2, m, i, k, iteration;   double tst1, tst2, g, r, s, s2, c, c2, c3, p, f, h, el1, dl1;   if (n == 1) return(0);   f = ZERO;   last = n - 1;   tst1 = ZERO;   e[last] = ZERO;   for (l = offset; l < n; l++) {      iteration = 0;      h = fabs(d[l]) + fabs(e[l]);      if (tst1 < h) tst1 = h;      /* look for small sub-diagonal element */      for (m = l; m < n; m++) {	 tst2 = tst1 + fabs(e[m]);	 if (tst2 == tst1) break;      }      if (m != l) {	 while (iteration < 30) {	    iteration += 1;            /*  form shift */	    l1 = l + 1;	    l2 = l1 + 1;	    g = d[l];            p = (d[l1] - g) / (2.0 * e[l]);	    r = pythag(p, ONE);	    d[l] = e[l] / (p + fsign(r, p));	    d[l1] = e[l] * (p + fsign(r, p));	    dl1 = d[l1];	    h = g - d[l];	    if (l2 < n) 	       for (i = l2; i < n; i++) d[i] -= h;            f += h;	    /* QL transformation */	    p = d[m];	    c = ONE;	    c2 = c;	    el1 = e[l1];	    s = ZERO;	    i = m - 1;	    while (i >= l) {	       c3 = c2;	       c2 = c;	       s2 = s;	       g = c * e[i];	       h = c * p;	       r = pythag(p, e[i]);	       e[i + 1] = s * r;	       s = e[i] / r;	       c = p / r;	       p = c * d[i] - s * g;	       d[i + 1]= h + s * (c * g + s * d[i]);	       /*  form vector */	       for (k = offset; k < n; k ++) {	          h = z[i + 1][k];	          z[i + 1][k] = s * z[i][k] + c * h;	          z[i][k] = c * z[i][k] - s * h;	       }	       i--;	    }	    p = -s * s2 * c3 *el1 * e[l] / dl1;	    e[l] = s * p;	    d[l] = c * p;	    tst2 = tst1 + fabs(e[l]);	    if (tst2 <= tst1) break;	    if (iteration == 30) 	       return(l);         }      }      d[l] += f;   }   /* order the eigenvalues */   for (l = 1+offset; 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 = offset; j < n; j ++) {	     p = z[i][j];	     z[i][j] = z[k][j];	     z[k][j] = p;	  }      }      }   return(0);}		/*...... end main ............................*/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>double dmax(double, double);double dmin(double, double);/**************************************************************  *							      * * Function finds sqrt(a^2 + b^2) without overflow or         * * destructive underflow.				      * *							      * **************************************************************/ /**************************************************************    Funtions used   -------------   UTILITY	dmax, dmin **************************************************************/ double pythag(double a, double b){   double p, r, s, t, u, temp;   p = dmax(fabs(a), fabs(b));   if (p != 0.0) {      temp = dmin(fabs(a), fabs(b)) / p;      r = temp * temp;       t = 4.0 + r;      while (t != 4.0) {	 s = r / t;	 u = 1.0 + 2.0 * s;	 p *= u;	 temp = s / u;	 r *= temp * temp;	 t = 4.0 + r;      }   }   return(p);}/**************************************************************  * Function forms the dot product of two vectors.      	      * * Based on Fortran-77 routine from Linpack by J. Dongarra    * **************************************************************/ extern long flag;double ddot( long n,double *dx,long incx,double *dy,long incy){   long i;   double dot_product;   if (n <= 0 || incx == 0 || incy == 0) return(0.0);   dot_product = 0.0;   if (incx == 1 && incy == 1)       for (i=0; i < n; i++)       dot_product += (*dx++) * (*dy++);   else {      if (incx < 0) dx += (-n+1) * incx;      if (incy < 0) dy += (-n+1) * incy;      for (i=0; i < n; i++) {         dot_product += (*dx) * (*dy);         dx += incx;         dy += incy;      }   }   return(dot_product);}/**************************************************************  * Constant times a vector plus a vector     		      * * Based on Fortran-77 routine from Linpack by J. Dongarra    * **************************************************************/ void daxpy (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++);	 dy++;      }   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;}/**************************************************************  * Function scales a vector by a constant.     		      * * Based on Fortran-77 routine from Linpack by J. Dongarra    * **************************************************************/ void dscal(long n,double da,double *dx,long incx){   long i;   if (n <= 0 || incx == 0) return;   if (incx < 0) dx += (-n+1) * incx;   for (i=0; i < n; i++) {      *dx *= da;      dx += incx;   }   return;}

⌨️ 快捷键说明

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