📄 tms1.c
字号:
sec2 = sec21 + sec22 + sec23; total += sec1 + sec2 + sec3 + sec4; /* load output time and mxv arrays */ time[0] = sec1; time[1] = sec2; 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"double epslon(double 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. */ double 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 long ncol,nrow;extern char *error[];/*********************************************************************** * check_parameters() * *********************************************************************** Description ----------- Function validates input parameters and returns error code (long) 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)**************************************************************************/long check_parameter(long n, FILE *fp_out1, long maxi, long nmax, long nzmax, long p, long vec, long nnzero){ long 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(long n,double *dx,long incx,double *dy,long incy){ long 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(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;}/************************************************************** * Function interchanges two vectors * * Based on Fortran-77 routine from Linpack by J. Dongarra * **************************************************************/ void dswap(long n,double *dx,long incx,double *dy,long incy){ long i; double 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(long, long, long, double, double **, double *, double, double *);double ddot(long, double *,long, double *, long);void dscal(long, double, double *,long);void daxpy(long, double, double *,long, double *, long);void dcopy(long, double *, long, double *, long);/*********************************************************************** * * * 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(long p, long f, long n, double **b, double **x, double *temp){ long fp, k, km1; long orig, small; double 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"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. 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 ............................*/#include <math.h>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -