📄 tms2.c
字号:
goto L10; } left = s-iptr+1; } } if((!shift) && (job>=1)) { /* work4(:,1) stores gershgorin radii * * iwork(:,1) is the clustering vector */ disk(left, &sig[iptr-1], work4[0], iwork[0], iwork[1]); for(k=iptr-1; k<s; k++) { if(iwork[0][k-iptr+1] == 1) isol(k, work4[2][k-iptr+1], red, lwork, work5[2], work5[3],s); else if(iwork[0][k-iptr+1] > 1) clus(k,iwork[0][k-iptr+1],&work4[2][k-iptr+1],red,lwork, work5[2], work5[3], work4[1],s); } } /* continue algorithm... */ /* shift start */ if((iter>0) && (!shift) && (job>=1)) { if(lwork[iptr-1]) { shift = TRUE; polyac = FALSE; orthg(s, 0, n, work1, y, &work4[0][0]); } } if(shift) { /* compute shifts in work5(:,1) here: */ for(k=iptr-1; k<s; k++) { if((k>iptr-1) && (k<=p-1)) { work5[0][k] = ZERO; for(j=iptr-2; j<k; j++) { if((j!=-1) && (sig[j] <= (sig[k] - work4[2][k-iptr+1]))) work5[0][k] = sig[j]; } if((work5[0][k] == sig[k-1]) && (work5[0][k-1]==sig[k-1])) work5[0][k] = sig[k]; if(work5[0][k] == ZERO) work5[0][k] = work5[0][k-1]; } else if(k>p-1) work5[0][k] = work5[0][p-1]; else if(k==iptr-1) work5[0][k] = sig[k]; } } t1 = timer();/* monitor polynomial degree (if job=2) */ if(job==2) { enew = sig[s-1]; e = fabs(enew-alpha*alpha); if((sig[iptr-1]>pparm1*sig[s-1]) && (enew<alpha*alpha) && (!shift)) { tmp = acosh(sig[s-1]/sig[iptr-1]); itmp = 2*imax(((int) (pparm2/tmp)),1); if(degree) ndegre = imin(2*degree,itmp); else ndegre = 2; } } if(polyac) { for(j=iptr-1; j<s; j++) { pmul(n,y[j],work2[j],work4[0],work4[1],work4[2], e,degree,alpha); } orthg(left,0,n,work1,&work2[iptr-1],work4[0]); for(j=iptr-1; j<s; j++) { for(i=0; i<n; i++) y[j][i]=work2[j][i]; } dtrsm('R','U',TRANSP,'N',n,left,ONE,work1,&y[iptr-1]); mxv[0] += degree*left; mxv[1] += degree*left; } else { /* do cg iterations */ /*load y into work1 array for orthog. projector in subroutine cgt*/ for(j=0; j<left; j++) { for(i=0; i<n; i++) work1[j][i] = y[iptr+j-1][i]; } /* cg loop for independent systems (no shifting used) */ if(!shift) for(i=0; i<left; i++) cgt(n, left, y[iptr+i-1], work1, &itcgt[iptr+i-1], sig[iptr+i-1], sig[s-1], &iwork[0][i], meps); else { /*shift with work5(:,1) in cg iterations */ for(i=0; i<left; i++) { cgts(n, left, y[iptr+i-1], work1, &itcgt[iptr+i-1], sig[iptr+i-1], work5[1][iptr+i-1], sig[s-1], work5[0][iptr+i-1], &iwork[0][i], meps); } } for(i=0; i<left; i++) { mxv[0] += iwork[0][i]; mxv[1] += iwork[0][i]; } } t1 = timer() - t1; sec4 += t1;}L10: /* compute final 2-norms of residual vectors w.r.t. B */ for(j=0; j<p; j++) { opb(n, y[j], work2[j], alpha*alpha); tmp = ddot(n,y[j],1,work2[j],1)/ddot(n,y[j],1,y[j],1); daxpy(n,-tmp,y[j],1,work2[j],1); tmp = sqrt(fabs(tmp)); work4[2][j] = sqrt(ddot(n,work2[j],1,work2[j],1)); opa(y[j],&y[j][n]); tmpi = 1.0/fabs(tmp); dscal(nrow,tmpi,&y[j][n],1); work4[2][j] = work4[2][j]*tmpi; sig[j]=tmp; } mxv[0] += 2*p; mxv[1] += p; 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(ierr);} /* end of tsvd2 */#include <stdio.h>#include <math.h>#include "tmsc.h"/*#define ZERO 0.0#define ONE 1.0*/double epslon(double x){ /* estimate unit roundoff inquantities of size x */ double a,b,c,eps; a = 4.0/3.0; do { b = a - ONE; 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(FILE *fp_out1, long maxi, long nmax, long nzmax, long p, long vec, long nnzero, long n){ 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>#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 <stdio.h>#include <math.h>void dscal(long, double, double *, long);void opb(long, double *, double *, double);void daxpy(long, double, double *, long, double *, long);void pmul(long n, double *y, double *z, double *z2, double *z3, double *z4, double e, long degree, double alpha)/* Compute the multiplication z=P(B)*y (and leave y untouched). P(B) is constructed from chebyshev polynomials. The input parameter degree specifies the polynomial degree to be used. Polynomials are constructed on interval (-e,e) as in Rutishauser's ritzit code */{double tmp2,alpha2,eps,tmp; long i,kk; alpha2 = alpha*alpha;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -