⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dsvdc.c

📁 InsightToolkit-1.4.0(有大量的优化算法程序)
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "f2c.h"
#include "netlib.h"
extern double sqrt(double); /* #include <math.h> */

/*
 * Calling this ensures that the operands are spilled to
 * memory and thus avoids excessive precision when compiling
 * for x86 with heavy optimization (gcc). It is better to do
 * this than to turn on -ffloat-store.
 */
static int fsm_ieee_doubles_equal(const doublereal *x, const doublereal *y);

/* Table of constant values */
static integer c__1 = 1;
static doublereal c_m1 = -1.;

/* Subroutine */ void dsvdc_(x, ldx, n, p, s, e, u, ldu, v, ldv, work, job, info)
doublereal *x;
const integer *ldx, *n, *p;
doublereal *s, *e, *u;
const integer *ldu;
doublereal *v;
const integer *ldv;
doublereal *work;
const integer *job;
integer *info;
{
    /* System generated locals */
    integer i__1;
    doublereal d__1;

    /* Local variables */
    static integer kase, jobu, iter;
    static doublereal test;
    static doublereal b, c;
    static doublereal f, g;
    static integer i, j, k, l, m;
    static doublereal t, scale;
    static doublereal shift;
    static integer maxit;
    static logical wantu, wantv;
    static doublereal t1, ztest, el;
    static doublereal cs;
    static integer mm, ls;
    static doublereal sl;
    static integer lu;
    static doublereal sm, sn;
    static integer lp1, nct, ncu, nrt;
    static doublereal emm1, smm1;

/*     dsvdc is a subroutine to reduce a double precision nxp matrix x  */
/*     by orthogonal transformations u and v to diagonal form.  The     */
/*     diagonal elements s(i) are the singular values of x.  The        */
/*     columns of u are the corresponding left singular vectors,        */
/*     and the columns of v the right singular vectors.                 */
/*                                                                      */
/*     on entry                                                         */
/*                                                                      */
/*         x         double precision(ldx,p), where ldx.ge.n.           */
/*                   x contains the matrix whose singular value         */
/*                   decomposition is to be computed.  x is             */
/*                   destroyed by dsvdc.                                */
/*                                                                      */
/*         ldx       integer.                                           */
/*                   ldx is the leading dimension of the array x.       */
/*                                                                      */
/*         n         integer.                                           */
/*                   n is the number of rows of the matrix x.           */
/*                                                                      */
/*         p         integer.                                           */
/*                   p is the number of columns of the matrix x.        */
/*                                                                      */
/*         ldu       integer.                                           */
/*                   ldu is the leading dimension of the array u.       */
/*                   (see below).                                       */
/*                                                                      */
/*         ldv       integer.                                           */
/*                   ldv is the leading dimension of the array v.       */
/*                   (see below).                                       */
/*                                                                      */
/*         work      double precision(n).                               */
/*                   work is a scratch array.                           */
/*                                                                      */
/*         job       integer.                                           */
/*                   job controls the computation of the singular       */
/*                   vectors.  it has the decimal expansion ab          */
/*                   with the following meaning                         */
/*                                                                      */
/*                        a.eq.0    do not compute the left singular    */
/*                                  vectors.                            */
/*                        a.eq.1    return the n left singular vectors  */
/*                                  in u.                               */
/*                        a.ge.2    return the first min(n,p) singular  */
/*                                  vectors in u.                       */
/*                        b.eq.0    do not compute the right singular   */
/*                                  vectors.                            */
/*                        b.eq.1    return the right singular vectors   */
/*                                  in v.                               */
/*                                                                      */
/*     on return                                                        */
/*                                                                      */
/*         s         double precision(mm), where mm=min(n+1,p).         */
/*                   the first min(n,p) entries of s contain the        */
/*                   singular values of x arranged in descending        */
/*                   order of magnitude.                                */
/*                                                                      */
/*         e         double precision(p).                               */
/*                   e ordinarily contains zeros.  however see the      */
/*                   discussion of info for exceptions.                 */
/*                                                                      */
/*         u         double precision(ldu,k), where ldu.ge.n.  if       */
/*                               joba.eq.1 then k.eq.n, if joba.ge.2    */
/*                               then k.eq.min(n,p).                    */
/*                   u contains the matrix of left singular vectors.    */
/*                   u is not referenced if joba.eq.0.  if n.le.p       */
/*                   or if joba.eq.2, then u may be identified with x   */
/*                   in the subroutine call.                            */
/*                                                                      */
/*         v         double precision(ldv,p), where ldv.ge.p.           */
/*                   v contains the matrix of right singular vectors.   */
/*                   v is not referenced if job.eq.0.  if p.le.n,       */
/*                   then v may be identified with x in the             */
/*                   subroutine call.                                   */
/*                                                                      */
/*         info      integer.                                           */
/*                   the singular values (and their corresponding       */
/*                   singular vectors) s(info+1),s(info+2),...,s(m)     */
/*                   are correct (here m=min(n,p)).  thus if            */
/*                   info.eq.0, all the singular values and their       */
/*                   vectors are correct.  in any event, the matrix     */
/*                   b = trans(u)*x*v is the bidiagonal matrix          */
/*                   with the elements of s on its diagonal and the     */
/*                   elements of e on its super-diagonal (trans(u)      */
/*                   is the transpose of u).  thus the singular         */
/*                   values of x and b are the same.                    */
/*                                                                      */
/*     linpack. this version dated 08/14/78 .                           */
/*              correction made to shift 2/84.                          */
/*     g.w. stewart, university of maryland, argonne national lab.      */

/*     dsvdc uses the following functions and subprograms. */
/*                                                         */
/*     external drot                                       */
/*     blas daxpy,ddot,dscal,dswap,dnrm2,drotg             */
/*     fortran dabs,dmax1,max0,min0,mod,dsqrt              */

/*     set the maximum number of iterations. */

    maxit = 1000;

/*     determine what is to be computed. */

    wantu = FALSE_;
    wantv = FALSE_;
    jobu = *job % 100 / 10;
    ncu = *n;
    if (jobu > 1) {
        ncu = min(*n,*p);
    }
    if (jobu != 0) {
        wantu = TRUE_;
    }
    if (*job % 10 != 0) {
        wantv = TRUE_;
    }

/*     reduce x to bidiagonal form, storing the diagonal elements */
/*     in s and the super-diagonal elements in e. */

    *info = 0;
    nct = min(*n-1,*p);
    nrt = max(0,min(*p-2,*n));
    lu = max(nct,nrt);
    for (l = 0; l < lu; ++l) {
        lp1 = l+1;
        if (lp1 > nct) {
            goto L20;
        }

/*           compute the transformation for the l-th column and */
/*           place the l-th diagonal in s(l). */

        i__1 = *n - l;
        s[l] = dnrm2_(&i__1, &x[l + l * *ldx], &c__1);
        if (s[l] == 0.) {
            goto L10;
        }
        if (x[l + l * *ldx] != 0.) {
            s[l] = d_sign(&s[l], &x[l + l * *ldx]);
        }
        i__1 = *n - l;
        d__1 = 1. / s[l];
        dscal_(&i__1, &d__1, &x[l + l * *ldx], &c__1);
        x[l + l * *ldx] += 1.;
L10:
        s[l] = -s[l];
L20:
        for (j = lp1; j < *p; ++j) {

/*              apply the transformation. */

            if (l < nct && s[l] != 0.) {
                i__1 = *n - l;
                t = -ddot_(&i__1, &x[l + l * *ldx], &c__1, &x[l + j * *ldx], &c__1) / x[l + l * *ldx];
                daxpy_(&i__1, &t, &x[l + l * *ldx], &c__1, &x[l + j * *ldx], &c__1);
            }

/*           place the l-th row of x into  e for the */
/*           subsequent calculation of the row transformation. */

            e[j] = x[l + j * *ldx];
        }

/*           place the transformation in u for subsequent back */
/*           multiplication. */

        if (wantu && l < nct)
        for (i = l; i < *n; ++i) {
            u[i + l * *ldu] = x[i + l * *ldx];
        }
        if (lp1 > nrt) {
            continue;
        }

/*           compute the l-th row transformation and place the */
/*           l-th super-diagonal in e(l). */

        i__1 = *p - lp1;
        e[l] = dnrm2_(&i__1, &e[lp1], &c__1);
        if (e[l] == 0.) {
            goto L80;
        }
        if (e[lp1] != 0.) {
            e[l] = d_sign(&e[l], &e[lp1]);
        }
        i__1 = *p - lp1;
        d__1 = 1. / e[l];
        dscal_(&i__1, &d__1, &e[lp1], &c__1);
        e[lp1] += 1.;
L80:
        e[l] = -e[l];
        if (l+2 > *n || e[l] == 0.) {
            goto L120;
        }

/*              apply the transformation. */

        for (i = lp1; i < *n; ++i) {
            work[i] = 0.;
        }
        for (j = lp1; j < *p; ++j) {
            i__1 = *n - lp1;
            daxpy_(&i__1, &e[j], &x[lp1 + j * *ldx], &c__1, &work[lp1], &c__1);
        }
        for (j = lp1; j < *p; ++j) {
            i__1 = *n - lp1;
            d__1 = -e[j] / e[lp1];
            daxpy_(&i__1, &d__1, &work[lp1], &c__1, &x[lp1 + j * *ldx], &c__1);
        }
L120:

/*              place the transformation in v for subsequent */
/*              back multiplication. */

        if (wantv)
        for (i = lp1; i < *p; ++i) {
            v[i + l * *ldv] = e[i];
        }
    }

/*     set up the final bidiagonal matrix or order m. */

    m = min(*p-1,*n);
    if (nct < *p) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -