📄 svdpack.cc
字号:
y[k][i] += value[j] * ztempp[k][rowind[j]]; } return;}/************************************************************** * * * multiplication of matrix B by vector x, where B = A'A, * * and A is nrow by ncol (nrow >> ncol) and is stored using * * the Harwell-Boeing compressed column sparse matrix format. * * Hence, B is of order n = ncol. y stores product vector. * * * **************************************************************/void svdpack::opb(long nrow, long ncol, double *x, double *y){ long i, j, end; mxvcount += 1; mtxvcount += 1; for (i = 0; i < ncol; i++) y[i] = ZERO; for (i = 0; i < nrow; i++) ztemp[i] = ZERO; for (i = 0; i < ncol; i++) { end = pointr[i+1]; for (j = pointr[i]; j < end; j++) ztemp[rowind[j]] += value[j] * (*x); x++; } for (i = 0; i < ncol; i++) { end = pointr[i+1]; for (j = pointr[i]; j < end; j++) *y += value[j] * ztemp[rowind[j]]; y++; } return;}/********************************************************************* * Function sorts array1 and array2 into increasing order for array1 * *********************************************************************/void svdpack::dsort2(long igap,long n,double *array1,double *array2){ double temp; long i, j, index; if (!igap) return; else { for (i = igap; i < n; i++) { j = i - igap; index = i; while (j >= 0 && array1[j] > array1[index]) { temp = array1[j]; array1[j] = array1[index]; array1[index] = temp; temp = array2[j]; array2[j] = array2[index]; array2[index] = temp; j -= igap; index = j + igap; } } } dsort2(igap/2,n,array1,array2);}/************************************************************** * multiplication of matrix B by vector x, where B = A'A, * * and A is nrow by ncol (nrow >> ncol). Hence, B is of order * * n = ncol (y stores product vector). * **************************************************************/void svdpack::opb(long n, double *x, double *y, bool flag){ long i, j, end; mxvcount += 2; for (i = 0; i < n; i++) y[i] = 0.0; for (i = 0; i < nrow; i++) ztemp[i] = 0.0; for (i = 0; i < ncol; i++) { end = pointr[i+1]; for (j = pointr[i]; j < end; j++) ztemp[rowind[j]] += value[j] * (*x); x++; } for (i = 0; i < ncol; i++) { end = pointr[i+1]; for (j = pointr[i]; j < end; j++) *y += value[j] * ztemp[rowind[j]]; y++; } return;}double svdpack::norm_1(){/* find matrix 1-norm */ double alpha,sum; long i,j,last; alpha = 0.0; for (j=0; j<ncol; ++j) { sum = 0.0; last= pointr[j+1]; for (i=pointr[j]; i<last ; ++i) sum += fabs(value[i]); alpha = dmax(alpha,sum); } return(alpha);}/************************************************************** * multiplication of 2-cyclic matrix B by a vector x, where * * * * B = [0 A] * * [A' 0] , where A is nrow by ncol (nrow >> ncol). Hence,* * B is of order n = nrow+ncol (y stores product vector). * **************************************************************/ void svdpack::opb(long n,double *x, double *y){ long i, j, end; double *tmp; mxvcount += 2; for (i = 0; i < n; i++) y[i] = 0.0; tmp = &x[nrow]; for (i = 0; i < ncol; i++) { end = pointr[i+1]; for (j = pointr[i]; j < end; j++) y[rowind[j]] += value[j] * (*tmp); tmp++; } for (i = nrow; i < n; i++) { end = pointr[i-nrow+1]; for (j = pointr[i-nrow]; j < end; j++) y[i] += value[j] * x[rowind[j]]; } return;}/************************************************************** * function scales a vector by a constant. * * Based on Fortran-77 routine from Linpack by J. Dongarra * **************************************************************/ void svdpack::datx(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++); 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;}/*********************************************************************** * * * dgemm3() * * * * A C-translation of the level 3 BLAS routine DGEMM by Dongarra, * * Duff, du Croz, and Hammarling (see LAPACK Users' Guide). * * In this version, the arrays which store the matrices used in this * * matrix-matrix multiplication are accessed as two-dimensional arrays.* * * ***********************************************************************//*********************************************************************** Description ----------- dgemm3() performs one of the matrix-matrix operations C := alpha * op(A) * op(B) + beta * C, where op(X) = X or op(X) = X', alpha and beta are scalars, and A, B and C are matrices, with op(A) an m by k matrix, op(B) a k by n matrix and C an m by n matrix. Parameters ---------- (input) transa TRANSP indicates op(A) = A' is to be used in the multiplication NTRANSP indicates op(A) = A is to be used in the multiplication transb TRANSP indicates op(B) = B' is to be used in the multiplication NTRANSP indicates op(B) = B is to be used in the multiplication m on entry, m specifies the number of rows of the matrix op(A) and of the matrix C. m must be at least zero. Unchanged upon exit. n on entry, n specifies the number of columns of the matrix op(B) and of the matrix C. n must be at least zero. Unchanged upon exit. k on entry, k specifies the number of columns of the matrix op(A) and the number of rows of the matrix B. k must be at least zero. Unchanged upon exit. alpha a scalar multiplier a matrix A as a 2-dimensional array. When transa = NTRANSP, the leading m by k part of a must contain the matrix A. Otherwise, the leading k by m part of a must contain the matrix A. ira,ica row and column indices of matrix a, where mxn part starts. b matrix B as a 2-dimensional array. When transb = NTRANSP, the leading k by n part of a must contain the matrix B. Otherwise, the leading n by k part of a must contain the matrix B. irb,icb row and column indices of matrix b, where kxn starts. beta a scalar multiplier. When beta is supplied as zero then C need not be set on input. c matrix C as a 2-dimensional array. On entry, the leading m by n part of c must contain the matrix C, except when beta = 0. In that case, c need not be set on entry. On exit, c is overwritten by the m by n matrix (alpha * op(A) * op(B) + beta * C). irc,icc row and column indices of matrix c, where the mxn part is stored.***********************************************************************/void svdpack::dgemm3(long transa, long transb, long m, long n, long k, double alpha, double **a, long ira, long ica, double **b, long irb, long icb, double beta, double **c, long irc, long icc){ long info; long i, j, l, nrowa, ncola, nrowb, ncolb; double temp; info = 0; if ( transa != TRANSP && transa != NTRANSP ) info = 1; else if ( transb != TRANSP && transb != NTRANSP ) info = 2; else if ( m < 0 ) info = 3; else if ( n < 0 ) info = 4; else if ( k < 0 ) info = 5; if (info) { fprintf(stderr, "%s %1ld %s\n", "*** ON ENTRY TO DGEMM3, PARAMETER NUMBER",info,"HAD AN ILLEGAL VALUE"); exit(info); } if (transa) { nrowa = m; ncola = k; } else { nrowa = k; ncola = m; } if (transb) { nrowb = k; ncolb = n; } else { nrowb = n; ncolb = k; } if (!m || !n || ((alpha == ZERO || !k) && beta == ONE)) return; if (alpha == ZERO) { if (beta == ZERO) for (j = 0; j < n; j++) for (i = 0; i < m; i++) c[icc+j][irc+i] = ZERO; else for (j = 0; j < n; j++) for (i = 0; i < m; i++) c[icc+j][irc+i] *= beta; return; } if (!transb) { switch(transa) { /* form C := alpha * A * B + beta * C */ case NTRANSP: for(j = 0; j < n; j++) { for(i=0; i<m; i++) c[icc+j][irc+i]=0.0; for(l=0; l<k; l++) if(b[icb+j][irb+l]!=0.0) { temp = alpha*b[icb+j][irb+l]; for(i=0; i<m; i++) c[icc+j][irc+i] += temp*a[ica+l][ira+i]; } } break; /* form C := alpha * A' * B + beta * C */ case TRANSP: for(j = 0; j < n; j++) { for(i=0; i<m; i++) { temp = 0.0; for(l = 0; l< k;l++) temp += a[ica+i][ira+l]*b[icb+j][irb+l]; if(beta==0.0) c[icc+j][irc+i]=alpha*temp; else c[icc+j][irc+i] = alpha*temp + beta*c[icc+j][irc+i]; } } break; } } else { switch(transa) { /* form C := alpha * A * B' + beta * C */ case NTRANSP: for(j=0; j<n; j++) { for(i=0; i<m; i++) c[icc+j][irc+i]=ZERO; for(l=0; l<k; l++) { temp = alpha*b[l+icb][j+irb]; for(i=0; i<m; i++) c[j+icc][i+irc] += temp*a[l+ica][i+ira]; } } break; /* form C := alpha * A' * B' + beta * C */ case TRANSP: for(j=0; j<n; j++) { for (i=0; i<m; i++) { temp = ZERO; for(l=0; l<k; l++) temp += a[i+ica][l+ira]*b[l+icb][j+irb]; if(!beta) c[j+icc][i+irc] += alpha * temp; else c[j+icc][i+irc]= alpha*temp+ beta*c[j+icc][i+irc]; } } break; } }}void svdpack::opat(double *x, double *y){ /* multiplication of transpose (nrow by ncol sparse matrix A) by the vector x, store in y */ long i,j,upper; for(i=0; i<ncol; i++) y[i]=ZERO; for(i=0; i<ncol; i++) { upper = pointr[i+1]; for(j=pointr[i]; j<upper; j++) y[i] += value[j]*x[rowind[j]]; } return;}double svdpack::dasum(long n, double *dx, long incx){ /************************************************************** * Function forms the sum of the absolute values. * * Uses unrolled loops for increment equal to one. * * Based on Fortran-77 routine from Linpack by J.Dongarra. **************************************************************/ double dtemp,dsum; long i,ix,m,mp1; dsum = ZERO; dtemp = ZERO; if(n <= 0) return 0; if(incx != 1) { /* code for increment not equal to 1 */ ix = 0; if(incx < 0) ix = (-n+1)*incx + 1; for(i=0; i<n; i++) { dtemp += fabs(dx[ix]); ix += incx; } dsum = dtemp; return(dsum); } /* code for increment equal to 1 */ /* clean-up loop */ m = n % 6; if(m) { for(i=0; i<m; i++) dtemp += fabs(dx[i]); } if(n>=6) { for(i=m; i<n; i+=6) dtemp += fabs(dx[i]) + fabs(dx[i+1]) + fabs(dx[i+2]) + fabs(dx[i+3]) + fabs(dx[i+4]) + fabs(dx[i+5]); } dsum = dtemp; return(dsum);}/*********************************************************************** * * * tred2() * * * ***********************************************************************//*********************************************************************** Description ----------- tred2() is a translation of the algol procedure TRED2, Num. Math. 11, 181-195 (1968) by Martin, Reinsch, and Wikinson. Handbook for Auto. Comp., Vol. II- Linear Algebra, 212-226 (1971) This subroutine reduces a real symmetric matrix to a symmetric tridiagonal matrix using and accumulating orthogonal similarity transformations. Arguments --------- (input) offset index of the leading element of the matrix to be tridiagonalized. The matrix tridiagonalized should be stored in a[offset:n-1, offset:n-
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -