📄 tms1.c
字号:
time[2] = sec3; time[3] = sec4; time[4] = total; mxv[2] = mxv[0]+mxv[1]; /* load residual vector */ for(i=0; i<p; i++) res[i] = work4[2][i]; return(0);} /* end of tsvd1 */#include <stdio.h>#include <math.h>#include "tmsc.h"float epslon(float x){ /* Estimate unit roundoff in quantities of size x This function should work properly on all systems satisfying the following two assumptions, 1. The base used in representiong floating point numbers is not a power of three. 2. The quantity a in statement 10 is represented to the accuracy used in floating point variables that are stored in memory. The statement number 10 and the while are intended to force optimizing compilers to generate code satisfying assumption 2. Under these assumptions, it should be true that, A is not exactly equal to four-thirds, B has a zero for its last bit or digit, C is not exactly equal to one, EPS measures the separation of 1.0 from the next larger floating point number. This routine is based on Eispack. The developers of Eispack would appreciate being informed about any systems where these assumptions do not hold. */ float a,b,c,eps; a = 4.0/3.0; do { b = a - ONE; /* statement 10 */ c = b + b + b; eps = fabs(c -ONE); } while (eps == ZERO); eps = eps*fabs(x); return(eps);}#include <stdio.h>#include <math.h>#include <errno.h>#include <fcntl.h>extern int ncol,nrow;extern char *error[];/*********************************************************************** * check_parameters() * *********************************************************************** Description ----------- Function validates input parameters and returns error code (int) Parameters ---------- (input) p desired number of eigenpairs of B. maxi upper limit of desired number of trace steps or iterations. n dimension of the eigenproblem for matrix B vec 1 indicates both singular values and singular vectors are wanted. 0 indicates singular values only. nnzero number of nonzero elements in input matrix (matrix A)**************************************************************************/int check_parameter(int n, FILE *fp_out1, int maxi, int nmax, int nzmax, int p, int vec, int nnzero){ int error_index, ncells; error_index = 0; if(ncol >= nmax || nnzero > nzmax) error_index = 1; else if(p > maxi) error_index = 3; else if(n <= 0) error_index = 4; else if(maxi <= 0 ) error_index = 5; else if(p <= 0 || p > maxi) error_index = 6; if(error_index) fprintf(fp_out1, "%s\n", error[error_index]); return(error_index);}/************************************************************** * Function copies a vector x to a vector y * * Based on Fortran-77 routine from Linpack by J. Dongarra * **************************************************************/ void dcopy(int n,float *dx,int incx,float *dy,int incy){ int i; if (n <= 0 || incx == 0 || incy == 0) return; if (incx == 1 && incy == 1) for (i=0; i < n; i++) *dy++ = *dx++; else { if (incx < 0) dx += (-n+1) * incx; if (incy < 0) dy += (-n+1) * incy; for (i=0; i < n; i++) { *dy = *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(int n,float da,float *dx,int incx){ int 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;}/************************************************************** * Function interchanges two vectors * * Based on Fortran-77 routine from Linpack by J. Dongarra * **************************************************************/ void dswap(int n,float *dx,int incx,float *dy,int incy){ int i; float dtemp; if (n <= 0 || incx == 0 || incy == 0) return; if (incx == 1 && incy == 1) { for (i=0; i < n; i++) { dtemp = *dy; *dy++ = *dx; *dx++ = dtemp; } } else { if (incx < 0) dx += (-n+1) * incx; if (incy < 0) dy += (-n+1) * incy; for (i=0; i < n; i++) { dtemp = *dy; *dy = *dx; *dx = dtemp; dx += incx; dy += incy; } }}#include <math.h>#include <stdio.h>#include "tmsc.h"#define CONST 100.0void dgemv(int, int, int, float, float **, float *, float, float *);float ddot(int, float *,int, float *, int);void dscal(int, float, float *,int);void daxpy(int, float, float *,int, float *, int);void dcopy(int, float *, int, float *, int);/*********************************************************************** * * * 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(int p, int f, int n, float **b, float **x, float *temp){ int fp, k, km1; int orig, small; float 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 <math.h>#include "tmsc.h"float fsign(float, float);float pythag(float, float);/*********************************************************************** * * * 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. Functions used -------------- UTILITY fsign MISC pythag ***********************************************************************/int tql2(int offset, int n, float *d, float *e, float **z){ int j, last, l, l1, l2, m, i, k, iteration; float 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 ............................*/#include <math.h>float dmax(float, float);float dmin(float, float);/************************************************************** * * * Function finds sqrt(a^2 + b^2) without overflow or * * destructive underflow. * * * **************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -