예제 #1
0
    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;
    }
예제 #2
0
파일: svd.cpp 프로젝트: cedrou/marian-dev
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);
}
예제 #4
0
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;
}
예제 #5
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);
}
예제 #6
0
파일: eig.c 프로젝트: S-V/nl-software
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;
}
예제 #7
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;
}
예제 #8
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;
  }
예제 #9
0
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;
}
예제 #10
0
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);
}
예제 #11
0
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;
}