📄 las1.c
字号:
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 + -