void BetaMultiple::addCol(const std::vector<double>& x, const char * name) throw (mrutils::ExceptionNumerical) { dirty = true; if (cols == maxCols) throw ExceptionNumerical("BetaMultiple: too many columns added"); if (n == 0) { n = (int)x.size(); M.resize(n*(maxCols+2),0); for (int r = 0; r < n; ++r) M(r,0) = 1; } if (storeData) { xs.push_back(x); } if ((int)xnames.size() < cols+1) xnames.resize(cols+1); if (xnames[cols].empty()) xnames[cols] = name; for (unsigned r = 0; r < x.size(); ++r) M(r,cols+1) = x[r]; ++cols; if (col <= 0) return; double nrm = 0; for (int k = 0; k < col; ++k) { dp = 0; for (int r = k; r < n; ++r) dp += M(r,k) * M(r,col); dp /= M(k,k); for (int r = k; r < n; ++r) M(r,col) -= dp * M(r,k); } for (int r = col; r < n; ++r) nrm = PYTHAG(nrm,M(r,col)); if (M(col,col) < 0) nrm = -nrm; dp = Y(col); for (int r = col; r < n; ++r) { M(r,col) /= nrm; dp += M(r,col) * Y(r); } M(col,col) += 1; dp /= M(col,col); diag[col] = -nrm; Y(col) -= dp * M(col,col); diag[maxCols+1] = 0; for (int r = col+1; r < n; ++r) { Y(r) -= dp * M(r,col); diag[maxCols+1] = PYTHAG(diag[maxCols+1],Y(r)); } ++col; }
int dsvd(float *a, int m, int n, float *w, float *v) { int flag, i, its, j, jj, k, l = 0, nm = 0; // (initializing to keep compiler happy) double c, f, h, s, x, y, z; double anorm = 0.0, g = 0.0, scale = 0.0; double *rv1; if (m < n) { fprintf(stderr, "#rows must be > #cols \n"); return(0); } rv1 = (double *)malloc((unsigned int) n*sizeof(double)); /* Householder reduction to bidiagonal form */ for (i = 0; i < n; i++) { /* left-hand reduction */ l = i + 1; rv1[i] = scale * g; g = s = scale = 0.0; if (i < m) { for (k = i; k < m; k++) scale += fabs((double)a[k * n + i]); if (scale) { for (k = i; k < m; k++) { a[k * n + i] = (float)((double)a[k * n + i]/scale); s += ((double)a[k * n + i] * (double)a[k * n + i]); } f = (double)a[i * n + i]; g = -SIGN(sqrt(s), f); h = f * g - s; a[i * n + i] = (float)(f - g); if (i != n - 1) { for (j = l; j < n; j++) { for (s = 0.0, k = i; k < m; k++) s += ((double)a[k * n + i] * (double)a[k * n + j]); f = s / h; for (k = i; k < m; k++) a[k * n + j] += (float)(f * (double)a[k * n + i]); } } for (k = i; k < m; k++) a[k * n + i] = (float)((double)a[k * n + i]*scale); } } w[i] = (float)(scale * g); /* right-hand reduction */ g = s = scale = 0.0; if (i < m && i != n - 1) { for (k = l; k < n; k++) scale += fabs((double)a[i * n + k]); if (scale) { for (k = l; k < n; k++) { a[i * n + k] = (float)((double)a[i * n + k]/scale); s += ((double)a[i * n + k] * (double)a[i * n + k]); } f = (double)a[i * n + l]; g = -SIGN(sqrt(s), f); h = f * g - s; a[i * n + l] = (float)(f - g); for (k = l; k < n; k++) rv1[k] = (double)a[i * n + k] / h; if (i != m - 1) { for (j = l; j < m; j++) { for (s = 0.0, k = l; k < n; k++) s += ((double)a[j * n + k] * (double)a[i * n + k]); for (k = l; k < n; k++) a[j * n + k] += (float)(s * rv1[k]); } } for (k = l; k < n; k++) a[i * n + k] = (float)((double)a[i * n + k]*scale); } } anorm = MAX(anorm, (fabs((double)w[i]) + fabs(rv1[i]))); } /* accumulate the right-hand transformation */ for (i = n - 1; i >= 0; i--) { if (i < n - 1) { if (g) { for (j = l; j < n; j++) v[j * n + i] = (float)(((double)a[i * n + j] / (double)a[i * n + l]) / g); /* double division to avoid underflow */ for (j = l; j < n; j++) { for (s = 0.0, k = l; k < n; k++) s += ((double)a[i * n + k] * (double)v[k * n + j]); for (k = l; k < n; k++) v[k * n + j] += (float)(s * (double)v[k * n + i]); } } for (j = l; j < n; j++) v[i * n + j] = v[j * n + i] = 0.0; } v[i * n + i] = 1.0; g = rv1[i]; l = i; } /* accumulate the left-hand transformation */ for (i = n - 1; i >= 0; i--) { l = i + 1; g = (double)w[i]; if (i < n - 1) for (j = l; j < n; j++) a[i * n + j] = 0.0; if (g) { g = 1.0 / g; if (i != n - 1) { for (j = l; j < n; j++) { for (s = 0.0, k = l; k < m; k++) s += ((double)a[k * n + i] * (double)a[k * n + j]); f = (s / (double)a[i * n + i]) * g; for (k = i; k < m; k++) a[k * n + j] += (float)(f * (double)a[k * n + i]); } } for (j = i; j < m; j++) a[j * n + i] = (float)((double)a[j * n + i]*g); } else { for (j = i; j < m; j++) a[j * n + i] = 0.0; } ++a[i * n + i]; } /* diagonalize the bidiagonal form */ for (k = n - 1; k >= 0; k--) { /* loop over singular values */ for (its = 0; its < 30; its++) { /* loop over allowed iterations */ flag = 1; for (l = k; l >= 0; l--) { /* test for splitting */ nm = l - 1; if (fabs(rv1[l]) + anorm == anorm) { flag = 0; break; } if (fabs((double)w[nm]) + anorm == anorm) break; } if (flag) { c = 0.0; s = 1.0; for (i = l; i <= k; i++) { f = s * rv1[i]; if (fabs(f) + anorm != anorm) { g = (double)w[i]; h = PYTHAG(f, g); w[i] = (float)h; h = 1.0 / h; c = g * h; s = (- f * h); for (j = 0; j < m; j++) { y = (double)a[j * n + nm]; z = (double)a[j * n + i]; a[j * n + nm] = (float)(y * c + z * s); a[j * n + i] = (float)(z * c - y * s); } } } } z = (double)w[k]; if (l == k) { /* convergence */ if (z < 0.0) { /* make singular value nonnegative */ w[k] = (float)(-z); for (j = 0; j < n; j++) v[j * n + k] = (-v[j * n + k]); } break; } if (its >= 30) { free((void*) rv1); fprintf(stderr, "No convergence after 30,000! iterations \n"); return(0); } /* shift from bottom 2 x 2 minor */ x = (double)w[l]; nm = k - 1; y = (double)w[nm]; g = rv1[nm]; h = rv1[k]; f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0 * h * y); g = PYTHAG(f, 1.0); f = ((x - z) * (x + z) + h * ((y / (f + SIGN(g, f))) - h)) / x; /* next QR transformation */ c = s = 1.0; for (j = l; j <= nm; j++) { i = j + 1; g = rv1[i]; y = (double)w[i]; h = s * g; g = c * g; z = PYTHAG(f, h); rv1[j] = z; c = f / z; s = h / z; f = x * c + g * s; g = g * c - x * s; h = y * s; y = y * c; for (jj = 0; jj < n; jj++) { x = (double)v[jj * n + j]; z = (double)v[jj * n + i]; v[jj * n + j] = (float)(x * c + z * s); v[jj * n + i] = (float)(z * c - x * s); } z = PYTHAG(f, h); w[j] = (float)z; if (z) { z = 1.0 / z; c = f * z; s = h * z; } f = (c * g) + (s * y); x = (c * y) - (s * g); for (jj = 0; jj < m; jj++) { y = (double)a[jj * n + j]; z = (double)a[jj * n + i]; a[jj * n + j] = (float)(y * c + z * s); a[jj * n + i] = (float)(z * c - y * s); } } rv1[l] = 0.0; rv1[k] = f; w[k] = (float)x; } } free((void*) rv1); return(1); }
int svdcmp(int m, int n, double **a, double *w, double **v) //Given a matrix a[1..m][1..n], this routine computes its singular value //decomposition, A = U.W.VT. The matrix U replaces a on output. The diagonal //matrix of singular values W is output as a vector w[1..n]. The matrix V (not //the transpose VT) is output as v[1..n][1..n]. { int flag, za, zb, i, its, j, jj, k, l, nm; double c, f, h, s, x, y, z; double anorm = 0.0, g = 0.0, scale = 0.0; double *rv1,**rv2; double *sum; sum = (double*)calloc(n,sizeof(double)); FILE *ft=fopen("U.txt","w"); FILE *fs=fopen("VT.txt","w"); FILE *fu=fopen("W.txt","w"); if (m < n) { fprintf(stderr, "#rows must be > #cols \n"); return(0); } rv1 = (double *)malloc((unsigned int) n*sizeof(double)); // printf("\n*"); // getch(); /* Householder reduction to bidiagonal form */ for (i = 0; i < n; i++) { /* left-hand reduction */ l = i + 1; rv1[i] = scale * g; g = s = scale = 0.0; if (i < m) { for (k = i; k < m; k++) scale += fabs((double)a[k][i]); if (scale) { for (k = i; k < m; k++) { a[k][i] = (double)((double)a[k][i]/scale); s += ((double)a[k][i] * (double)a[k][i]); } f = (double)a[i][i]; g = -SIGN(sqrt(s), f); h = f * g - s; a[i][i] = (double)(f - g); if (i != n - 1) { for (j = l; j < n; j++) { for (s = 0.0, k = i; k < m; k++) s += ((double)a[k][i] * (double)a[k][j]); f = s / h; for (k = i; k < m; k++) a[k][j] += (double)(f * (double)a[k][i]); } } for (k = i; k < m; k++) a[k][i] = (double)((double)a[k][i]*scale); } } w[i] = (double)(scale * g); /* right-hand reduction */ g = s = scale = 0.0; if (i < m && i != n - 1) { for (k = l; k < n; k++) scale += fabs((double)a[i][k]); if (scale) { for (k = l; k < n; k++) { a[i][k] = (double)((double)a[i][k]/scale); s += ((double)a[i][k] * (double)a[i][k]); } f = (double)a[i][l]; g = -SIGN(sqrt(s), f); h = f * g - s; a[i][l] = (double)(f - g); for (k = l; k < n; k++) rv1[k] = (double)a[i][k] / h; if (i != m - 1) { for (j = l; j < m; j++) { for (s = 0.0, k = l; k < n; k++) s += ((double)a[j][k] * (double)a[i][k]); for (k = l; k < n; k++) a[j][k] += (double)(s * rv1[k]); } } for (k = l; k < n; k++) a[i][k] = (double)((double)a[i][k]*scale); } } anorm = MAX(anorm, (fabs((double)w[i]) + fabs(rv1[i]))); } // printf("\n*"); // getch(); /* accumulate the right-hand transformation */ for (i = n - 1; i >= 0; --i) { if (i < n - 1) { if (g) { for (j = l; j < n; j++) v[j][i] = (double)(((double)a[i][j] / (double)a[i][l]) / g); /* double division to avoid underflow */ for (j = l; j < n; j++) { for (s = 0.0, k = l; k < n; k++) s += ((double)a[i][k] * (double)v[k][j]); for (k = l; k < n; k++) v[k][j] += (double)(s * (double)v[k][i]); } } for (j = l; j < n; j++) v[i][j] = v[j][i] = 0.0; } v[i][i] = 1.0; g = rv1[i]; l = i; } // printf("\n*"); // getch(); /* accumulate the left-hand transformation */ for (i = n - 1; i >= 0; i--) { l = i + 1; g = (double)w[i]; if (i < n - 1) for (j = l; j < n; j++) a[i][j] = 0.0; if (g) { g = 1.0 / g; if (i != n - 1) { for (j = l; j < n; j++) { for (s = 0.0, k = l; k < m; k++) s += ((double)a[k][i] * (double)a[k][j]); f = (s / (double)a[i][i]) * g; for (k = i; k < m; k++) a[k][j] += (double)(f * (double)a[k][i]); } } for (j = i; j < m; j++) a[j][i] = (double)((double)a[j][i]*g); } else { for (j = i; j < m; j++) a[j][i] = 0.0; } ++a[i][i]; } // printf("\n*"); // getch(); /* diagonalize the bidiagonal form */ for (k = n - 1; k >= 0; k--) { /* loop over singular values */ for (its = 0; its < 30; its++) { /* loop over allowed iterations */ flag = 1; for (l = k; l >= 0; l--) { /* test for splitting */ nm = l - 1; if (fabs(rv1[l]) + anorm == anorm) { flag = 0; break; } if (fabs((double)w[nm]) + anorm == anorm) break; } if (flag) { c = 0.0; s = 1.0; for (i = l; i <= k; i++) { f = s * rv1[i]; if (fabs(f) + anorm != anorm) { g = (double)w[i]; h = PYTHAG(f, g); w[i] = (double)h; h = 1.0 / h; c = g * h; s = (- f * h); for (j = 0; j < m; j++) { y = (double)a[j][nm]; z = (double)a[j][i]; a[j][nm] = (double)(y * c + z * s); a[j][i] = (double)(z * c - y * s); } } } } z = (double)w[k]; if (l == k) { /* convergence */ if (z < 0.0) { /* make singular value nonnegative */ w[k] = (double)(-z); for (j = 0; j < n; j++) v[j][k] = (-v[j][k]); } break; } if (its >= 30) { free((void*) rv1); fprintf(stderr, "No convergence after 30,000! iterations \n"); return(0); } /* shift from bottom 2 x 2 minor */ x = (double)w[l]; nm = k - 1; y = (double)w[nm]; g = rv1[nm]; h = rv1[k]; f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0 * h * y); g = PYTHAG(f, 1.0); f = ((x - z) * (x + z) + h * ((y / (f + SIGN(g, f))) - h)) / x; /* next QR transformation */ c = s = 1.0; for (j = l; j <= nm; j++) { i = j + 1; g = rv1[i]; y = (double)w[i]; h = s * g; g = c * g; z = PYTHAG(f, h); rv1[j] = z; c = f / z; s = h / z; f = x * c + g * s; g = g * c - x * s; h = y * s; y = y * c; for (jj = 0; jj < n; jj++) { x = (double)v[jj][j]; z = (double)v[jj][i]; v[jj][j] = (double)(x * c + z * s); v[jj][i] = (double)(z * c - x * s); } z = PYTHAG(f, h); w[j] = (double)z; if (z) { z = 1.0 / z; c = f * z; s = h * z; } f = (c * g) + (s * y); x = (c * y) - (s * g); for (jj = 0; jj < m; jj++) { y = (double)a[jj][j]; z = (double)a[jj][i]; a[jj][j] = (double)(y * c + z * s); a[jj][i] = (double)(z * c - y * s); } } rv1[l] = 0.0; rv1[k] = f; w[k] = (double)x; } } // printf("\n*"); // getch(); rv2 = (double**)calloc(n,sizeof(double*)); for(i=0;i<n;i++) rv2[i]=(double*)calloc(n,sizeof(double)); for(za=0;za<n;++za){ //transposition for(zb=0;zb<n;++zb){ if(rv2[za][zb]==0 && rv2[zb][za]==0 && za!=zb) { z=v[za][zb]; v[za][zb]=v[zb][za]; v[zb][za]=z; rv2[za][zb]=1; } v[za][zb]=fabs(v[za][zb]); } } for(za=0;za<n;++za){ for(zb=0;zb<n;++zb){ sum[zb]+=v[za][zb]; fprintf(fs,"\t%f",v[za][zb]);} fprintf(fs,"\n"); } fclose(fs); FILE *fv = fopen("Values.txt","a"); for(za=0;za<n;za++)fprintf(fv,"%f ",sum[za]); fclose(fv); for(za=0;za<m;za++){ for(zb=0;zb<n;zb++){ a[za][zb]=fabs(a[za][zb]); fprintf(ft,"\t%f",a[za][zb]); } fprintf(ft,"\n"); } fclose(ft); for(za=0;za<n;++za){ fprintf(fu,"\n%f",w[za]); } fclose(fu); free((void*) rv1); return(1); }
int _mossNRsvdcmp(register double **a, const int m, const int n, double w[], register double **v) { int flag,i,its,j,jj,k,l,nm; double anorm,c,f,g,h,s,scale,x,y,z, rv11[n+1]; register double *rv1 = rv11; g = scale = anorm = 0.0; for (i=1;i<=n;i++) { l=i+1; rv1[i]=scale*g; g=s=scale=0.0; if (i <= m) { for (k=i;k<=m;k++) scale += fabs(a[k][i]); if (scale) { for (k=i; k<=m; k++) { a[k][i] /= scale; s += a[k][i]*a[k][i]; } f = a[i][i]; g = -SIGN(sqrt(s), f); h=f*g-s; a[i][i]=f-g; for (j=l;j<=n;j++) { for (s=0.0,k=i;k<=m;k++) s += a[k][i]*a[k][j]; f=s/h; for (k=i;k<=m;k++) a[k][j] += f*a[k][i]; } for (k=i;k<=m;k++) a[k][i] *= scale; } } w[i]=scale *g; g=s=scale=0.0; if (i <= m && i != n) { for (k=l;k<=n;k++) scale += fabs(a[i][k]); if (scale) { for (k=l;k<=n;k++) { a[i][k] /= scale; s += a[i][k]*a[i][k]; } f=a[i][l]; g = -SIGN(sqrt(s),f); h=f*g-s; a[i][l]=f-g; for (k=l;k<=n;k++) rv1[k]=a[i][k]/h; for (j=l;j<=m;j++) { for (s=0.0,k=l;k<=n;k++) s += a[j][k]*a[i][k]; for (k=l;k<=n;k++) a[j][k] += s*rv1[k]; } for (k=l;k<=n;k++) a[i][k] *= scale; } } anorm=FMAX(anorm,(fabs(w[i])+fabs(rv1[i]))); } for (i=n;i>=1;i--) { if (i < n) { if (g) { for (j=l;j<=n;j++) v[j][i]=(a[i][j]/a[i][l])/g; for (j=l;j<=n;j++) { for (s=0.0,k=l;k<=n;k++) s += a[i][k]*v[k][j]; for (k=l;k<=n;k++) v[k][j] += s*v[k][i]; } } for (j=l;j<=n;j++) v[i][j]=v[j][i]=0.0; } v[i][i]=1.0; g=rv1[i]; l=i; } for (i = IMIN(m,n); i>=1; i--) { l=i+1; g=w[i]; for (j=l;j<=n;j++) a[i][j]=0.0; if (g) { g=1.0/g; for (j=l;j<=n;j++) { for (s=0.0,k=l;k<=m;k++) s += a[k][i]*a[k][j]; f = (s/a[i][i])*g; for (k=i;k<=m;k++) a[k][j] += f*a[k][i]; } for (j=i;j<=m;j++) a[j][i] *= g; } else for (j=i;j<=m;j++) a[j][i]=0.0; ++a[i][i]; } for (k=n;k>=1;k--) { for (its=1;its<=30;its++) { flag=1; for (l=k;l>=1;l--) { nm=l-1; if ((double)(fabs(rv1[l])+anorm) == anorm) { flag=0; break; } if ((double)(fabs(w[nm])+anorm) == anorm) break; } if (flag) { c=0.0; s=1.0; for (i=l;i<=k;i++) { f=s*rv1[i]; rv1[i]=c*rv1[i]; if ((double)(fabs(f)+anorm) == anorm) break; g=w[i]; h=PYTHAG(f,g); w[i]=h; h=1.0/h; c=g*h; s = -f*h; for (j=1;j<=m;j++) { y=a[j][nm]; z=a[j][i]; a[j][nm]=y*c+z*s; a[j][i]=z*c-y*s; } } } z=w[k]; if (l == k) { if (z < 0.0) { w[k] = -z; for (j=1;j<=n;j++) v[j][k] = -v[j][k]; } break; } if (its == 30) { //sprintf(err, "%s: no convergence in 30 svdcmp iterations", me); //biffAdd(MOSS, err); return 1; } x=w[l]; nm=k-1; y=w[nm]; g=rv1[nm]; h=rv1[k]; f=((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y); g=PYTHAG(f,1.0); f=((x-z)*(x+z)+h*((y/(f+SIGN(g,f)))-h))/x; c=s=1.0; for (j=l;j<=nm;j++) { i=j+1; g=rv1[i]; y=w[i]; h=s*g; g=c*g; z=PYTHAG(f,h); rv1[j]=z; c=f/z; s=h/z; f=x*c+g*s; g = g*c-x*s; h=y*s; y *= c; for (jj=1;jj<=n;jj++) { x=v[jj][j]; z=v[jj][i]; v[jj][j]=x*c+z*s; v[jj][i]=z*c-x*s; } z=PYTHAG(f,h); w[j]=z; if (z) { z=1.0/z; c=f*z; s=h*z; } f=c*g+s*y; x=c*y-s*g; for (jj=1;jj<=m;jj++) { y=a[jj][j]; z=a[jj][i]; a[jj][j]=y*c+z*s; a[jj][i]=z*c-y*s; } } rv1[l]=0.0; rv1[k]=f; w[k]=x; } } //free(rv1); return 0; }
void svdcmp(double** a, int m, int n, double* w, double** v) { int flag,i,its,j,jj,k,l,nm; double c,f,h,s,x,y,z; double anorm=0.0,g=0.0,scale=0.0; double *rv1; void nrerror(); if (m < n) ntrerror("SVDCMP: You must augment A with extra zero rows"); rv1=allocVect(n); for (i=1;i<=n;i++) { l=i+1; rv1[i]=scale*g; g=s=scale=0.0; if (i <= m) { for (k=i;k<=m;k++) scale += fabs(a[k][i]); if (scale) { for (k=i;k<=m;k++) { a[k][i] /= scale; s += a[k][i]*a[k][i]; } f=a[i][i]; g = -SIGN(sqrt(s),f); h=f*g-s; a[i][i]=f-g; if (i != n) { for (j=l;j<=n;j++) { for (s=0.0,k=i;k<=m;k++) s += a[k][i]*a[k][j]; f=s/h; for (k=i;k<=m;k++) a[k][j] += f*a[k][i]; } } for (k=i;k<=m;k++) a[k][i] *= scale; } } w[i]=scale*g; g=s=scale=0.0; if (i <= m && i != n) { for (k=l;k<=n;k++) scale += fabs(a[i][k]); if (scale) { for (k=l;k<=n;k++) { a[i][k] /= scale; s += a[i][k]*a[i][k]; } f=a[i][l]; g = -SIGN(sqrt(s),f); h=f*g-s; a[i][l]=f-g; for (k=l;k<=n;k++) rv1[k]=a[i][k]/h; if (i != m) { for (j=l;j<=m;j++) { for (s=0.0,k=l;k<=n;k++) s += a[j][k]*a[i][k]; for (k=l;k<=n;k++) a[j][k] += s*rv1[k]; } } for (k=l;k<=n;k++) a[i][k] *= scale; } } anorm=MAX(anorm,(fabs(w[i])+fabs(rv1[i]))); } for (i=n;i>=1;i--) { if (i < n) { if (g) { for (j=l;j<=n;j++) v[j][i]=(a[i][j]/a[i][l])/g; for (j=l;j<=n;j++) { for (s=0.0,k=l;k<=n;k++) s += a[i][k]*v[k][j]; for (k=l;k<=n;k++) v[k][j] += s*v[k][i]; } } for (j=l;j<=n;j++) v[i][j]=v[j][i]=0.0; } v[i][i]=1.0; g=rv1[i]; l=i; } for (i=n;i>=1;i--) { l=i+1; g=w[i]; if (i < n) for (j=l;j<=n;j++) a[i][j]=0.0; if (g) { g=1.0/g; if (i != n) { for (j=l;j<=n;j++) { for (s=0.0,k=l;k<=m;k++) s += a[k][i]*a[k][j]; f=(s/a[i][i])*g; for (k=i;k<=m;k++) a[k][j] += f*a[k][i]; } } for (j=i;j<=m;j++) a[j][i] *= g; } else { for (j=i;j<=m;j++) a[j][i]=0.0; } ++a[i][i]; } for (k=n;k>=1;k--) { for (its=1;its<=30;its++) { flag=1; for (l=k;l>=1;l--) { nm=l-1; if (fabs(rv1[l])+anorm == anorm) { flag=0; break; } if (fabs(w[nm])+anorm == anorm) break; } if (flag) { c=0.0; s=1.0; for (i=l;i<=k;i++) { f=s*rv1[i]; if (fabs(f)+anorm != anorm) { g=w[i]; h=PYTHAG(f,g); w[i]=h; h=1.0/h; c=g*h; s=(-f*h); for (j=1;j<=m;j++) { y=a[j][nm]; z=a[j][i]; a[j][nm]=y*c+z*s; a[j][i]=z*c-y*s; } } } } z=w[k]; if (l == k) { if (z < 0.0) { w[k] = -z; for (j=1;j<=n;j++) v[j][k]=(-v[j][k]); } break; } if (its == 30) ntrerror("No convergence in 30 SVDCMP iterations"); x=w[l]; nm=k-1; y=w[nm]; g=rv1[nm]; h=rv1[k]; f=((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y); g=PYTHAG(f,1.0); f=((x-z)*(x+z)+h*((y/(f+SIGN(g,f)))-h))/x; c=s=1.0; for (j=l;j<=nm;j++) { i=j+1; g=rv1[i]; y=w[i]; h=s*g; g=c*g; z=PYTHAG(f,h); rv1[j]=z; c=f/z; s=h/z; f=x*c+g*s; g=g*c-x*s; h=y*s; y=y*c; for (jj=1;jj<=n;jj++) { x=v[jj][j]; z=v[jj][i]; v[jj][j]=x*c+z*s; v[jj][i]=z*c-x*s; } z=PYTHAG(f,h); w[j]=z; if (z) { z=1.0/z; c=f*z; s=h*z; } f=(c*g)+(s*y); x=(c*y)-(s*g); for (jj=1;jj<=m;jj++) { y=a[jj][j]; z=a[jj][i]; a[jj][j]=y*c+z*s; a[jj][i]=z*c-y*s; } } rv1[l]=0.0; rv1[k]=f; w[k]=x; } } freeVect(rv1); }
void eig_tridiag(double *d, double *a, size_t n, int matq, double *Q, size_t *rc) { size_t m, l, i, k; int iter; double s, r, p, g, f, dd, c, b; for (i = 1; i < n; i++) a[i - 1] = a[i]; a[n - 1] = 0.0; for (l = 0; l < n; l++) { iter = 0; do { for (m = l; m < n - 1; m++) { dd = fabs(d[m]) + fabs(d[m + 1]); if ((double)(fabs(a[m]) + dd) == dd) break; } if (m != l) { if (iter++ == 30) { *rc = l+1; return; /* Too many iterations */ } g = (d[l + 1] - d[l]) / (2.0 * a[l]); r = PYTHAG(g, 1.0); g = d[m] - d[l] + a[l] / (g + (g >= 0.0 ? fabs(r) : -fabs(r))); s = c = 1.0; p = 0.0; for (i = m; i > l; i--) { f = s * a[i - 1]; b = c * a[i - 1]; a[i] = (r = PYTHAG(f, g)); if (r == 0.0) { d[i] -= p; a[m] = 0.0; break; } s = f / r; c = g / r; g = d[i] - p; r = (d[i - 1] - g) * s + 2.0 * c * b; d[i] = g + (p = s * r); g = c * r - b; if (matq) for (k = 0; k < n; k++) { f = Q[k*n + i]; Q[k*n + i] = s * Q[k*n + i - 1] + c * f; Q[k*n + i - 1] = c * Q[k*n + i - 1] - s * f; } } if (r == 0.0 && i > l) continue; d[l] -= p; a[l] = g; a[m] = 0.0; } } while (m != l); } *rc = 0; }
int svdcmp( double **a, int m,int n, double *w,double **v) { int flag,i,its,j,jj,k,ii=0,nm=0; SVD_FLOAT c,f,h,s,x,y,z; SVD_FLOAT anorm=0.0,g=0.0,scale=0.0; if (m < n) return -1; // must augment A with extra zero rows assert(n==3); SVD_FLOAT rv1[3]; // was: rv1=G_alloc_vector(n); n--; m--; for (i=0;i<=n;i++) { ii=i+1; rv1[i]=scale*g; g=s=scale=0.0; if (i <= m) { for (k=i;k<=m;k++) scale += (SVD_FLOAT)fabs(a[k][i]); if (scale) { for (k=i;k<=m;k++) { a[k][i] /= (SVD_FLOAT)(scale); s += a[k][i]*a[k][i]; } f=a[i][i]; g = -SIGN(sqrt(s),f); h=f*g-s; a[i][i]=(SVD_FLOAT)(f-g); if (i != n) { for (j=ii;j<=n;j++) { for (s=0.0,k=i;k<=m;k++) s += a[k][i]*a[k][j]; f=s/h; for (k=i;k<=m;k++) a[k][j] += (SVD_FLOAT)(f)*a[k][i]; } } for (k=i;k<=m;k++) a[k][i] *= (SVD_FLOAT)(scale); } } w[i]=scale*g; g=s=scale=0.0; if (i <= m && i != n) { for (k=ii;k<=n;k++) scale += fabs(a[i][k]); if (scale) { for (k=ii;k<=n;k++) { a[i][k] /= scale; s += a[i][k]*a[i][k]; } f=a[i][ii]; g = -SIGN(sqrt(s),f); h=f*g-s; a[i][ii]=f-g; for (k=ii;k<=n;k++) rv1[k]=a[i][k]/h; if (i != m) { for (j=ii;j<=m;j++) { for (s=0.0,k=ii;k<=n;k++) s += a[j][k]*a[i][k]; for (k=ii;k<=n;k++) a[j][k] += s*rv1[k]; } } for (k=ii;k<=n;k++) a[i][k] *= scale; } } anorm=MAX(anorm,(fabs(w[i])+fabs(rv1[i]))); } for (i=n;i>=0;i--) { if (i < n) { if (g) { for (j=ii;j<=n;j++) v[j][i]=(a[i][j]/a[i][ii])/g; for (j=ii;j<=n;j++) { for (s=0.0,k=ii;k<=n;k++) s += a[i][k]*v[k][j]; for (k=ii;k<=n;k++) v[k][j] += s*v[k][i]; } } for (j=ii;j<=n;j++) v[i][j]=v[j][i]=0.0; } v[i][i]=1.0; g=rv1[i]; ii=i; } for (i=n;i>=0;i--) { ii=i+1; g=w[i]; if (i < n) for (j=ii;j<=n;j++) a[i][j]=0.0; if (g) { g=SVD_FLOAT(1.0)/g; if (i != n) { for (j=ii;j<=n;j++) { for (s=0.0,k=ii;k<=m;k++) s += a[k][i]*a[k][j]; f=(s/a[i][i])*g; for (k=i;k<=m;k++) a[k][j] += f*a[k][i]; } } for (j=i;j<=m;j++) a[j][i] *= g; } else { for (j=i;j<=m;j++) a[j][i]=0.0; } ++a[i][i]; } for (k=n;k>=0;k--) { for (its=1;its<=30;its++) { flag=1; for (ii=k;ii>=0;ii--) { nm=ii-1; if (fabs(rv1[ii])+anorm == anorm) { flag=0; break; } if (fabs(w[nm])+anorm == anorm) break; } if (flag) { c=0.0; s=1.0; for (i=ii;i<=k;i++) { f=s*rv1[i]; if (fabs(f)+anorm != anorm) { g=w[i]; h=PYTHAG(f,g); w[i]=h; h=SVD_FLOAT(1.0)/h; c=g*h; s=(-f*h); for (j=0;j<=m;j++) { y=a[j][nm]; z=a[j][i]; a[j][nm]=y*c+z*s; a[j][i]=z*c-y*s; } } } } z=w[k]; if (ii == k) { if (z < 0.0) { w[k] = -z; for (j=0;j<=n;j++) v[j][k]=(-v[j][k]); } break; } if (its == 30) return -2; /*No convergence in 30 SVDCMP iterations*/ x=w[ii]; nm=k-1; y=w[nm]; g=rv1[nm]; h=rv1[k]; f=((y-z)*(y+z)+(g-h)*(g+h))/(SVD_FLOAT(2.0)*h*y); g=PYTHAG(f,SVD_FLOAT(1.0)); f=((x-z)*(x+z)+h*((y/(f+SIGN(g,f)))-h))/x; c=s=SVD_FLOAT(1.0); for (j=ii;j<=nm;j++) { i=j+1; g=rv1[i]; y=w[i]; h=s*g; g=c*g; z=PYTHAG(f,h); rv1[j]=z; c=f/z; s=h/z; f=x*c+g*s; g=g*c-x*s; h=y*s; y=y*c; for (jj=0;jj<=n;jj++) { x=v[jj][j]; z=v[jj][i]; v[jj][j]=x*c+z*s; v[jj][i]=z*c-x*s; } z=PYTHAG(f,h); w[j]=z; if (z) { z=SVD_FLOAT(1.0)/z; c=f*z; s=h*z; } f=(c*g)+(s*y); x=(c*y)-(s*g); for (jj=0;jj<=m;jj++) { y=a[jj][j]; z=a[jj][i]; a[jj][j]=y*c+z*s; a[jj][i]=z*c-y*s; } } rv1[ii]=SVD_FLOAT(0.0); rv1[k]=f; w[k]=x; } } //G_free_vector(rv1); // no longer used, rv1 is now on stack return 0; }
/* Given a matrix a[m][n], this routine computes its singular value decomposition, A = U*W*V^{T}. The matrix U replaces a on output. The diagonal matrix of singular values W is output as a vector w[n]. The matrix V (not the transpose V^{T}) is output as v[n][n]. m must be greater or equal to n; if it is smaller, then a should be filled up to square with zero rows. */ void svdcmp(double* a[], int m, int n, double w[], double* v[]) { int flag, i, its, j, jj, k, l, nm; double c, f, h, s, x, y, z; double anorm = 0.0, g = 0.0, scale = 0.0; if (m < n) error("SVDCMP: Matrix A must be augmented with extra rows of zeros."); double* rv1 = new double [n]; /* Householder reduction to bidiagonal form. */ for (i = 0; i < n; i++) { l = i + 1; rv1[i] = scale*g; g = s = scale = 0.0; if (i < m) { for (k = i; k < m; k++) scale += fabs(a[k][i]); if (scale) { for (k = i; k < m; k++) { a[k][i] /= scale; s += a[k][i]*a[k][i]; }; f = a[i][i]; g = -SIGN(sqrt(s), f); h = f*g - s; a[i][i] = f - g; if (i != n - 1) { for (j = l; j < n; j++) { for (s = 0.0, k = i; k < m; k++) s += a[k][i]*a[k][j]; f = s/h; for ( k = i; k < m; k++) a[k][j] += f*a[k][i]; }; }; for (k = i; k < m; k++) a[k][i] *= scale; }; }; w[i] = scale*g; g = s= scale = 0.0; if (i < m && i != n - 1) { for (k = l; k < n; k++) scale += fabs(a[i][k]); if (scale) { for (k = l; k < n; k++) { a[i][k] /= scale; s += a[i][k]*a[i][k]; }; f = a[i][l]; g = -SIGN(sqrt(s), f); h = f*g - s; a[i][l] = f - g; for (k = l; k < n; k++) rv1[k] = a[i][k]/h; if (i != m - 1) { for (j = l; j < m; j++) { for (s = 0.0, k = l; k < n; k++) s += a[j][k]*a[i][k]; for (k = l; k < n; k++) a[j][k] += s*rv1[k]; }; }; for (k = l; k < n; k++) a[i][k] *= scale; }; }; anorm = MAX(anorm, (fabs(w[i]) + fabs(rv1[i]))); }; /* Accumulation of right-hand transformations. */ for (i = n - 1; 0 <= i; i--) { if (i < n - 1) { if (g) { for (j = l; j < n; j++) v[j][i] = (a[i][j]/a[i][l])/g; /* Double division to avoid possible underflow: */ for (j = l; j < n; j++) { for (s = 0.0, k = l; k < n; k++) s += a[i][k]*v[k][j]; for (k = l; k < n; k++) v[k][j] += s*v[k][i]; }; }; for (j = l; j < n; j++) v[i][j] = v[j][i] = 0.0; }; v[i][i] = 1.0; g = rv1[i]; l = i; }; /* Accumulation of left-hand transformations. */ for (i = n - 1; 0 <= i; i--) { l = i + 1; g = w[i]; if (i < n - 1) for (j = l; j < n; j++) a[i][j] = 0.0; if (g) { g = 1.0/g; if (i != n - 1) { for (j = l; j < n; j++) { for (s = 0.0, k = l; k < m; k++) s += a[k][i]*a[k][j]; f = (s/a[i][i])*g; for (k = i; k < m; k++) a[k][j] += f*a[k][i]; }; }; for (j = i; j < m; j++) a[j][i] *= g; } else for (j = i; j < m; j++) a[j][i] = 0.0; ++a[i][i]; }; /* Diagonalization of the bidiagonal form. */ for (k = n - 1; 0 <= k; k--) /* Loop over singular values. */ { for (its = 0; its < 30; its++) /* Loop over allowed iterations.*/ { flag = 1; for (l = k; 0 <= l; l--) /* Test for splitting: */ { nm = l - 1; /* Note that rv1[0] is always zero.*/ if (fabs(rv1[l]) + anorm == anorm) { flag = 0; break; }; if (fabs(w[nm]) + anorm == anorm) break; }; if (flag) { c = 0.0; /* Cancellation of rv1[l], if l>0:*/ s = 1.0; for (i = l; i <= k; i++) { f = s*rv1[i]; if (fabs(f) + anorm != anorm) { g = w[i]; h = PYTHAG(f, g); w[i] = h; h = 1.0/h; c = g*h; s = (-f*h); for (j = 0; j < m; j++) { y = a[j][nm]; z = a[j][i]; a[j][nm] = y*c + z*s; a[j][i] = z*c - y*s; }; }; }; }; z = w[k]; if (l == k) /* Convergence. */ { if (z < 0.0) /* Singular value is made non-negative. */ { w[k] = -z; for (j = 0; j < n; j++) v[j][k] = (-v[j][k]); }; break; }; if (its == 29) error("No convergence in 30 SVDCMP iterations."); x = w[l]; /* Shift from bottom 2-by-2 minor. */ nm = k - 1; y = w[nm]; g = rv1[nm]; h = rv1[k]; f = ((y - z)*(y + z) + (g - h)*(g + h))/(2.0*h*y); g = PYTHAG(f, 1.0); f = ((x - z)*(x + z) + h*((y/(f + SIGN(g, f))) - h))/x; /* Next QR transformation: */ c = s = 1.0; for (j = l; j <= nm; j++) { i = j + 1; g = rv1[i]; y = w[i]; h = s*g; g = c*g; z = PYTHAG(f, h); rv1[j] = z; c = f/z; s = h/z; f = x*c + g*s; g = g*c - x*s; h = y*s; y = y*c; for (jj = 0; jj < n; jj++) { x = v[jj][j]; z = v[jj][i]; v[jj][j] = x*c + z*s; v[jj][i] = z*c - x*s; }; z = PYTHAG(f, h); w[j] = z; /* Rotation can be arbitrary if z = 0. */ if (z) { z = 1.0/z; c = f*z; s = h*z; }; f = (c*g) + (s*y); x = (c*y) - (s*g); for (jj = 0; jj < m; jj++) { y = a[jj][j]; z = a[jj][i]; a[jj][j] = y*c + z*s; a[jj][i] = z*c - y*s; }; }; rv1[l] = 0.0; rv1[k] = f; w[k] = x; }; }; delete rv1; }
int DL_largematrix::svdcmp(){ // calculates an singular value decompisition of this matrix: // A=U w V^T // where U is nrrows x nrcols and has orthonormal columns (stored in a) // where w is nrcols x nrcols diagonal with the singular values // where V is nrcols x nrcols and has orthonormal columns // pre: nrrows>=nrcols && rep==full // returns te number of singular values after postprocessing w to // nullify too small elements in w int flag,i,its,j,jj,k,l,nm; DL_Scalar c,f,h,s,x,y,z; DL_Scalar anorm=0.0,g=0.0,scale=0.0; DL_Scalar *rv1; if (nrrows < nrcols) { DL_dsystem->get_companion()->Msg("Error: DL_largematrix::svdcmp: more columns than rows!\n"); return 1; } rep=svdcmpd; if (!u) u=new DL_Scalar[nrelem]; if (!w) w=new DL_Scalar[nrcols]; if (!v) v=new DL_Scalar[nrcols*nrcols]; rv1=new DL_Scalar[nrcols]; for (i=0;i<nrelem;i++) u[i]=a[i]; for (i=0;i<nrcols;i++) { l=i+1; rv1[i]=scale*g; g=s=scale=0.0; if (i < nrrows) { register int k_nrcols_i=i*(nrcols+1); for (k=i;k<nrrows;k++) { scale += fabs(u[k_nrcols_i]); k_nrcols_i+=nrcols; } if (scale) { k_nrcols_i=i*(nrcols+1); for (k=i;k<nrrows;k++) { u[k_nrcols_i] /= scale; s += u[k_nrcols_i]*u[k_nrcols_i]; k_nrcols_i+=nrcols; } f=u[i*nrcols+i]; g = -SIGN(sqrt(s),f); h=f*g-s; u[i*nrcols+i]=f-g; if (i != nrcols-1) { register int j_i=1; // j_i==j-i; for (j=l;j<nrcols;j++) { k_nrcols_i=i*(nrcols+1); for (s=0.0,k=i;k<nrrows;k++) { s += u[k_nrcols_i]*u[k_nrcols_i+j_i]; k_nrcols_i+=nrcols; } f=s/h; k_nrcols_i=i*(nrcols+1); for (k=i;k<nrrows;k++) { u[k_nrcols_i+j_i] += f*u[k_nrcols_i]; k_nrcols_i+=nrcols; } j_i++; } } k_nrcols_i=i*(nrcols+1); for (k=i;k<nrrows;k++) { u[k_nrcols_i] *= scale; k_nrcols_i+=nrcols; } } } w[i]=scale*g; g=s=scale=0.0; if ((i < nrrows) && (l != nrcols)) { register int i_nrcols=i*nrcols; for (k=l;k<nrcols;k++) scale += fabs(u[i_nrcols+k]); if (scale) { for (k=l;k<nrcols;k++) { u[i_nrcols+k] /= scale; s += u[i_nrcols+k]*u[i_nrcols+k]; } f=u[i_nrcols+l]; g = -SIGN(sqrt(s),f); h=f*g-s; u[i_nrcols+l]=f-g; for (k=l;k<nrcols;k++) rv1[k]=u[i_nrcols+k]/h; if (l != nrrows) { register int j_nrcols=l*nrcols; for (j=l;j<nrrows;j++) { for (s=0.0,k=l;k<nrcols;k++) s += u[j_nrcols+k]*u[i_nrcols+k]; for (k=l;k<nrcols;k++) u[j_nrcols+k] += s*rv1[k]; j_nrcols+=nrcols; } } for (k=l;k<nrcols;k++) u[i_nrcols+k] *= scale; } } anorm=max(anorm,(fabs(w[i])+fabs(rv1[i]))); } register int i_nrcols=nrcols*nrcols; for (i=nrcols-1;i>=0;i--) { i_nrcols-=nrcols; if (l < nrcols) { if (g) { register int j_nrcols_i=l*nrcols+i; register int i_nrcols_l=i_nrcols+l; register int j_l=0; // j_l==j-l; for (j=l;j<nrcols;j++) { v[j_nrcols_i]=(u[i_nrcols_l+j_l]/u[i_nrcols_l])/g; j_nrcols_i+=nrcols; j_l++; } register int j_i=1;; for (j=l;j<nrcols;j++) { register int k_nrcols_j=l*nrcols+j; for (s=0.0,k=l;k<nrcols;k++) { s += u[i_nrcols+k]*v[k_nrcols_j]; k_nrcols_j+=nrcols; } register int k_nrcols_i=l*nrcols+i; for (k=l;k<nrcols;k++) { v[k_nrcols_i+j_i] += s*v[k_nrcols_i]; k_nrcols_i+=nrcols; } j_i++; } } register int j_nrcols_i=l*nrcols+i; for (j=l;j<nrcols;j++) { v[i_nrcols+j]=v[j_nrcols_i]=0.0; j_nrcols_i+=nrcols; } } v[i_nrcols+i]=1.0; g=rv1[i]; l=i; } i_nrcols=nrcols*nrcols; for (i=nrcols-1;i>=0;i--) { i_nrcols-=nrcols; l=i+1; g=w[i]; if (l < nrcols) for (j=l;j<nrcols;j++) u[i_nrcols+j]=0.0; if (g) { g=1.0/g; if (l != nrcols) { register int j_i=1; // j_i==j-i; for (j=l;j<nrcols;j++) { register int k_nrcols_i=l*nrcols+i; for (s=0.0,k=l;k<nrrows;k++) { s += u[k_nrcols_i]*u[k_nrcols_i+j_i]; k_nrcols_i+=nrcols; } f=(s/u[i_nrcols+i])*g; k_nrcols_i=i_nrcols+i; for (k=i;k<nrrows;k++) { u[k_nrcols_i+j_i] += f*u[k_nrcols_i]; k_nrcols_i+=nrcols; } j_i++; } } register int j_nrcols_i=i_nrcols+i; for (j=i;j<nrrows;j++) { u[j_nrcols_i] *= g; j_nrcols_i+=nrcols; } } else { register int j_nrcols_i=i_nrcols+i; for (j=i;j<nrrows;j++) { u[j_nrcols_i]=0.0; j_nrcols_i+=nrcols; } } ++u[i_nrcols+i]; } for (k=nrcols-1;k>=0;k--) { for (its=1;its<=30;its++) { flag=1; for (l=k;l>0;l--) { nm=l-1; if (fabs(rv1[l])+anorm == anorm) { flag=0; break; } if (fabs(w[nm])+anorm == anorm) break; } if (flag) { c=0.0; s=1.0; for (i=l;i<=k;i++) { f=s*rv1[i]; if (fabs(f)+anorm != anorm) { g=w[i]; h=PYTHAG(f,g); w[i]=h; h=1.0/h; c=g*h; s=(-f*h); register int j_nrcols=0; for (j=0;j<nrrows;j++) { y=u[j_nrcols+nm]; z=u[j_nrcols+i]; u[j_nrcols+nm]=y*c+z*s; u[j_nrcols+i]=z*c-y*s; j_nrcols+=nrcols; } } } } z=w[k]; if (l == k) { if (z < 0.0) { w[k] = -z; register int j_nrcols_k=k; for (j=0;j<nrcols;j++) { v[j_nrcols_k]=(-v[j_nrcols_k]); j_nrcols_k+=nrcols; } } break; } if (its == 30) { DL_dsystem->get_companion()->Msg("Warning: DL_largematrix::svdcmp: no convergence in 30 iterations\n"); } x=w[l]; nm=k-1; y=w[nm]; g=rv1[nm]; h=rv1[k]; f=((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y); g=PYTHAG(f,1.0); f=((x-z)*(x+z)+h*((y/(f+SIGN(g,f)))-h))/x; c=s=1.0; for (j=l;j<=nm;j++) { i=j+1; g=rv1[i]; y=w[i]; h=s*g; g=c*g; z=PYTHAG(f,h); rv1[j]=z; c=f/z; s=h/z; f=x*c+g*s; g=g*c-x*s; h=y*s; y=y*c; register int jj_nrcols=0; for (jj=0;jj<nrcols;jj++) { x=v[jj_nrcols+j]; z=v[jj_nrcols+i]; v[jj_nrcols+j]=x*c+z*s; v[jj_nrcols+i]=z*c-x*s; jj_nrcols+=nrcols; } z=PYTHAG(f,h); w[j]=z; if (z) { z=1.0/z; c=f*z; s=h*z; } f=(c*g)+(s*y); x=(c*y)-(s*g); jj_nrcols=0; for (jj=0;jj<nrrows;jj++) { y=u[jj_nrcols+j]; z=u[jj_nrcols+i]; u[jj_nrcols+j]=y*c+z*s; u[jj_nrcols+i]=z*c-y*s; jj_nrcols+=nrcols; } } rv1[l]=0.0; rv1[k]=f; w[k]=x; } } delete[] rv1; // post process w: DL_Scalar biggest=0.0; for (i=0;i<nrelem;i+=nrcols+1) if (fabs(a[i])>biggest) biggest=fabs(a[i]); // biggest is now the largest magnitude on A's diagonal #define TINY 1.0e-10 biggest*=TINY; #undef TINY for (jj=0,i=0;i<nrcols;i++) if (fabs(w[i])<biggest) { w[i]=0.0; jj++; } if (jj>0) { DL_dsystem->get_companion()->Msg("svdcomp: %d singularities\n", jj ); } return jj; }
void svdcmp(dfprec *a,int m,int n,dfprec *w,dfprec *v) { int flag,i,its,j,jj,k,l,nm; dfprec c,f,h,s,x,y,z; dfprec anorm=0.0,g=0.0,scale=0.0; dfprec *rv1; rv1=(dfprec *)malloc(sizeof(dfprec)*n); l = 1; for (i=0;i<n;i++) { dfprec *ai; ai=a+i*m; l=i+1; rv1[i]=scale*g; g=s=scale=0.0; if (i < m) { for (k=i;k<m;k++) scale += fabs(ai[k]); if (scale) { for (k=i;k<m;k++) { ai[k] /= scale; s += ai[k]*ai[k]; } f=ai[i]; g = -SIGN(sqrt(s),f); h=f*g-s; ai[i]=f-g; if (i != n-1) { for (j=l;j<n;j++) { dfprec *aj; aj=a+j*m; for (s=0.0,k=i;k<m;k++) s += ai[k]*aj[k]; f=s/h; for (k=i;k<m;k++) aj[k] += f*ai[k]; } } for (k=i;k<m;k++) ai[k] *= scale; } } w[i]=scale*g; g=s=scale=0.0; if (i < m && i != n-1) { dfprec *atmp; atmp=a+l*m; for (k=l;k<n;k++,atmp+=m) scale += fabs(atmp[i]); if (scale) { atmp=a+l*m; for (k=l;k<n;k++,atmp+=m) { atmp[i] /= scale; s += atmp[i]*atmp[i]; } atmp=a+l*m; f=atmp[i]; g = -SIGN(sqrt(s),f); h=f*g-s; atmp[i]=f-g; for (k=l;k<n;k++,atmp+=m) rv1[k]=atmp[i]/h; if (i != m-1) { for (j=l;j<m;j++) { atmp=a+l*m; for (s=0.0,k=l;k<n;k++,atmp+=m) s += atmp[j]*atmp[i]; atmp=a+l*m; for (k=l;k<n;k++,atmp+=m) atmp[j] += s*rv1[k]; } } atmp=a+l*m; for (k=l;k<n;k++,atmp+=m) atmp[i] *= scale; } } anorm=MAX(anorm,(fabs(w[i])+fabs(rv1[i]))); } for (i=n-1;i>=0;i--) { dfprec *vi; vi=v+i*n; if (i < n-1) { if (g) { for (j=l;j<n;j++) vi[j]=((a+m*j)[i]/(a+m*l)[i])/g; for (j=l;j<n;j++) { for (s=0.0,k=l;k<n;k++) s += (a+m*k)[i]*(v+n*j)[k]; for (k=l;k<n;k++) (v+n*j)[k] += s*vi[k]; } } for (j=l;j<n;j++) (v+n*j)[i]=vi[j]=0.0; } vi[i]=1.0; g=rv1[i]; l=i; } for (i=n-1;i>=0;i--) { dfprec *ai; ai=a+i*m; l=i+1; g=w[i]; if (i < n-1) for (j=l;j<n;j++) (a+m*j)[i]=0.0; if (g) { g=1.0/g; if (i != n-1) { for (j=l;j<n;j++) { for (s=0.0,k=l;k<m;k++) s += ai[k]*(a+m*j)[k]; f=(s/ai[i])*g; for (k=i;k<m;k++) (a+m*j)[k] += f*ai[k]; } } for (j=i;j<m;j++) ai[j] *= g; } else { for (j=i;j<m;j++) ai[j]=0.0; } ++ai[i]; } for (k=n-1;k>=0;k--) { dfprec *vk; vk=v+k*n; for (its=1;its<=30;its++) { flag=1; for (l=k;l>=0;l--) { nm=l-1; if (fabs(rv1[l])+anorm == anorm) { flag=0; break; } if (fabs(w[nm])+anorm == anorm) break; } if (flag) { c=0.0; s=1.0; for (i=l;i<=k;i++) { f=s*rv1[i]; if (fabs(f)+anorm != anorm) { dfprec *anm, *ai; anm=a+nm*m; ai=a+m*i; g=w[i]; h=PYTHAG(f,g); w[i]=h; h=1.0/h; c=g*h; s=(-f*h); for (j=0;j<m;j++) { y=anm[j]; z=ai[j]; anm[j]=y*c+z*s; ai[j]=z*c-y*s; } } } } z=w[k]; if (l == k) { if (z < 0.0) { w[k] = -z; for (j=0;j<n;j++) vk[j]=(-vk[j]); } break; } x=w[l]; nm=k-1; y=w[nm]; g=rv1[nm]; h=rv1[k]; f=((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y); g=PYTHAG(f,1.0); f=((x-z)*(x+z)+h*((y/(f+SIGN(g,f)))-h))/x; c=s=1.0; for (j=l;j<=nm;j++) { dfprec *vj, *vi; vj=v+j*n; vi=vj+n; i=j+1; g=rv1[i]; y=w[i]; h=s*g; g=c*g; z=PYTHAG(f,h); rv1[j]=z; c=f/z; s=h/z; f=x*c+g*s; g=g*c-x*s; h=y*s; y=y*c; for (jj=0;jj<n;jj++) { x=vj[jj]; z=vi[jj]; vj[jj]=x*c+z*s; vi[jj]=z*c-x*s; } z=PYTHAG(f,h); w[j]=z; if (z) { z=1.0/z; c=f*z; s=h*z; } f=(c*g)+(s*y); x=(c*y)-(s*g); vj=a+j*m;//use vj for aj vi=vj+m;//use vi for ai for (jj=0;jj<m;jj++) { y=vj[jj]; z=vi[jj]; vj[jj]=y*c+z*s; vi[jj]=z*c-y*s; } } rv1[l]=0.0; rv1[k]=f; w[k]=x; } } free(rv1); }
void svdcmp(double **a, int m, int n, double *w, double **v) { assert(m>=n); int flag,i,its,j,jj,k,l,nm; double c,f,h,s,x,y,z; double anorm=0.0,g=0.0,scale=0.0; double *rv1=new double [n]; assert(rv1!=NULL); rv1--; for(i=1;i<=n;i++) { l=i+1; rv1[i]=scale*g; g=s=scale=0.0; if(i<=m) { for(k=i;k<=m;k++) scale+=fabs(a[k][i]); if(scale) { for(k=i;k<=m;k++) { a[k][i]/=scale; s+=a[k][i]*a[k][i]; } f=a[i][i]; g=-SIGN(sqrt(s),f); h=f*g-s; a[i][i]=f-g; if(i!=n) { for(j=l;j<=n;j++) { for(s=0.0,k=i;k<=m;k++) s+=a[k][i]*a[k][j]; f=s/h; for(k=i;k<=m;k++) a[k][j]+=f*a[k][i]; } } for(k=i;k<=m;k++) a[k][i]*=scale; } } w[i]=scale*g; g=s=scale=0.0; if((i<=m)&&(i!=n)) { for(k=l;k<=n;++k) scale+=fabs(a[i][k]); if(scale) { for(k=l;k<=n;k++) { a[i][k]/=scale; s+=a[i][k]*a[i][k]; } f=a[i][l]; g=-SIGN(sqrt(s),f); h=f*g-s; a[i][l]=f-g; for(k=l;k<=n;k++) rv1[k]=a[i][k]/h; if(i!=m) { for(j=l;j<=m;j++) { for(s=0.0,k=l;k<=n;k++) s+=a[j][k]*a[i][k]; for(k=l;k<=n;k++) a[j][k]+=s*rv1[k]; } } for(k=l;k<=n;k++) a[i][k]*=scale; } } anorm=NR_MAX(anorm,(fabs(w[i])+fabs(rv1[i]))); } for(i=n;i>=1;--i) { if(i<n) { if(g) { for(j=l;j<=n;j++) v[j][i]=(a[i][j]/a[i][l])/g; for(j=l;j<=n;j++) { for(s=0.0,k=l;k<=n;k++) s+=a[i][k]*v[k][j]; for(k=l;k<=n;k++) v[k][j]+=s*v[k][i]; } } for(j=l;j<=n;j++) v[i][j]=v[j][i]=0.0; } v[i][i]=1.0; g=rv1[i]; l=i; } for(i=n;i>=1;i--) { l=i+1; g=w[i]; if(i<n) for(j=l;j<=n;j++) a[i][j]=0.0; if(g) { g=1.0/g; if(i!=n) { for(j=l;j<=n;j++) { for(s=0.0,k=l;k<=m;k++) s+=a[k][i]*a[k][j]; f=(s/a[i][i])*g; for(k=i;k<=m;k++) a[k][j]+=f*a[k][i]; } } for(j=i;j<=m;j++) a[j][i]*=g; } else for(j=i;j<=m;j++) a[j][i]=0.0; ++a[i][i]; } for(k=n;k>=1;k--) { for(its=1;its<=30;its++) { flag=1; for(l=k;l>=1;l--) { nm=l-1; if((double)(fabs(rv1[l])+anorm)==anorm) { flag=0; break; } if((double)(fabs(w[nm])+anorm)==anorm) break; } if(flag) { c=0.0; s=1.0; for(i=l;i<=k;i++) { f=s*rv1[i]; rv1[i]=c*rv1[i]; if((double)(fabs(f)+anorm)==anorm) break; g=w[i]; h=PYTHAG(f,g); w[i]=h; h=1.0/h; c=g*h; s=-f*h; for(j=1;j<=m;j++) { y=a[j][nm]; z=a[j][i]; a[j][nm]=y*c+z*s; a[j][i]=z*c-y*s; } } } z=w[k]; if(l==k) { if(z<0.0) { w[k]=-z; for(j=1;j<=n;j++) v[j][k]=-v[j][k]; } break; } if(its==30) exit(fprintf(stderr,"no convergence in 30 svdcmp iterations")); x=w[l]; nm=k-1; y=w[nm]; g=rv1[nm]; h=rv1[k]; f=((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y); g=PYTHAG(f,1.0); f=((x-z)*(x+z)+h*((y/(f+SIGN(g,f)))-h))/x; c=s=1.0; for(j=l;j<=nm;j++) { i=j+1; g=rv1[i]; y=w[i]; h=s*g; g=c*g; z=PYTHAG(f,h); rv1[j]=z; c=f/z; s=h/z; f=x*c+g*s; g=g*c-x*s; h=y*s; y=y*c; for(jj=1;jj<=n;jj++) { x=v[jj][j]; z=v[jj][i]; v[jj][j]=x*c+z*s; v[jj][i]=z*c-x*s; } z=PYTHAG(f,h); w[j]=z; if(z) { z=1.0/z; c=f*z; s=h*z; } f=c*g+s*y; x=c*y-s*g; for(jj=1;jj<=m;jj++) { y=a[jj][j]; z=a[jj][i]; a[jj][j]=y*c+z*s; a[jj][i]=z*c-y*s; } } rv1[l]=0.0; rv1[k]=f; w[k]=x; } } rv1++; delete[] rv1; }