blas.cc
Upload User: hkdiguang
Upload Date: 2013-05-12
Package Size: 105k
Code Size: 75k
Development Platform:

Unix_Linux

  1. /**************************************************************
  2.  *                                                            *
  3.  * multiplication of matrix A by vector x, where A is m by n  *
  4.  * (m >> n) and is stored using the Harwell-Boeing compressed *
  5.  * column sparse matrix format.  y stores product vector.     *
  6.  *                                                            *
  7.  **************************************************************/
  8. void opa(long m, long n, double *x, double *y)
  9. {
  10.    long end,i,j;
  11.    mxvcount += 1;
  12.    for (i = 0; i < m; i++) y[i] = ZERO;
  13.    for (i = 0; i < n; i++) {
  14.       end = pointr[i+1];
  15.       for (j = pointr[i]; j < end; j++)
  16.  y[rowind[j]] += value[j] * x[i]; 
  17.    }
  18.    return;
  19. }
  20. /**************************************************************
  21.  *                                                            *
  22.  * multiplication of an n by m matrix A' by a vector X, store *
  23.  * in Y.                                                      *
  24.  *                                                            *
  25.  **************************************************************/
  26. void opat(long n, double *x, double *y)
  27. {
  28.    long end,i,j;
  29.    
  30.    mtxvcount += 1;
  31.    for (i = 0; i < n; i++) y[i] = ZERO;
  32.    for (i = 0; i < n; i++) {
  33.       end = pointr[i+1];
  34.       for (j = pointr[i]; j < end; j++)
  35.  y[i] += value[j] * x[rowind[j]]; 
  36.    }
  37.    return;
  38. }
  39. double fsign(double a,double b)
  40.   /************************************************************** 
  41.    * returns |a| if b is positive; else fsign returns -|a|      *
  42.    **************************************************************/ 
  43. {
  44.   
  45.   if ((a>=0.0 && b>=0.0) || (a<0.0 && b<0.0))return(a);
  46.   if  ((a<0.0 && b>=0.0) || (a>=0.0 && b<0.0))return(-a);
  47. }
  48. double dmax(double a, double b)
  49.   /************************************************************** 
  50.    * returns the larger of two double precision numbers         *
  51.    **************************************************************/ 
  52. {
  53.   
  54.   if (a > b) return(a);
  55.   else return(b);
  56. }
  57. double dmin(double a, double b)
  58.   /************************************************************** 
  59.    * returns the smaller of two double precision numbers        *
  60.    **************************************************************/ 
  61. {
  62.   
  63.   if (a < b) return(a);
  64.   else return(b);
  65. }
  66. long imin(long a, long b)
  67.   /************************************************************** 
  68.    * returns the smaller of two integers                        *
  69.    **************************************************************/ 
  70. {
  71.   
  72.   if (a < b) return(a);
  73.   else return(b);
  74. }
  75. long imax(long a,long b)
  76.   /************************************************************** 
  77.    * returns the larger of two integers                         *
  78.    **************************************************************/ 
  79. {
  80.   
  81.   if (a > b) return(a);
  82.   else return(b);
  83. }
  84.  
  85. /***********************************************************************
  86.  *                                                                     *
  87.  *                        orthg()                                      *
  88.  *         Gram-Schmidt orthogonalization procedure                    *
  89.  *                                                                     *
  90.  ***********************************************************************/
  91. /***********************************************************************
  92.    Description
  93.    -----------
  94.    The p by n matrix Z stored row-wise in rows f to (f+p-1) of
  95.    array X is reorthogonalized w.r.t. the first f rows of array X.
  96.    The resulting matrix Z is then factored into the product of a
  97.    p by n orthonormal matrix (stored over matrix Z) and a p by p
  98.    upper-triangular matrix (stored in the first p rows and columns 
  99.    of array B).  (Based on orthog from Rutishauser) 
  100.    Parameters
  101.    ----------
  102.    (input)
  103.    p           number of consecutive vectors of array x (stored row-wise)
  104.        to be orthogonalized
  105.    f           number of rows against which the next p rows are to be
  106.        orthogonalized
  107.    n           column dimension of x
  108.    x           2-dimensional array whose p rows are to be orthogonalized
  109.        against its first f rows
  110.    temp        work array
  111.    (output)
  112.    x           output matrix whose f+p rows are orthonormalized
  113.    b           p by p upper-triangular matrix
  114.    Functions called
  115.    --------------
  116.    BLAS         dgemv, ddot, dscal, daxpy, dcopy
  117.  ***********************************************************************/
  118. void orthg(long p, long f, long n, double **b, double **x, double *temp)
  119. {
  120.    long fp, k, km1;
  121.    long orig, small;
  122.    double t, s;
  123.    if (!p) return;
  124.    if (f == 0 && p > n) {
  125.       fprintf(stderr,"%sn",
  126.          "*** ON ENTRY TO ORTHG, MATRIX TO BE ORTHONORMALIZED IS SINGULAR");
  127.       return;
  128.    }
  129.    fp = f + p;
  130.    for (k = f; k < fp; k++) {
  131.       km1 = k - 1;
  132.       orig = TRUE;
  133.       while(TRUE) {
  134.          t = ZERO;
  135.  if (km1 >= 0) {
  136.     if (km1 > 0) {
  137.        dgemv(NTRANSP, k, n, ONE, x, x[k], ZERO, temp);
  138.        t += ddot(k, temp, 1, temp, 1);
  139.     }
  140.     else {
  141.        temp[0] = ddot(n, x[0], 1, x[k], 1);
  142.        t += temp[0] * temp[0];
  143.     }
  144.     if (orig && km1 >= f) 
  145.                dcopy(k - f, &temp[f], 1, &b[k - f][0], 1); 
  146.             if (km1 > 0) 
  147.        dgemv(TRANSP, k, n, -ONE, x, temp, ONE, &x[k][0]);
  148.             else
  149.        daxpy(n, -temp[0], x[0], 1, x[k], 1);
  150.          }
  151.  if (km1 < 0 || p != 1) {
  152.     s = ddot(n, x[k], 1, x[k], 1);
  153.     t += s;
  154.     if (s > t/CONST) {
  155.        small = FALSE;
  156.        s = sqrt(s);
  157.                b[k - f][k - f] = s;
  158.        if (s != ZERO) s = ONE/s;
  159.        dscal(n, s, x[k], 1);
  160.     }
  161.     else {
  162.        small = TRUE;
  163.        orig  = FALSE;
  164.     }
  165.  }
  166.  if (small == FALSE || p == 1) break;
  167.       }
  168.    }
  169. }
  170. /***********************************************************************
  171.  *                                                                     *
  172.  *                         dgemv()                                     *
  173.  * A C-translation of the level 2 BLAS routine DGEMV by Dongarra,      *
  174.  * du Croz, and Hammarling, and Hanson (see LAPACK Users' Guide).      *
  175.  *                                                                     *
  176.  ***********************************************************************/
  177. /***********************************************************************
  178.    Description
  179.    -----------
  180.    dgemv() performs one of the matrix-vector operations
  181.    y := alpha * A * x + beta * y  or  y := alpha * A' * x + beta * y
  182.    where alpha and beta are scalars, X, Y are vectors and A is an
  183.    m by n matrix.
  184. void dgemv(long transa, long m, long n, 
  185.            double alpha, double **a, double *x, double beta, double *y)
  186.    Parameters
  187.    ----------
  188.    (input)
  189.    transa   TRANSP indicates op(A) = A' is to be used in the multiplication
  190.     NTRANSP indicates op(A) = A is to be used in the multiplication
  191.    m        on entry, m specifies the number of rows of the matrix A.
  192.     m must be at least zero.  Unchanged upon exit.
  193.    n        on entry, n specifies the number of columns of the matrix A.
  194.     n must be at least zero.  Unchanged upon exit.
  195.    alpha    a scalar multiplier.  Unchanged upon exit.
  196.    a        matrix A as a 2-dimensional array.  Before entry, the leading
  197.     m by n part of the array a must contain the matrix A.
  198.    x        linear array of dimension of at least n if transa = NTRANSP
  199.     and at least m otherwise.
  200.    beta     a scalar multiplier.  When beta is supplied as zero then y
  201.     need not be set on input.  Unchanged upon exit.
  202.    y        linear array of dimension of at least m if transa = NTRANSP
  203.     and at leat n otherwise.  Before entry with beta nonzero,
  204.     the array y must contain the vector y.  On exit, y is 
  205.     overwritten by the updated vector y.
  206.  ***********************************************************************/
  207. void dgemv(long transa, long m, long n, 
  208.            double alpha, double **a, double *x, double beta, double *y)
  209. {
  210.    long info, leny, i, j;
  211.    double temp, *ptrtemp;
  212.    info = 0;
  213.    if      ( transa != TRANSP && transa != NTRANSP ) info = 1;
  214.    else if ( m < 0 )       info = 2;
  215.    else if ( n < 0 )      info = 3;
  216.    if (info) {
  217.       fprintf(stderr, "%s %1ld %sn",
  218.       "*** ON ENTRY TO DGEMV, PARAMETER NUMBER",info,"HAD AN ILLEGAL VALUE");
  219.       return;
  220.       //throw new svdpack_error(info);
  221.    }
  222.    if (transa) leny = n;
  223.    else        leny = m;
  224.    if (!m || !n || (alpha == ZERO && beta == ONE))
  225.       return;
  226.    ptrtemp = y; 
  227.    /* form Y := beta * Y */
  228.    if (beta == ZERO) 
  229.       for (i = 0; i < leny; i++) *ptrtemp++ = ZERO;
  230.    else if (beta != ONE) 
  231.       for (i = 0; i < leny; i++) *ptrtemp++ *= beta;
  232.    if (alpha == ZERO) return;
  233.    switch(transa) {
  234.       /* form Y := alpha * A * X + Y */
  235.       case NTRANSP:  for(i = 0; i < m; i++) {
  236.                         ptrtemp = *a++;
  237.         temp = ZERO;
  238.         for(j = 0; j < n; j++) 
  239.    temp += *ptrtemp++ * x[j];
  240. y[i] += alpha * temp;
  241.      }
  242.      break;
  243.      
  244.       /* form Y := alpha * A' * X + Y */
  245.       case TRANSP:   for(i = 0; i < m; i++) { 
  246.                         ptrtemp = *a++;
  247. if (x[i] != ZERO) {
  248.    temp = alpha * x[i];
  249.    for(j = 0; j < n; j++)
  250.       y[j] += temp * (*ptrtemp++);
  251. }
  252.      }
  253.      break;
  254.    }
  255. }
  256. /***********************************************************************
  257.  *                                                                     *
  258.  *                         dgemm()                                     *
  259.  *                                                                     *
  260.  * A C-translation of the level 3 BLAS routine DGEMM by Dongarra,      *
  261.  * Duff, du Croz, and Hammarling (see LAPACK Users' Guide).            *
  262.  * In this version, two of the three arrays which store the matrices   *
  263.  * used in this matrix-matrix multiplication are accessed as linear    *
  264.  * arrays.                                                             *
  265.  *                                                                     *
  266.  ***********************************************************************/
  267. /***********************************************************************
  268.    Description
  269.    -----------
  270.    dgemm() performs one of the matrix-matrix operations
  271.       C := alpha * op(A) * op(B) + beta * C,
  272.    where op(X) = X or op(X) = X', alpha and beta are scalars, and A, B
  273.    and C are matrices, with op(A) an m by k matrix, op(B) a k by n
  274.    matrix and C an m by n matrix.
  275.    Note that the arrays storing matrices B and C are linear arrays while
  276.    the array of A is two-dimensional.
  277.    Parameters
  278.    ----------
  279.    (input)
  280.    transa   TRANSP indicates op(A) = A' is to be used in the multiplication
  281.     NTRANSP indicates op(A) = A is to be used in the multiplication
  282.    transb   TRANSP indicates op(B) = B' is to be used in the multiplication
  283.     NTRANSP indicates op(B) = B is to be used in the multiplication
  284.    m        on entry, m specifies the number of rows of the matrix op(A)
  285.     and of the matrix C.  m must be at least zero.  Unchanged
  286.     upon exit.
  287.    n        on entry, n specifies the number of columns of the matrix op(B)
  288.     and of the matrix C.  n must be at least zero.  Unchanged
  289.     upon exit.
  290.    k        on entry, k specifies the number of columns of the matrix op(A)
  291.     and the number of rows of the matrix B.  k must be at least 
  292.     zero.  Unchanged upon exit.
  293.    alpha    a scalar multiplier
  294.    a        matrix A as a 2-dimensional array.  When transa = NTRANSP, the
  295.     first k columns of the first m rows must contain the matrix A.
  296.     Otherwise, the first m columns of the first k rows must contain
  297.     the matrix A.
  298.    b        matrix B as a linear array.  The leading (k * n) elements of
  299.     b must contain the matrix B.
  300.    beta     a scalar multiplier.  When beta is supplied as zero then C
  301.     need not be set on input.
  302.    c        matrix C as a linear array.  Before entry, the leading (m * n)
  303.     elements of c must contain the matrix C except when beta = 0.
  304.     In this case, c need not be set on entry.
  305.     On exit, c is overwritten by the (m * n) elements of matrix
  306.     (alpha * op(A) * op(B) + beta * C).
  307.  ***********************************************************************/
  308. void dgemm(long transa, long transb, long m, long n, long k, 
  309.            double alpha, double **a, double *b, double beta, double *c)
  310. {
  311.    long info;
  312.    long i, j, l, nrowa, ncola, nrowb, ncolb, nc;
  313.    double temp, *atemp, *btemp1, *ptrtemp, *ctemp;
  314.    info = 0;
  315.    if      ( transa != TRANSP && transa != NTRANSP ) info = 1;
  316.    else if ( transb != TRANSP && transb != NTRANSP ) info = 2;
  317.    else if ( m < 0 )       info = 3;
  318.    else if ( n < 0 )      info = 4;
  319.    else if ( k < 0 )              info = 5;
  320.    if (info) {
  321.       fprintf(stderr, "%s %1ld %sn",
  322.       "*** ON ENTRY TO DGEMM, PARAMETER NUMBER",info,"HAD AN ILLEGAL VALUE");
  323.       return; //exit(info);
  324.    }
  325.    if (transa) {
  326.       nrowa = k;
  327.       ncola = m;
  328.    }
  329.    else { 
  330.       nrowa = m;
  331.       ncola = k;
  332.    }
  333.    if (transb) {
  334.       nrowb = n;
  335.       ncolb = k;
  336.    }
  337.    else {
  338.       nrowb = k;
  339.       ncolb = n;
  340.    }
  341.    nc = m * n;
  342.    if (!m || !n || ((alpha == ZERO || !k) && beta == ONE))
  343.       return;
  344.    ctemp = c; 
  345.    if (alpha == ZERO) {
  346.       if (beta == ZERO)
  347.          for (i = 0; i < nc; i++) *ctemp++ = ZERO;
  348.       else if (beta != ONE)
  349.          for (i = 0; i < nc; i++) *ctemp++ *= beta;
  350.       return;
  351.    }
  352.    if (beta == ZERO) 
  353.       for (i = 0; i < nc; i++) *ctemp++ = ZERO;
  354.    else if (beta != ONE) 
  355.       for (i = 0; i < nc; i++) *ctemp++ *= beta;
  356.    if (!transb) { 
  357.       switch(transa) {
  358.  /* form C := alpha * A * B + beta * C */
  359.  case NTRANSP:  ptrtemp = c;
  360.         for(l = 0; l < nrowa; l++) {
  361.                            atemp = *a++;
  362.                   btemp1 = b;
  363.              for(j = 0; j < ncola; j++) {
  364.               temp = *atemp * alpha;
  365.                     ctemp = ptrtemp;
  366.                       for(i = 0; i < ncolb; i++) 
  367.       (*ctemp++) += temp * (*btemp1++);
  368.               atemp++;
  369.              }
  370.                ptrtemp = ctemp;
  371.                  }
  372. break;
  373.  /* form C := alpha * A' * B + beta * C */
  374.  case TRANSP:   ptrtemp = b;
  375.                 for(l = 0; l < nrowa; l++) {
  376.                            atemp = *a++;
  377.                   ctemp = c;
  378.              for(j = 0; j < ncola; j++) {
  379.               temp = *atemp * alpha;
  380.                     btemp1 = ptrtemp;
  381.                       for(i = 0; i < ncolb; i++) 
  382.       (*ctemp++) += temp * (*btemp1++);
  383.               atemp++;
  384.              }
  385.                ptrtemp = btemp1;
  386.          }
  387. break;
  388.       }
  389.    }
  390.    else { 
  391.       ctemp = c;
  392.       switch(transa) {
  393.  /* form C := alpha * A * B' + beta * C */
  394.  case NTRANSP: for(l = 0; l < nrowa; l++) {
  395.                   btemp1 = b;
  396.              for(j = 0; j < nrowb; j++) {
  397.               atemp = *a;
  398.                       for(i = 0; i < ncolb; i++) 
  399.       *ctemp += (*atemp++) * alpha * (*btemp1++);
  400.               ctemp++;
  401.              }
  402.    a++;
  403.          }
  404. break;
  405.  /* form C := alpha * A' * B' + beta * C */
  406.  case TRANSP:   for(i = 0; i < ncola; i++) {
  407.    btemp1 = b;
  408.    for (l = 0; l < nrowb; l++) {
  409.                      temp = ZERO;
  410.         for(j = 0; j < nrowa; j++) 
  411.          temp += a[j][i] * (*btemp1++);
  412.            *ctemp++ += alpha * temp;
  413.    }
  414.          }
  415. break;
  416.       }
  417.    }
  418. }
  419. /***********************************************************************
  420.  *                                                                     *
  421.  *                        enorm()                                      *
  422.  *  a C translation of the Fortran-77 version by Burton, Garbow,       *
  423.  *  Hillstrom and More of Argonne National Laboratory.                 *
  424.  *                                                                     *
  425.  ***********************************************************************/
  426. /***********************************************************************
  427.    Description
  428.    -----------
  429.    given an n-vector x, this function calculates the Euclidean norm of x.
  430.    The Euclidean norm is computed by accumulating the sum of squares in 
  431.    three different sums.  The sums of squares for the small and large 
  432.    components are scaled so that no overflows occur.  Non-destructive 
  433.    underflows are permitted.  Underflows and overflows do not occur in the 
  434.    computation of the unscaled sum of squares for the intermediate components. 
  435.    The definitions of small, intermediate and large components depend on two
  436.    constants, rdwarf and rgiant.  The restrictions on these constants are 
  437.    that rdwarf**2 not underflow and rgiant**2 not overflow.  The constants
  438.    given here are suitable for every known computer.
  439.    The function returns the Euclidean norm of vector x in double precision.
  440.    Parameters
  441.    ----------
  442.    n         number of elements in vector x
  443.    x         linear array of vector x whose Euclidean norm is to be 
  444. calculated
  445.  ***********************************************************************/
  446. double enorm(long n, double *x)
  447. {
  448.    double norm2, agiant, floatn, s1, s2, s3, xabs, x1max, x3max;
  449.    long i;
  450.    s1     = ZERO;
  451.    s2     = ZERO;
  452.    s3     = ZERO;
  453.    x1max  = ZERO;
  454.    x3max  = ZERO;
  455.    floatn = (double)n;
  456.    agiant = RGIANT / floatn;
  457.    for (i = 0; i < n; i++) {
  458.       xabs = fabs(x[i]);
  459.       /* summing components of vector that need no scaling */
  460.       if (xabs > RDWARF && xabs < agiant)
  461.  s2 += xabs * xabs;
  462.       else {
  463.  /* underflow... */
  464.  if (xabs <= RDWARF) {
  465.             if (xabs > x3max) {
  466.        s3 = ONE + s3 * (x3max/xabs) * (x3max/xabs);
  467.        x3max = xabs;
  468.     }
  469.     else if (xabs != 0)
  470.        s3 += (xabs/x3max) * (xabs/x3max);
  471.  }
  472.  /* overflow... */
  473.  else {
  474.     /* summing large components of vector */
  475.     if (xabs <= x1max)
  476.        s1 += (xabs/x1max) * (xabs/x1max);
  477.             else {
  478.        s1 = ONE + s1 * (x1max/xabs) * (x1max/xabs);
  479.        x1max = xabs;
  480.     }
  481.  }
  482.       }
  483.    }
  484.    if (s1 != ZERO)
  485.       norm2 = x1max * sqrt(s1 + (s2/x1max) / x1max);
  486.    else if (s2 != ZERO) {
  487.       if (s2 >= x3max)
  488.  norm2 = sqrt(s2 * (ONE + (x3max/s2) * (x3max*s3)));
  489.       else 
  490.  norm2 = sqrt(x3max * ((s2/x3max) + (x3max*s3)));
  491.    }
  492.    else
  493.       norm2 = x3max * sqrt(s3);
  494.    return(norm2);
  495. }
  496. /***********************************************************************
  497.  *                                                                     *
  498.  *                          dtbmv()                                    *
  499.  *                                                                     *
  500.  ***********************************************************************/
  501. /***********************************************************************
  502.    Description
  503.    -----------
  504.    The function performs one of the matrix-vector operations
  505. x := A * x,  or  x := A' * x,
  506.    where A is an upper-triangular matrix.
  507.    Parameters
  508.    ----------
  509.    trans     if trans = TRANSP, A' is to be used in the multiplication
  510.              if trans = NTRANSP, A is to be used in the multiplication
  511.    n         number of rows of matrix A; n must be at least 0.  Unchanged
  512.      upon exit.
  513.    k         number of super-diagonals of matrix A
  514.    a         2-dimensional array whose leading n by (k + 1) part must 
  515.      contain the upper triangular band part of the matrix of 
  516.      coefficients, supplied row by row, with the leading diagonal
  517.      of the matrix in column (k + 1) of the array, the first super-
  518.      diagonal starting at position 2 in column k, and so on.
  519.      The top left k by k triangle of the array A is not referenced.
  520.    x         linear array of dimension of at least n.  Before entry,
  521.      x must contain the n elements of vector x.  On exit, x is
  522.      overwritten with the transformed vector x.
  523.    Functions called
  524.    --------------
  525.    MISC      imax  
  526.  ***********************************************************************/
  527. void dtbmv(long trans, long n, long k, double **a, double *x)
  528. {
  529.    long info, j, i, l, end;
  530.    double temp;
  531.    info = 0;
  532.    if      ( trans != TRANSP && trans != NTRANSP )   info = 1;
  533.    else if ( n < 0 )                                 info = 2;
  534.    else if ( k < 0 )                                 info = 3;
  535.    if (info) {
  536.       fprintf(stderr, "%s %1ld %sn",
  537.       "*** ON ENTRY TO DTBMV, PARAMETER NUMBER",info,"HAD AN ILLEGAL VALUE");
  538.       return; //exit(info);
  539.    }
  540.    switch(trans) {
  541.       case NTRANSP:  for (j = 0; j < n; j++) {
  542.                         temp = x[j];
  543.                         l = k - j;
  544.                         for (i = imax(0, j - k); i < j; i++) 
  545.                            x[i] += temp * a[j][l+i];
  546.                         x[j] *= a[j][k];
  547.                      }
  548.      break;
  549.       case TRANSP:   for (j = n - 1; j >= 0; j--) {
  550. temp = x[j] * a[j][k];
  551. l = k - j;
  552. end = imax(0, j - k);
  553. for (i = j - 1; i >= end; i--)
  554.    temp += x[i] * a[j][l+i];
  555.                         x[j] = temp;
  556.      }
  557.      break;
  558.    }
  559. }
  560. /************************************************************** 
  561.  * Function interchanges two vectors             *
  562.  * Based on Fortran-77 routine from Linpack by J. Dongarra    *
  563.  **************************************************************/ 
  564. void dswap(long n,double *dx,long incx,double *dy,long incy)
  565. {
  566.    long i;
  567.    double dtemp;
  568.    if (n <= 0 || incx == 0 || incy == 0) return;
  569.    if (incx == 1 && incy == 1) {
  570.       for (i=0; i < n; i++) {
  571.  dtemp = *dy;
  572.  *dy++ = *dx;
  573.  *dx++ = dtemp;
  574.       }
  575.    }
  576.    else {
  577.       if (incx < 0) dx += (-n+1) * incx;
  578.       if (incy < 0) dy += (-n+1) * incy;
  579.       for (i=0; i < n; i++) {
  580.          dtemp = *dy;
  581.          *dy = *dx;
  582.          *dx = dtemp;
  583.          dx += incx;
  584.          dy += incy;
  585.       }
  586.    }
  587. }
  588. /* am keeping these temporarily here will do away with later on */
  589. #define               MAXIT     30
  590. #define               CASE1     1
  591. #define               CASE2     2
  592. #define               CASE3     3
  593. #define               CONVERGE  4
  594. /***********************************************************************
  595.  *                                                                     *
  596.  *                        qriter2()                                    *
  597.  *                                                                     *
  598.  ***********************************************************************/
  599. /***********************************************************************
  600.    Description
  601.    -----------
  602.    This function reduces an upper bidiagonal matrix B to diagonal form.
  603.    It is a C translation of a portion of DSVDC from Linpack.  In this 
  604.    version, vectors are accumulated and B is assumed to be a square matrix.
  605.    Parameters
  606.    ---------
  607.    (input)
  608.    n           order of B
  609.    s           linear array containing the diagonal elements of B
  610.    e           linear array containing the off-diagonal elements of B
  611.    (output)
  612.    s           contains the singular values of the original matrix B
  613.    up          2-dimensional array containing left singular vectors of B
  614.    vp          2-dimensional array containing right singular vectors of B
  615.    Functions called
  616.    --------------
  617.    BLAS         dscal, dswap, drot, drotg 
  618.    MISC         dmax
  619.  ***********************************************************************/
  620. void qriter2(long n, double *s, double *e, double **up, double **vp)
  621. {
  622.    long negligible, iter, m, mm1, k, l, qrcase;
  623.    double ztest, test, sl, g, t, smm1;
  624.    double f, t1, cs, sn, scale, sm, el, emm1, b, c, shift;
  625.    m     = n - 1;
  626.    iter  = 0;
  627.    while (m >= 0) {
  628.       if (iter >= MAXIT) return;
  629.       negligible = FALSE;
  630.       /* this portion of the code inspects for negligible elements
  631.        * in the s and e arrays.  On completion the variable qrcase
  632.        * is set as follows:
  633.        * qrcase = CASE1 if s[m] and e[l-1] are negligible and l < m
  634.        * qrcase = CASE2 if s[l] is negligible and l < m
  635.        * qrcase = CASE3 if s[l], ..., s[m] are not negligible (QR step),
  636.        *                e[l-1] is negligible and l < m
  637.        * qrcase = CONVERGENCE if e[m-1] is negligible */
  638.       for (l = m - 1; l >= 0; l--) {
  639.  test = fabs(s[l]) + fabs(s[l + 1]);
  640.  ztest = test + fabs(e[l]);
  641.  if (ztest == test) {
  642.     e[l] = ZERO;
  643.     negligible = TRUE;
  644.  }
  645.  if (negligible) break;
  646.       }
  647.       if (l == m - 1) qrcase = CONVERGE;
  648.       else {
  649.          negligible = FALSE;
  650.          for (k = m; k > l; k--) {
  651.     test = ZERO;
  652.     if (k != m) test += fabs(e[k]);
  653.     if (k != l + 1) test += fabs(e[k-1]);
  654.     ztest = test + fabs(s[k]);
  655.     if (ztest == test) {
  656.        s[k] = ZERO;
  657.        negligible = TRUE;
  658.     }
  659.     if (negligible) break;
  660.  }
  661.  if (k == l) qrcase = CASE3;
  662.  else if (k == m) qrcase = CASE1;
  663.  else {
  664.     qrcase = CASE2;
  665.     l = k;
  666.  }
  667.       }
  668.       l += 1;
  669.       switch(qrcase) {
  670.          /* deflate negligible s[m] */
  671.  case CASE1:    mm1 = m - 1;
  672. f = e[mm1];
  673. e[mm1] = ZERO;
  674. for (k = mm1; k >= l; k--) {
  675.    t1 = s[k];
  676.    drotg(&t1, &f, &cs, &sn);
  677.    s[k] = t1;
  678.    if (k != l) {
  679.       f = -sn * e[k - 1];
  680.       e[k - 1] *= cs;
  681.    }
  682.    drot(n, vp[k], vp[m], cs, sn);
  683.                         }
  684. break;
  685.          /* split at negligible s[l] */
  686.  case CASE2:    f = e[l - 1];
  687. e[l - 1] = ZERO;
  688. for (k = l; k <= m; k++) {
  689.    t1 = s[k];
  690.    drotg(&t1, &f, &cs, &sn);
  691.    s[k] = t1;
  692.    f = -sn * e[k];
  693.    e[k] *= cs;
  694.    drot(n, up[k], up[l - 1], cs, sn);
  695.                         }
  696. break;
  697.          /* perform one QR step */
  698.  case CASE3:    f = e[l - 1];
  699. /* calculate the shift */
  700. scale = dmax(fabs(s[m]), fabs(s[m - 1]));
  701. if (scale < fabs(e[m - 1])) scale = fabs(e[m - 1]);
  702. if (scale < fabs(s[l])) scale = fabs(s[l]);
  703. if (scale < fabs(e[l])) scale = fabs(e[l]);
  704. sm = s[m] / scale;
  705. smm1 = s[m - 1] / scale;
  706. emm1 = e[m - 1] / scale;
  707. sl = s[l] / scale;
  708. el = e[l] / scale;
  709. b = ((smm1 + sm) * (smm1 - sm) + emm1 * emm1) / 2.0;
  710. c = (sm * emm1);
  711. c *= c;
  712. shift = ZERO;
  713. if (b != ZERO || c !=ZERO) {
  714.    shift = sqrt(b * b + c);
  715.    if (b < ZERO) shift = -shift;
  716.    shift = c / (b + shift);
  717. }
  718. f = (sl + sm) * (sl - sm) + shift;
  719. g = sl * el;
  720. /* chase zeros */
  721. mm1 = m - 1;
  722. for (k = l; k <= mm1; k++) {
  723.    drotg(&f, &g, &cs, &sn);
  724.    if (k != l) e[k - 1] = f;
  725.    f = cs * s[k] + sn * e[k];
  726.    e[k] = cs * e[k] - sn * s[k];
  727.    g = sn * s[k + 1];
  728.    s[k + 1] = cs * s[k + 1];
  729.    drot(n, vp[k], vp[k + 1], cs, sn);
  730.    drotg(&f, &g, &cs, &sn);
  731.    s[k] = f;
  732.    f = cs * e[k] + sn * s[k + 1];
  733.    s[k + 1] = -sn * e[k] + cs * s[k + 1];
  734.    g = sn * e[k + 1];
  735.    e[k + 1] = cs * e[k + 1];
  736.    if (k < n - 1)
  737.       drot(n, up[k], up[k + 1], cs, sn);
  738. }
  739. e[mm1] = f;
  740. iter += 1;
  741. break;
  742.          /* convergence */
  743.  case CONVERGE: if (s[l] < ZERO) {
  744.    /* make singular value positive */
  745.                    s[l] = -s[l];
  746.    dscal (n, -ONE, vp[l], 1); 
  747.                         }
  748. /* order the singular value */
  749. while (l < n - 1) {
  750.    if (s[l] < s[l + 1]) {
  751.       t = s[l];
  752.       s[l] = s[l + 1];
  753.       s[l + 1] = t;
  754.       if (l < n - 1) 
  755.  dswap(n, vp[l], 1, vp[l + 1], 1);
  756.       if (l < n - 1) 
  757.  dswap(n, up[l], 1, up[l + 1], 1);
  758.                               l += 1;
  759.    }
  760.    else break;
  761. }
  762. iter = 0;
  763. m -= 1;
  764. break;
  765.       }
  766.    }
  767. }
  768. /***************************************************************** 
  769.  * applies a plane rotation;  assume a stride of 1 for dx and dy *
  770.  * based on FORTRAN 77 routine from Linpack by J. Dongarra       *
  771.  *****************************************************************/ 
  772. void drot(long n, double *dx, double *dy, double c, double s)
  773. {
  774.    long i;
  775.    double temp;
  776.    if (n <= 0) return;
  777.    for (i = 0; i < n; i++) {
  778.       temp = c * (*dx) + s * (*dy);
  779.       *dy = c * (*dy) - s * (*dx);
  780.       dy++;
  781.       *dx++ = temp;
  782.    }
  783.    return;
  784. }
  785. /***************************************************************** 
  786.  * constructs Givens plane rotation                              *
  787.  * based on FORTRAN 77 routine from Linpack by J. Dongarra       *
  788.  *****************************************************************/ 
  789. void drotg(double *da, double *db, double *c, double *s)
  790. {
  791.    double r, roe, scale, z, temp1, temp2;
  792.    roe = *db;
  793.    temp1 = fabs(*da);
  794.    temp2 = fabs(*db);
  795.    if (temp1 > temp2) roe = *da;
  796.    scale = temp1 + temp2;
  797.    if (scale != ZERO) {
  798.       temp1 = *da / scale;
  799.       temp2 = *db / scale;
  800.       r = scale * sqrt(temp1 * temp1 + temp2 * temp2);
  801.       r *= fsign(ONE, roe);
  802.       *c = *da / r;
  803.       *s = *db / r;
  804.    }
  805.    else {
  806.       *c = ONE;
  807.       *s = ZERO;
  808.       r = ZERO;
  809.    }
  810.    z = *s;
  811.    temp1 = fabs(*c);
  812.    if (temp1 > ZERO && temp1 <= *s) z = ONE / *c;
  813.    *da = r;
  814.    *db = z;
  815.    return;
  816. }
  817. /************************************************************** 
  818.  * Function forms the dot product of two vectors.             *
  819.  * Based on Fortran-77 routine from Linpack by J. Dongarra    *
  820.  **************************************************************/ 
  821. double ddot(long n,double *dx,long incx,double *dy,long incy)
  822. {
  823.    long i;
  824.    double dot_product;
  825.    if (n <= 0 || incx == 0 || incy == 0) return(0.0);
  826.    dot_product = 0.0;
  827.    if (incx == 1 && incy == 1) 
  828.       for (i=0; i < n; i++) dot_product += (*dx++) * (*dy++);
  829.    else {
  830.       if (incx < 0) dx += (-n+1) * incx;
  831.       if (incy < 0) dy += (-n+1) * incy;
  832.       for (i=0; i < n; i++) {
  833.          dot_product += (*dx) * (*dy);
  834.          dx += incx;
  835.          dy += incy;
  836.       }
  837.    }
  838.    return(dot_product);
  839. }
  840. /************************************************************** 
  841.  * Function scales a vector by a constant.            *
  842.  * Based on Fortran-77 routine from Linpack by J. Dongarra    *
  843.  **************************************************************/ 
  844. void dscal(long n,double da,double *dx,long incx)
  845. {
  846.    long i;
  847.    if (n <= 0 || incx == 0) return;
  848.    if (incx < 0) dx += (-n+1) * incx;
  849.    for (i=0; i < n; i++) {
  850.       *dx *= da;
  851.       dx += incx;
  852.    }
  853.    return;
  854. }
  855. /************************************************************** 
  856.  * Constant times a vector plus a vector            *
  857.  * Based on Fortran-77 routine from Linpack by J. Dongarra    *
  858.  **************************************************************/ 
  859. void daxpy (long n,double da,double *dx,long incx,double *dy,long incy)
  860. {
  861.    long i;
  862.    if (n <= 0 || incx == 0 || incy == 0 || da == 0.0) return;
  863.    if (incx == 1 && incy == 1) 
  864.       for (i=0; i < n; i++) {
  865.  *dy += da * (*dx++);
  866.  dy++;
  867.       }
  868.    else {
  869.       if (incx < 0) dx += (-n+1) * incx;
  870.       if (incy < 0) dy += (-n+1) * incy;
  871.       for (i=0; i < n; i++) {
  872.          *dy += da * (*dx);
  873.          dx += incx;
  874.          dy += incy;
  875.       }
  876.    }
  877.    return;
  878. }
  879. /***********************************************************************
  880.  *                                                                     *
  881.  * mrandom()                               *
  882.  *                        (double precision)                           *
  883.  ***********************************************************************/
  884. /***********************************************************************
  885.    Description
  886.    -----------
  887.    This is a translation of a Fortran-77 uniform random number
  888.    generator.  The code is based  on  theory and suggestions  given in
  889.    D. E. Knuth (1969),  vol  2.  The argument to the function should 
  890.    be initialized to an arbitrary integer prior to the first call to 
  891.    random.  The calling program should  not  alter  the value of the
  892.    argument between subsequent calls to random.  Random returns values
  893.    within the the interval (0,1).
  894.    Arguments 
  895.    ---------
  896.    (input)
  897.    iy    an integer seed whose value must not be altered by the caller
  898.    between subsequent calls
  899.    (output)
  900.    random  a double precision random number between (0,1)
  901.  ***********************************************************************/
  902. double mrandom(long *iy)
  903. {
  904.    static long m2 = 0;
  905.    static long ia, ic, mic;
  906.    static double halfm, s;
  907.    /* If first entry, compute (max int) / 2 */
  908.    if (!m2) {
  909.       m2 = 1 << (8 * (int)sizeof(int) - 2); 
  910.       halfm = m2;
  911.       /* compute multiplier and increment for linear congruential 
  912.        * method */
  913.       ia = 8 * (long)(halfm * atan(1.0) / 8.0) + 5;
  914.       ic = 2 * (long)(halfm * (0.5 - sqrt(3.0)/6.0)) + 1;
  915.       mic = (m2-ic) + m2;
  916.       /* s is the scale factor for converting to floating point */
  917.       s = 0.5 / halfm;
  918.    }
  919.    /* compute next random number */
  920.    *iy = *iy * ia;
  921.    /* for computers which do not allow integer overflow on addition */
  922.    if (*iy > mic) *iy = (*iy - m2) - m2;
  923.    *iy = *iy + ic;
  924.    /* for computers whose word length for addition is greater than
  925.     * for multiplication */
  926.    if (*iy / 2 > m2) *iy = (*iy - m2) - m2;
  927.   
  928.    /* for computers whose integer overflow affects the sign bit */
  929.    if (*iy < 0) *iy = (*iy + m2) + m2;
  930.    return((double)(*iy) * s);
  931. }
  932. /************************************************************** 
  933.  * Function copies a vector x to a vector y             *
  934.  * Based on Fortran-77 routine from Linpack by J. Dongarra    *
  935.  **************************************************************/ 
  936. void dcopy(long n,double *dx,long incx,double *dy,long incy)
  937. {
  938.    long i;
  939.    if (n <= 0 || incx == 0 || incy == 0) return;
  940.    if (incx == 1 && incy == 1) 
  941.       for (i=0; i < n; i++) *dy++ = *dx++;
  942.    else {
  943.       if (incx < 0) dx += (-n+1) * incx;
  944.       if (incy < 0) dy += (-n+1) * incy;
  945.       for (i=0; i < n; i++) {
  946.          *dy = *dx;
  947.          dx += incx;
  948.          dy += incy;
  949.       }
  950.    }
  951.    return;
  952. }
  953. /***********************************************************************
  954.  *                                                                     *
  955.  *                         dgemm2()                                    *
  956.  *                                                                     *
  957.  * A C-translation of the level 3 BLAS routine DGEMM by Dongarra,      *
  958.  * Duff, du Croz, and Hammarling (see LAPACK Users' Guide).            *
  959.  * In this version, the arrays which store the matrices used in this   *
  960.  * matrix-matrix multiplication are accessed as two-dimensional arrays.*
  961.  *                                                                     *
  962.  ***********************************************************************/
  963. /***********************************************************************
  964.    Description
  965.    -----------
  966.    dgemm2() performs one of the matrix-matrix operations
  967.       C := alpha * op(A) * op(B) + beta * C,
  968.    where op(X) = X or op(X) = X', alpha and beta are scalars, and A, B
  969.    and C are matrices, with op(A) an m by k matrix, op(B) a k by n
  970.    matrix and C an m by n matrix.
  971.    Parameters
  972.    ----------
  973.    (input)
  974.    transa   TRANSP indicates op(A) = A' is to be used in the multiplication
  975.     NTRANSP indicates op(A) = A is to be used in the multiplication
  976.    transb   TRANSP indicates op(B) = B' is to be used in the multiplication
  977.     NTRANSP indicates op(B) = B is to be used in the multiplication
  978.    m        on entry, m specifies the number of rows of the matrix op(A)
  979.     and of the matrix C.  m must be at least zero.  Unchanged
  980.     upon exit.
  981.    n        on entry, n specifies the number of columns of the matrix op(B)
  982.     and of the matrix C.  n must be at least zero.  Unchanged
  983.     upon exit.
  984.    k        on entry, k specifies the number of columns of the matrix op(A)
  985.     and the number of rows of the matrix B.  k must be at least 
  986.     zero.  Unchanged upon exit.
  987.    alpha    a scalar multiplier
  988.    a        matrix A as a 2-dimensional array.  When transa = NTRANSP, the
  989.             leading m by k part of a must contain the matrix A. Otherwise,
  990.     the leading k by m part of a must contain  the matrix A.
  991.    b        matrix B as a 2-dimensional array.  When transb = NTRANSP, the
  992.             leading k by n part of a must contain the matrix B. Otherwise,
  993.     the leading n by k part of a must contain  the matrix B.
  994.    beta     a scalar multiplier.  When beta is supplied as zero then C
  995.     need not be set on input.
  996.    c        matrix C as a 2-dimensional array.  On entry, the leading
  997.     m by n part of c must contain the matrix C, except when
  998.     beta = 0.  In that case, c need not be set on entry. 
  999.     On exit, c is overwritten by the m by n matrix
  1000.     (alpha * op(A) * op(B) + beta * C).
  1001.  ***********************************************************************/
  1002. void dgemm2(long transa, long transb, long m, long n, long k, 
  1003.             double alpha, double **a, double **b, double beta, double **c)
  1004. {
  1005.    long info;
  1006.    long i, j, l, nrowa, ncola, nrowb, ncolb;
  1007.    double temp, *atemp;
  1008.    info = 0;
  1009.    if      ( transa != TRANSP && transa != NTRANSP ) info = 1;
  1010.    else if ( transb != TRANSP && transb != NTRANSP ) info = 2;
  1011.    else if ( m < 0 )       info = 3;
  1012.    else if ( n < 0 )      info = 4;
  1013.    else if ( k < 0 )              info = 5;
  1014.    if (info) {
  1015.       fprintf(stderr, "%s %1d %sn",
  1016.       "*** ON ENTRY TO DGEMM2, PARAMETER NUMBER",info,"HAD AN ILLEGAL VALUE");
  1017.       exit(info);
  1018.    }
  1019.    if (transa) {
  1020.       nrowa = k;
  1021.       ncola = m;
  1022.    }
  1023.    else { 
  1024.       nrowa = m;
  1025.       ncola = k;
  1026.    }
  1027.    if (transb) {
  1028.       nrowb = n;
  1029.       ncolb = k;
  1030.    }
  1031.    else {
  1032.       nrowb = k;
  1033.       ncolb = n;
  1034.    }
  1035.    if (!m || !n || ((alpha == ZERO || !k) && beta == ONE))
  1036.       return;
  1037.    if (alpha == ZERO) {
  1038.       if (beta == ZERO) 
  1039.          for (i = 0; i < m; i++)
  1040.             for (j = 0; j < n; j++) c[i][j] = ZERO;
  1041.       else if (beta != ONE)
  1042.          for (i = 0; i < m; i++)
  1043.             for (j = 0; j < n; j++) c[i][j] *= beta;
  1044.       return;
  1045.    }
  1046.    if (beta == ZERO)
  1047.       for (i = 0; i < m; i++)
  1048.          for (j = 0; j < n; j++) c[i][j] = ZERO;
  1049.    else if (beta != ONE)
  1050.       for (i = 0; i < m; i++)
  1051.          for (j = 0; j < n; j++) c[i][j] *= beta;
  1052.    if (!transb) { 
  1053.       switch(transa) {
  1054.  /* form C := alpha * A * B + beta * C */
  1055.  case NTRANSP:  for(l = 0; l < nrowa; l++) {
  1056.                            atemp = *a++;
  1057.              for(j = 0; j < ncola; j++) {
  1058.               temp = *atemp * alpha;
  1059.                       for(i = 0; i < ncolb; i++) 
  1060.       c[l][i] += temp * b[j][i];
  1061.               atemp++;
  1062.              }
  1063.                  }
  1064. break;
  1065.  /* form C := alpha * A' * B + beta * C */
  1066.  case TRANSP:   for(l = 0; l < nrowa; l++) {
  1067.                            atemp = *a++;
  1068.              for(j = 0; j < ncola; j++) {
  1069.               temp = *atemp * alpha;
  1070.                       for(i = 0; i < ncolb; i++) 
  1071.       c[j][i] += temp * b[l][i];
  1072.               atemp++;
  1073.              }
  1074.          }
  1075. break;
  1076.       }
  1077.    }
  1078.    else { 
  1079.       switch(transa) {
  1080.  /* form C := alpha * A * B' + beta * C */
  1081.  case NTRANSP: for(l = 0; l < nrowa; l++) {
  1082.              for(j = 0; j < nrowb; j++) {
  1083.               atemp = *a;
  1084.                       for(i = 0; i < ncolb; i++) 
  1085.       c[l][j] += (*atemp++) * alpha * b[j][i];
  1086.              }
  1087.    a++;
  1088.          }
  1089. break;
  1090.  /* form C := alpha * A' * B' + beta * C */
  1091.  case TRANSP:   for(i = 0; i < ncola; i++) {
  1092.    for (l = 0; l < nrowb; l++) {
  1093.                      temp = ZERO;
  1094.         for(j = 0; j < nrowa; j++) 
  1095.  temp += a[j][i] * b[l][j];
  1096.                               c[i][l] += alpha * temp;
  1097.    }
  1098.          }
  1099. break;
  1100.       }
  1101.    }
  1102. }
  1103. /***********************************************************************
  1104.  *                                                                     *
  1105.  *                          dsbmv()                                    *
  1106.  *                                                                     *
  1107.  ***********************************************************************/
  1108. /***********************************************************************
  1109.    Description
  1110.    -----------
  1111.    The function performs the matrix-vector operation
  1112.   y := alpha * A * y + beta * y,
  1113.    where alpha and beta are scalars, x and y are n-element vectors and
  1114.    A is an n by n symmetric band matrix, with k super-diagonals.
  1115.    Parameters
  1116.    ----------
  1117.    n         number of rows of matrix A; n must be at least 0.  Unchanged
  1118.      upon exit.
  1119.    k         number of super-diagonals of matrix A
  1120.    a         2-dimensional array whose leading n by (k + 1) part must 
  1121.      contain the upper triangular band part of the symmetric matrix,
  1122.      supplied row by row, with the leading diagonal of the matrix 
  1123.      in column (k + 1) of the array, the first super-diagonal 
  1124.      starting at position 2 in column k, and so on.
  1125.      The top left k by k triangle of the array A is not referenced.
  1126.    x         linear array of dimension of at least n.  Before entry,
  1127.      x must contain the n elements of vector x.  Unchanged on exit.
  1128.    y         linear array of dimension of at least n.  Before entry,
  1129.      y must contain the n elements of vector y.  On exit, y is
  1130.      overwritten by the updated vector y.
  1131.    Functions called
  1132.    --------------
  1133.    MISC      imax  
  1134.  ***********************************************************************/
  1135. void dsbmv(long n, long k, double alpha, double **a, 
  1136.            double *x, double beta, double *y)
  1137. {
  1138.    long info, j, i, l;
  1139.    double *ptrtemp, temp1, temp2;
  1140.    info = 0;
  1141.    if ( n < 0 )                                      info = 1;
  1142.    else if ( k < 0 )                                 info = 2;
  1143.    if (info) {
  1144.       fprintf(stderr, "%s %1d %sn",
  1145.       "*** ON ENTRY TO DSBMV, PARAMETER NUMBER",info,"HAD AN ILLEGAL VALUE");
  1146.       exit(info);
  1147.    }
  1148.    if (!n || (alpha == ZERO && beta == ONE))
  1149.       return;
  1150.    ptrtemp = y; 
  1151.    /* form y := beta * y */
  1152.    if (beta == ZERO) 
  1153.       for (i = 0; i < n; i++) *ptrtemp++ = ZERO;
  1154.    else if (beta != ONE) 
  1155.       for (i = 0; i < n; i++) *ptrtemp++ *= beta;
  1156.    if (alpha == ZERO) return;
  1157.    for (j = 0; j < n; j++) {
  1158.       temp1 = alpha * x[j];
  1159.       temp2 = ZERO;
  1160.       l = k - j;
  1161.       for (i = imax(0, j - k); i < j; i++) {
  1162.          y[i] = y[i] + temp1 * a[j][l+i];
  1163.          temp2 = temp2 + a[j][l+i] * x[i];
  1164.       }
  1165.       y[j] = y[j] + temp1 * a[j][k] + alpha * temp2;
  1166.    }
  1167. }
  1168. /***********************************************************************
  1169.  *                                                                     *
  1170.  * tql2()           *
  1171.  *                                                                     *
  1172.  ***********************************************************************/
  1173. /***********************************************************************
  1174.    Description
  1175.    -----------
  1176.    tql2() is a translation of a Fortran version of the Algol
  1177.    procedure TQL2, Num. Math. 11, 293-306(1968) by Dowdler, Martin, 
  1178.    Reinsch and Wilkinson.
  1179.    Handbook for Auto. Comp., vol.II-Linear Algebra, 227-240(1971).  
  1180.    This function finds the eigenvalues and eigenvectors of a symmetric
  1181.    tridiagonal matrix by the QL method.
  1182.    Arguments
  1183.    ---------
  1184.    (input)                                                             
  1185.    n      order of the symmetric tridiagonal matrix           
  1186.    d      contains the diagonal elements of the input matrix        
  1187.    e      contains the subdiagonal elements of the input matrix in its
  1188.             first n-1 positions.
  1189.    z      contains the identity matrix     
  1190.                                                                    
  1191.    (output)                                                       
  1192.    d      contains the eigenvalues in ascending order.  if an error
  1193.             exit is made, the eigenvalues are correct but unordered for
  1194.             for indices 0,1,...,ierr.    
  1195.    e      has been destroyed.   
  1196.    z      contains orthonormal eigenvectors of the symmetric   
  1197.             tridiagonal (or full) matrix.  if an error exit is made,
  1198.             z contains the eigenvectors associated with the stored 
  1199.           eigenvalues.
  1200.    ierr   set to zero for normal return, j if the j-th eigenvalue has
  1201.             not been determined after 30 iterations.     
  1202.    Functions used
  1203.    --------------
  1204.    UTILITY fsign
  1205.    MISC pythag
  1206.  ***********************************************************************/
  1207. long tql2(long n, double *d, double *e, double **z)
  1208. {
  1209.    long j, last, l, l1, l2, m, i, k, iteration;
  1210.    double tst1, tst2, g, r, s, s2, c, c2, c3, p, f, h, el1, dl1;
  1211.    if (n == 1) return(0);
  1212.    f = ZERO;
  1213.    last = n - 1;
  1214.    tst1 = ZERO;
  1215.    e[last] = ZERO;
  1216.    for (l = 0; l < n; l++) {
  1217.       iteration = 0;
  1218.       h = fabs(d[l]) + fabs(e[l]);
  1219.       if (tst1 < h) tst1 = h;
  1220.       /* look for small sub-diagonal element */
  1221.       for (m = l; m < n; m++) {
  1222.  tst2 = tst1 + fabs(e[m]);
  1223.  if (tst2 == tst1) break;
  1224.       }
  1225.       if (m != l) {
  1226.  while (iteration < 30) {
  1227.     iteration += 1;
  1228.             /*  form shift */
  1229.     l1 = l + 1;
  1230.     l2 = l1 + 1;
  1231.     g = d[l];
  1232.             p = (d[l1] - g) / (2.0 * e[l]);
  1233.     r = pythag(p, ONE);
  1234.     d[l] = e[l] / (p + fsign(r, p));
  1235.     d[l1] = e[l] * (p + fsign(r, p));
  1236.     dl1 = d[l1];
  1237.     h = g - d[l];
  1238.     if (l2 < n) 
  1239.        for (i = l2; i < n; i++) d[i] -= h;
  1240.             f += h;
  1241.     /* QL transformation */
  1242.     p = d[m];
  1243.     c = ONE;
  1244.     c2 = c;
  1245.     el1 = e[l1];
  1246.     s = ZERO;
  1247.     i = m - 1;
  1248.     while (i >= l) {
  1249.        c3 = c2;
  1250.        c2 = c;
  1251.        s2 = s;
  1252.        g = c * e[i];
  1253.        h = c * p;
  1254.        r = pythag(p, e[i]);
  1255.        e[i + 1] = s * r;
  1256.        s = e[i] / r;
  1257.        c = p / r;
  1258.        p = c * d[i] - s * g;
  1259.        d[i + 1]= h + s * (c * g + s * d[i]);
  1260.        /*  form vector */
  1261.        for (k = 0; k < n; k ++) {
  1262.           h = z[i + 1][k];
  1263.           z[i + 1][k] = s * z[i][k] + c * h;
  1264.           z[i][k] = c * z[i][k] - s * h;
  1265.        }
  1266.        i--;
  1267.     }
  1268.     p = -s * s2 * c3 *el1 * e[l] / dl1;
  1269.     e[l] = s * p;
  1270.     d[l] = c * p;
  1271.     tst2 = tst1 + fabs(e[l]);
  1272.     if (tst2 <= tst1) break;
  1273.     if (iteration == 30) 
  1274.        return(l);
  1275.          }
  1276.       }
  1277.       d[l] += f;
  1278.    }
  1279.    /* order the eigenvalues */
  1280.    for (l = 1; l < n; l++) {
  1281.       i = l - 1;
  1282.       k = i;
  1283.       p = d[i];
  1284.       for (j = l; j < n; j++) {
  1285.  if (d[j] < p) {
  1286.     k = j;
  1287.     p = d[j];
  1288.  }
  1289.       }
  1290.       /* ...and corresponding eigenvectors */
  1291.       if (k != i) {
  1292.  d[k] = d[i];
  1293.  d[i] = p;
  1294.   for (j = 0; j < n; j ++) {
  1295.      p = z[i][j];
  1296.      z[i][j] = z[k][j];
  1297.      z[k][j] = p;
  1298.   }
  1299.       }   
  1300.    }
  1301.    return(0);
  1302. }
  1303. double pythag(double a, double b)
  1304. {
  1305.    double p, r, s, t, u, temp;
  1306.    p = dmax(fabs(a), fabs(b));
  1307.    if (p != 0.0) {
  1308.       temp = dmin(fabs(a), fabs(b)) / p;
  1309.       r = temp * temp; 
  1310.       t = 4.0 + r;
  1311.       while (t != 4.0) {
  1312.  s = r / t;
  1313.  u = 1.0 + 2.0 * s;
  1314.  p *= u;
  1315.  temp = s / u;
  1316.  r *= temp * temp;
  1317.  t = 4.0 + r;
  1318.       }
  1319.    }
  1320.    return(p);
  1321. }
  1322. /**************************************************************
  1323.  *                                                            *
  1324.  * multiplication of A'A by the transpose of an nc by n       *
  1325.  * matrix X.  A is nrow by ncol and is stored using the       *
  1326.  * Harwell-Boeing compressed column sparse matrix format.     *
  1327.  * The transpose of the n by nc product matrix Y is returned  *
  1328.  * in the two-dimensional array y.                            *
  1329.  *                                                            *
  1330.  *              Y = A'A * X'  and  y := Y'                    *
  1331.  *                                                            *
  1332.  **************************************************************/
  1333. void opm(long nrow, long ncol, long nc, double **x, double **y)
  1334. {
  1335.    long i, j, k, end;
  1336.    
  1337.    mxvcount  += nc;
  1338.    mtxvcount += nc;
  1339.    for (i = 0; i < nc; i++) 
  1340.       for (j = 0; j < nrow; j++) ztempp[i][j] = ZERO;
  1341.    for (i = 0; i < nc; i++) 
  1342.       for (j = 0; j < ncol; j++) y[i][j] = ZERO;
  1343.    /* multiply by sparse matrix A */
  1344.    for (i = 0; i < ncol; i++) {
  1345.       end = pointr[i+1];
  1346.       for (j = pointr[i]; j < end; j++)
  1347.          for (k = 0; k < nc; k++)
  1348.     ztempp[k][rowind[j]] += value[j] * x[k][i]; 
  1349.    }
  1350.    /* multiply by transpose of A (A') */
  1351.    for (k = 0; k < nc; k++)
  1352.       for (i = 0; i < ncol; i++) {
  1353.          end = pointr[i+1];
  1354.          for (j = pointr[i]; j < end; j++) 
  1355.     y[k][i] += value[j] * ztempp[k][rowind[j]];
  1356.       }
  1357.    return;
  1358. }
  1359. /**************************************************************
  1360.  *                                                            *
  1361.  * multiplication of matrix B by vector x, where B = A'A,     *
  1362.  * and A is nrow by ncol (nrow >> ncol) and is stored using   *
  1363.  * the Harwell-Boeing compressed column sparse matrix format. *
  1364.  * Hence, B is of order n = ncol.  y stores product vector.   *
  1365.  *                                                            *
  1366.  **************************************************************/
  1367. void opb(long nrow, long ncol, double *x, double *y)
  1368. {
  1369.    long i, j, end;
  1370.    
  1371.    mxvcount += 1;
  1372.    mtxvcount += 1;
  1373.    for (i = 0; i < ncol; i++) y[i] = ZERO;
  1374.    for (i = 0; i < nrow; i++) ztemp[i] = ZERO;
  1375.    for (i = 0; i < ncol; i++) {
  1376.       end = pointr[i+1];
  1377.       for (j = pointr[i]; j < end; j++) 
  1378.  ztemp[rowind[j]] += value[j] * (*x); 
  1379.       x++;
  1380.    }
  1381.    for (i = 0; i < ncol; i++) {
  1382.       end = pointr[i+1];
  1383.       for (j = pointr[i]; j < end; j++) 
  1384.  *y += value[j] * ztemp[rowind[j]];
  1385.       y++;
  1386.    }
  1387.    return;
  1388. }
  1389. /********************************************************************* 
  1390.  * Function sorts array1 and array2 into increasing order for array1 *
  1391.  *********************************************************************/
  1392. void dsort2(long igap,long n,double *array1,double *array2)
  1393. {
  1394.     double temp;
  1395.     long i, j, index;
  1396.     if (!igap) return;
  1397.     else {
  1398. for (i = igap; i < n; i++) {
  1399.     j = i - igap;
  1400.     index = i;
  1401.     while (j >= 0 && array1[j] > array1[index]) {
  1402. temp = array1[j];
  1403. array1[j] = array1[index];
  1404. array1[index] = temp;
  1405. temp = array2[j];
  1406. array2[j] = array2[index];
  1407. array2[index] = temp;
  1408.         j -= igap;
  1409. index = j + igap;
  1410.     }
  1411.     }
  1412.     dsort2(igap/2,n,array1,array2);
  1413. }
  1414. /**************************************************************
  1415.  * multiplication of matrix B by vector x, where B = A'A,     *
  1416.  * and A is nrow by ncol (nrow >> ncol). Hence, B is of order *
  1417.  * n = ncol (y stores product vector).               *
  1418.  **************************************************************/
  1419. void opb(long n, double *x, double *y, bool flag)
  1420. {
  1421.    long i, j, end;
  1422.    
  1423.    mxvcount += 2;
  1424.    for (i = 0; i < n; i++) y[i] = 0.0;
  1425.    for (i = 0; i < nrow; i++) ztemp[i] = 0.0;
  1426.    for (i = 0; i < ncol; i++) {
  1427.       end = pointr[i+1];
  1428.       for (j = pointr[i]; j < end; j++) 
  1429.  ztemp[rowind[j]] += value[j] * (*x); 
  1430.       x++;
  1431.    }
  1432.    for (i = 0; i < ncol; i++) {
  1433.       end = pointr[i+1];
  1434.       for (j = pointr[i]; j < end; j++) 
  1435.  *y += value[j] * ztemp[rowind[j]];
  1436.       y++;
  1437.    }
  1438.    return;
  1439. }
  1440. double norm_1()
  1441. {
  1442. /* find matrix 1-norm  */
  1443.     double alpha,sum;
  1444.     long i,j,last;
  1445.     alpha = 0.0;
  1446.     for (j=0; j<ncol; ++j) {
  1447.         sum = 0.0;
  1448.         last= pointr[j+1];
  1449.         for (i=pointr[j]; i<last ; ++i)
  1450.             sum += fabs(value[i]);
  1451.         alpha = dmax(alpha,sum);
  1452.     }
  1453.     return(alpha);
  1454. }
  1455. /************************************************************** 
  1456.  * multiplication of 2-cyclic matrix B by a vector x, where   *
  1457.  *       *
  1458.  * B = [0  A]       *
  1459.  *     [A' 0] , where A is nrow by ncol (nrow >> ncol). Hence,*
  1460.  * B is of order n = nrow+ncol (y stores product vector).     *
  1461.  **************************************************************/ 
  1462. void opb(long n,double *x, double *y)
  1463. {
  1464.    long i, j, end;
  1465.    double *tmp;
  1466.    
  1467.    mxvcount += 2;
  1468.    for (i = 0; i < n; i++) y[i] = 0.0;
  1469.    tmp = &x[nrow]; 
  1470.    for (i = 0; i < ncol; i++) {
  1471.       end = pointr[i+1];
  1472.       for (j = pointr[i]; j < end; j++) 
  1473.  y[rowind[j]] += value[j] * (*tmp); 
  1474.       tmp++; 
  1475.    }
  1476.    for (i = nrow; i < n; i++) {
  1477.       end = pointr[i-nrow+1];
  1478.       for (j = pointr[i-nrow]; j < end; j++) 
  1479.  y[i] += value[j] * x[rowind[j]];
  1480.    }
  1481.    return;
  1482. }
  1483. /************************************************************** 
  1484.  * function scales a vector by a constant.             *
  1485.  * Based on Fortran-77 routine from Linpack by J. Dongarra    *
  1486.  **************************************************************/ 
  1487. void datx(long n,double da,double *dx,long incx,double *dy,long incy)
  1488. {
  1489.    long i;
  1490.    if (n <= 0 || incx == 0 || incy == 0 || da == 0.0) return;
  1491.    if (incx == 1 && incy == 1) 
  1492.       for (i=0; i < n; i++) *dy++ = da * (*dx++);
  1493.    else {
  1494.       if (incx < 0) dx += (-n+1) * incx;
  1495.       if (incy < 0) dy += (-n+1) * incy;
  1496.       for (i=0; i < n; i++) {
  1497.          *dy = da * (*dx);
  1498.          dx += incx;
  1499.          dy += incy;
  1500.       }
  1501.    }
  1502.    return;
  1503. }
  1504. /***********************************************************************
  1505.  *                                                                     *
  1506.  *                         dgemm3()                                    *
  1507.  *                                                                     *
  1508.  * A C-translation of the level 3 BLAS routine DGEMM by Dongarra,      *
  1509.  * Duff, du Croz, and Hammarling (see LAPACK Users' Guide).            *
  1510.  * In this version, the arrays which store the matrices used in this   *
  1511.  * matrix-matrix multiplication are accessed as two-dimensional arrays.*
  1512.  *                                                                     *
  1513.  ***********************************************************************/
  1514. /***********************************************************************
  1515.    Description
  1516.    -----------
  1517.    dgemm3() performs one of the matrix-matrix operations
  1518.       C := alpha * op(A) * op(B) + beta * C,
  1519.    where op(X) = X or op(X) = X', alpha and beta are scalars, and A, B
  1520.    and C are matrices, with op(A) an m by k matrix, op(B) a k by n
  1521.    matrix and C an m by n matrix.
  1522.    Parameters
  1523.    ----------
  1524.    (input)
  1525.    transa   TRANSP indicates op(A) = A' is to be used in the multiplication
  1526.     NTRANSP indicates op(A) = A is to be used in the multiplication
  1527.    transb   TRANSP indicates op(B) = B' is to be used in the multiplication
  1528.     NTRANSP indicates op(B) = B is to be used in the multiplication
  1529.    m        on entry, m specifies the number of rows of the matrix op(A)
  1530.     and of the matrix C.  m must be at least zero.  Unchanged
  1531.     upon exit.
  1532.    n        on entry, n specifies the number of columns of the matrix op(B)
  1533.     and of the matrix C.  n must be at least zero.  Unchanged
  1534.     upon exit.
  1535.    k        on entry, k specifies the number of columns of the matrix op(A)
  1536.     and the number of rows of the matrix B.  k must be at least 
  1537.     zero.  Unchanged upon exit.
  1538.    alpha    a scalar multiplier
  1539.    a        matrix A as a 2-dimensional array.  When transa = NTRANSP, the
  1540.             leading m by k part of a must contain the matrix A. Otherwise,
  1541.     the leading k by m part of a must contain  the matrix A.
  1542.    ira,ica  row and column indices of matrix a, where mxn part starts.
  1543.    b        matrix B as a 2-dimensional array.  When transb = NTRANSP, the
  1544.             leading k by n part of a must contain the matrix B. Otherwise,
  1545.     the leading n by k part of a must contain  the matrix B.
  1546.    irb,icb  row and column indices of matrix b, where kxn starts.
  1547.    beta     a scalar multiplier.  When beta is supplied as zero then C
  1548.     need not be set on input.
  1549.    c        matrix C as a 2-dimensional array.  On entry, the leading
  1550.     m by n part of c must contain the matrix C, except when
  1551.     beta = 0.  In that case, c need not be set on entry. 
  1552.     On exit, c is overwritten by the m by n matrix
  1553.     (alpha * op(A) * op(B) + beta * C).
  1554.    irc,icc  row and column indices of matrix c, where the mxn part is stored.
  1555. ***********************************************************************/
  1556. void dgemm3(long transa, long transb, long m, long n, long k, 
  1557.             double alpha, double **a, long ira, long ica, double **b,
  1558.             long irb, long icb, double beta, double **c, long irc,
  1559.             long icc)
  1560. {
  1561.    long info;
  1562.    long i, j, l, nrowa, ncola, nrowb, ncolb;
  1563.    double temp;
  1564.    info = 0;
  1565.    if      ( transa != TRANSP && transa != NTRANSP ) info = 1;
  1566.    else if ( transb != TRANSP && transb != NTRANSP ) info = 2;
  1567.    else if ( m < 0 )       info = 3;
  1568.    else if ( n < 0 )      info = 4;
  1569.    else if ( k < 0 )              info = 5;
  1570.    if (info) {
  1571.       fprintf(stderr, "%s %1ld %sn",
  1572.       "*** ON ENTRY TO DGEMM3, PARAMETER NUMBER",info,"HAD AN ILLEGAL VALUE");
  1573.       exit(info);
  1574.    }
  1575.    if (transa) {
  1576.       nrowa = m;
  1577.       ncola = k;
  1578.    }
  1579.    else { 
  1580.       nrowa = k;
  1581.       ncola = m;
  1582.    }
  1583.    if (transb) {
  1584.       nrowb = k;
  1585.       ncolb = n;
  1586.    }
  1587.    else {
  1588.       nrowb = n;
  1589.       ncolb = k;
  1590.    }
  1591.    if (!m || !n || ((alpha == ZERO || !k) && beta == ONE))
  1592.       return;
  1593.    if (alpha == ZERO) {
  1594.       if (beta == ZERO) 
  1595.          for (j = 0; j < n; j++)
  1596.             for (i = 0; i < m; i++) c[icc+j][irc+i] = ZERO;
  1597.       else 
  1598.          for (j = 0; j < n; j++)
  1599.              for (i = 0; i < m; i++) c[icc+j][irc+i] *= beta;
  1600.       return;
  1601.    }
  1602.    if (!transb) { 
  1603.       switch(transa) {
  1604.  /* form C := alpha * A * B + beta * C */
  1605.  case NTRANSP: for(j = 0; j < n; j++) {
  1606.                           for(i=0; i<m; i++) c[icc+j][irc+i]=0.0;
  1607.                           for(l=0; l<k; l++) 
  1608.                              if(b[icb+j][irb+l]!=0.0) {
  1609.                                temp = alpha*b[icb+j][irb+l];
  1610.                                for(i=0; i<m; i++) 
  1611.                                 c[icc+j][irc+i] += temp*a[ica+l][ira+i];
  1612.                 }
  1613.                         }
  1614. break;
  1615.  /* form C := alpha * A' * B + beta * C */
  1616.  case TRANSP:   for(j = 0; j < n; j++) {
  1617.                            for(i=0; i<m; i++) {
  1618.                               temp = 0.0;
  1619.                 for(l = 0; l< k;l++) 
  1620.                                  temp += a[ica+i][ira+l]*b[icb+j][irb+l];
  1621.                               if(beta==0.0) c[icc+j][irc+i]=alpha*temp; 
  1622.                               else 
  1623.                        c[icc+j][irc+i] = alpha*temp + beta*c[icc+j][irc+i];
  1624.              }
  1625.          }
  1626. break;
  1627.       }
  1628.    }
  1629.    else { 
  1630.       switch(transa) {
  1631.  /* form C := alpha * A * B' + beta * C */
  1632.  case NTRANSP: for(j=0; j<n; j++) {
  1633.              for(i=0; i<m; i++) c[icc+j][irc+i]=ZERO;
  1634.              for(l=0; l<k; l++) {
  1635.               temp = alpha*b[l+icb][j+irb];
  1636.                       for(i=0; i<m; i++) 
  1637.       c[j+icc][i+irc] += temp*a[l+ica][i+ira];
  1638.              }
  1639.          }
  1640. break;
  1641.  /* form C := alpha * A' * B' + beta * C */
  1642.  case TRANSP:   for(j=0; j<n; j++) {
  1643.    for (i=0; i<m; i++) {
  1644.                      temp = ZERO;
  1645.         for(l=0; l<k; l++) 
  1646.  temp += a[i+ica][l+ira]*b[l+icb][j+irb];
  1647.                               if(!beta) c[j+icc][i+irc] += alpha * temp;
  1648.                               else 
  1649.                                  c[j+icc][i+irc]= alpha*temp+
  1650.                                                   beta*c[j+icc][i+irc];
  1651.    }
  1652.          }
  1653. break;
  1654.       }
  1655.    }
  1656. }
  1657. void opat(double *x, double *y)
  1658. {
  1659.   /*  multiplication of transpose (nrow by ncol sparse matrix A)
  1660.     by the vector x, store in y  */
  1661.   long i,j,upper;
  1662.   for(i=0; i<ncol; i++)
  1663.      y[i]=ZERO;
  1664.   for(i=0; i<ncol; i++) {
  1665.      upper = pointr[i+1];
  1666.      for(j=pointr[i]; j<upper; j++)
  1667.         y[i] += value[j]*x[rowind[j]];
  1668.   }
  1669.   return;
  1670. }
  1671. double dasum(long n, double *dx, long incx)
  1672. {
  1673.   /**************************************************************
  1674.    *  Function forms the sum of the absolute values.            *
  1675.    *  Uses unrolled loops for increment equal to one.           *
  1676.    *  Based on Fortran-77 routine from Linpack by J.Dongarra.
  1677.    **************************************************************/
  1678.   double dtemp,dsum;
  1679.   long   i,ix,m,mp1;
  1680.   dsum = ZERO;
  1681.   dtemp = ZERO;
  1682.   if(n <= 0) return 0;
  1683.   if(incx != 1) {
  1684.   /* code for increment not equal to 1 */
  1685.     ix = 0;
  1686.     if(incx < 0) ix = (-n+1)*incx + 1;
  1687.     for(i=0; i<n; i++) {
  1688.        dtemp += fabs(dx[ix]);
  1689.        ix    += incx;
  1690.     }
  1691.     dsum = dtemp;
  1692.     return(dsum);
  1693.   }  
  1694.   /* code for increment equal to 1 */
  1695.   
  1696.   /* clean-up loop */
  1697.   m = n % 6;
  1698.   if(m) {
  1699.     for(i=0; i<m; i++)
  1700.        dtemp += fabs(dx[i]);
  1701.   }
  1702.   if(n>=6) {
  1703.     for(i=m; i<n; i+=6)
  1704.        dtemp += fabs(dx[i]) + fabs(dx[i+1]) + fabs(dx[i+2]) +
  1705.                 fabs(dx[i+3]) + fabs(dx[i+4]) + fabs(dx[i+5]);
  1706.   }
  1707.   dsum = dtemp;
  1708.   return(dsum);
  1709. }
  1710. /***********************************************************************
  1711.  *                                                                     *
  1712.  *                              tred2()                                *
  1713.  *                                                                     *
  1714.  ***********************************************************************/
  1715. /***********************************************************************
  1716.   Description
  1717.   -----------
  1718.   
  1719.   tred2() is a translation of the algol procedure TRED2, Num. Math. 11, 
  1720.   181-195 (1968) by Martin, Reinsch, and Wikinson.  Handbook for Auto.
  1721.   Comp., Vol. II- Linear Algebra, 212-226 (1971)
  1722.   This subroutine reduces a real symmetric matrix to a symmetric
  1723.   tridiagonal matrix using and accumulating orthogonal similarity
  1724.   transformations.
  1725.   Arguments
  1726.   ---------
  1727.   (input)
  1728.   offset index of the leading element of the matrix to be
  1729.          tridiagonalized. The matrix tridiagonalized should be 
  1730.          stored in a[offset:n-1, offset:n-1]
  1731.   n  order of the matrix
  1732.   a  contains the real symmetric input matrix. Only the upper
  1733.  triangle of the matrix need be supplied
  1734.   (output)
  1735.   d  contains the diagonal elements of the tridiagonal matrix.
  1736.   
  1737.   e  contains the subdiagonal elements of the tridiagonal matrix
  1738.  in its first n-1 positions.
  1739.   z  contains the orthogonal transformation matrix produced in the
  1740.  reduction.
  1741.   a and z may coincide. If distinct, a is unaltered.
  1742.   Functions used:
  1743.   UTILITY: fsign
  1744. ***********************************************************************/
  1745. void tred2(long offset, long n, double **a, double *d, double *e, double **z)
  1746. {
  1747.  long jj,ii,i,j,k,l, jp1;
  1748.  double *zptr,*aptr,h, scale, f, g,  hh, tmp;
  1749.  long i1;
  1750.  for (i=offset;i<n;i++) 
  1751.   { 
  1752.    for (j=i;j<n;j++)
  1753.      {
  1754.       z[j][i]=a[i][j];   /*fix this later?.. the rest of the routine 
  1755.                            assumes that z has the lower triangular part
  1756.                            of the symmetric matrix */
  1757.      }
  1758.    d[i]=a[i][n-1];
  1759.   }
  1760.   if (n==1) 
  1761.    {
  1762.     for (i=offset;i<n;i++)
  1763.      {
  1764.        d[i]=z[n-1][i];
  1765.        z[n-1][i]=ZERO;
  1766.      }
  1767.     z[n-1][n-1]=ONE;
  1768.     e[1]=ZERO;
  1769.     return;
  1770.    }
  1771.   /*for i = n step -1 until 2 do*/
  1772.   for (ii=3;ii<n+2-offset;ii++)
  1773.    {
  1774.      i=n+2-ii;
  1775.      l=i-1;
  1776.      h=ZERO; 
  1777.      scale=ZERO;
  1778.     /*scale row (algol tol then not needed)*/
  1779.      if (l>=1)
  1780.        for (k=offset;k<=l;k++)
  1781.         {
  1782.          scale+= fabs(d[k]);
  1783.         }
  1784.     if ((scale==ZERO)||(l<1))
  1785.      {
  1786.       e[i]=d[l];
  1787.       for (j=offset;j<=l;j++)
  1788.           {
  1789.             d[j]=z[l][j];
  1790.             z[i][j]=ZERO;
  1791.             z[j][i]=ZERO;
  1792.           }
  1793.      }
  1794.    else                   /*scale <> ZERO */
  1795.      {
  1796.        for (k=offset;k<=l;k++)
  1797.         {
  1798.          d[k]=d[k]/scale;
  1799.          h+=d[k]*d[k];
  1800.         }
  1801.        f=d[l];
  1802.        g=-fsign(sqrt(h), f);
  1803.        e[i]=scale * g;
  1804.        h-=f*g;
  1805.        d[l]=f-g;
  1806.    
  1807.        /* form A*u */
  1808.   
  1809.        for (j=offset; j<=l; j++)
  1810.           e[j]=ZERO;
  1811.           
  1812.           for (j=offset;j<=l;j++)
  1813.             {
  1814.              f=d[j];
  1815.              z[j][i]=f;
  1816.              g= e[j] + z[j][j] * f;
  1817.              
  1818.              jp1= j + 1;
  1819.    
  1820.              if (l >= jp1) 
  1821.                  {
  1822.                   for (k=jp1; k<=l; k++)
  1823.                    {
  1824.                      g+= z[k][j] * d[k];
  1825.                      e[k] += z[k][j] * f;
  1826.                    }
  1827.                  };
  1828.              e[j]=g;
  1829.            }
  1830.        /* form P */
  1831.  
  1832.        f= ZERO;
  1833.  
  1834.        for (j=offset; j<=l; j++)
  1835.         {
  1836.           e[j]=e[j]/h;
  1837.           f+= e[j] * d[j];
  1838.         }
  1839.        hh= f/ (h+h);
  1840.   
  1841.        /* form Q */
  1842.   
  1843.       for (j=offset; j<=l; j++)
  1844.        e[j] -= hh * d[j];
  1845.       /* form reduced A */
  1846.       for (j=offset; j<=l; j++)
  1847.        {
  1848.          f= d[j];
  1849.          g = e[j];
  1850.          for (k=j; k<=l; k++)
  1851.           z[k][j]= z[k][j] - f * e[k] - g * d[k];
  1852.          d[j]=z[l][j];
  1853.          z[i][j]=ZERO;
  1854.        }
  1855.     }  /* end scale <> zero */
  1856.     d[i]=h;
  1857.    }   /* end for ii */
  1858.    /*accumulation of transformation matrices */
  1859.    for (i=offset + 1;i<n;i++)
  1860.     {
  1861.      l=i-1;
  1862.      z[n-1][l] = z[l][l];
  1863.      z[l][l] = ONE;
  1864.      h=d[i];
  1865.      if (h != ZERO) 
  1866.        {
  1867.         for (k=offset; k<=l; k++)
  1868.           d[k]= z[k][i]/h;
  1869.         for (j=offset; j<=l; j++)
  1870.          {
  1871.            g= ZERO;
  1872.            
  1873.            for (k=offset;k<=l; k++)
  1874.             g+= z[k][i]*z[k][j];
  1875.    for (k=offset;k<=l;k++)
  1876.             z[k][j] -= g * d[k];
  1877.          }
  1878.        }
  1879.        for (k=offset;k<=l;k++) z[k][i]=ZERO;
  1880.      }
  1881.   
  1882.      for (i=offset;i<n;i++)
  1883.        {
  1884.         d[i]=z[n-1][i];
  1885.         z[n-1][i]=ZERO;
  1886.        }
  1887.      z[n-1][n-1]=ONE;
  1888.      e[0]=ZERO;
  1889. /*preparation for tql2.c.. reorder e[]*/
  1890. for (i=1+offset;i<n;i++) e[i-1]=e[i]; 
  1891. /*preparation for tql2.c.. z has to be transposed for 
  1892.   tql2 to give correct eigenvectors */
  1893. for (ii=offset; ii<n; ii++)
  1894.  for (jj=ii; jj<n; jj++)
  1895.  {
  1896.    tmp=z[ii][jj];
  1897.   z[ii][jj]=z[jj][ii];
  1898.   z[jj][ii]=tmp;
  1899.  }
  1900.      return;
  1901. }
  1902. /***********************************************************************
  1903.  *                                                                     *
  1904.  * tql2()           *
  1905.  *                                                                     *
  1906.  ***********************************************************************/
  1907. /***********************************************************************
  1908.    Description
  1909.    -----------
  1910.    tql2() is a translation of a Fortran version of the Algol
  1911.    procedure TQL2, Num. Math. 11, 293-306(1968) by Dowdler, Martin, 
  1912.    Reinsch and Wilkinson.
  1913.    Handbook for Auto. Comp., vol.II-Linear Algebra, 227-240(1971).  
  1914.    This function finds the eigenvalues and eigenvectors of a symmetric
  1915.    tridiagonal matrix by the QL method.
  1916.    Arguments
  1917.    ---------
  1918.    (input)                                                             
  1919.    offset the index of the leading element  of the input(full) matrix
  1920.           to be factored.
  1921.    n      order of the symmetric tridiagonal matrix           
  1922.    d      contains the diagonal elements of the input matrix        
  1923.    e      contains the subdiagonal elements of the input matrix in its
  1924.             first n-1 positions.
  1925.    z      contains the identity matrix     
  1926.                                                                    
  1927.    (output)                                                       
  1928.    d      contains the eigenvalues in ascending order.  if an error
  1929.             exit is made, the eigenvalues are correct but unordered for
  1930.             for indices 0,1,...,ierr.    
  1931.    e      has been destroyed.   
  1932.    z      contains orthonormal eigenvectors of the symmetric   
  1933.             tridiagonal (or full) matrix.  if an error exit is made,
  1934.             z contains the eigenvectors associated with the stored 
  1935.           eigenvalues.
  1936.    ierr   set to zero for normal return, j if the j-th eigenvalue has
  1937.             not been determined after 30 iterations.     
  1938.    Functions used
  1939.    --------------
  1940.    UTILITY fsign
  1941.    MISC pythag
  1942.  ***********************************************************************/
  1943. long tql2(long offset, long n, double *d, double *e, double **z)
  1944. {
  1945.    long j, last, l, l1, l2, m, i, k, iteration;
  1946.    double tst1, tst2, g, r, s, s2, c, c2, c3, p, f, h, el1, dl1;
  1947.    if (n == 1) return(0);
  1948.    f = ZERO;
  1949.    last = n - 1;
  1950.    tst1 = ZERO;
  1951.    e[last] = ZERO;
  1952.    for (l = offset; l < n; l++) {
  1953.       iteration = 0;
  1954.       h = fabs(d[l]) + fabs(e[l]);
  1955.       if (tst1 < h) tst1 = h;
  1956.       /* look for small sub-diagonal element */
  1957.       for (m = l; m < n; m++) {
  1958.  tst2 = tst1 + fabs(e[m]);
  1959.  if (tst2 == tst1) break;
  1960.       }
  1961.       if (m != l) {
  1962.  while (iteration < 30) {
  1963.     iteration += 1;
  1964.             /*  form shift */
  1965.     l1 = l + 1;
  1966.     l2 = l1 + 1;
  1967.     g = d[l];
  1968.             p = (d[l1] - g) / (2.0 * e[l]);
  1969.     r = pythag(p, ONE);
  1970.     d[l] = e[l] / (p + fsign(r, p));
  1971.     d[l1] = e[l] * (p + fsign(r, p));
  1972.     dl1 = d[l1];
  1973.     h = g - d[l];
  1974.     if (l2 < n) 
  1975.        for (i = l2; i < n; i++) d[i] -= h;
  1976.             f += h;
  1977.     /* QL transformation */
  1978.     p = d[m];
  1979.     c = ONE;
  1980.     c2 = c;
  1981.     el1 = e[l1];
  1982.     s = ZERO;
  1983.     i = m - 1;
  1984.     while (i >= l) {
  1985.        c3 = c2;
  1986.        c2 = c;
  1987.        s2 = s;
  1988.        g = c * e[i];
  1989.        h = c * p;
  1990.        r = pythag(p, e[i]);
  1991.        e[i + 1] = s * r;
  1992.        s = e[i] / r;
  1993.        c = p / r;
  1994.        p = c * d[i] - s * g;
  1995.        d[i + 1]= h + s * (c * g + s * d[i]);
  1996.        /*  form vector */
  1997.        for (k = offset; k < n; k ++) {
  1998.           h = z[i + 1][k];
  1999.           z[i + 1][k] = s * z[i][k] + c * h;
  2000.           z[i][k] = c * z[i][k] - s * h;
  2001.        }
  2002.        i--;
  2003.     }
  2004.     p = -s * s2 * c3 *el1 * e[l] / dl1;
  2005.     e[l] = s * p;
  2006.     d[l] = c * p;
  2007.     tst2 = tst1 + fabs(e[l]);
  2008.     if (tst2 <= tst1) break;
  2009.     if (iteration == 30) 
  2010.        return(l);
  2011.          }
  2012.       }
  2013.       d[l] += f;
  2014.    }
  2015.    /* order the eigenvalues */
  2016.    for (l = 1+offset; l < n; l++) {
  2017.       i = l - 1;
  2018.       k = i;
  2019.       p = d[i];
  2020.       for (j = l; j < n; j++) {
  2021.  if (d[j] < p) {
  2022.     k = j;
  2023.     p = d[j];
  2024.  }
  2025.       }
  2026.       /* ...and corresponding eigenvectors */
  2027.       if (k != i) {
  2028.  d[k] = d[i];
  2029.  d[i] = p;
  2030.   for (j = offset; j < n; j ++) {
  2031.      p = z[i][j];
  2032.      z[i][j] = z[k][j];
  2033.      z[k][j] = p;
  2034.   }
  2035.       }   
  2036.    }
  2037.    return(0);
  2038. }
  2039. // void opb(long n, double *x, double *y, double shift)
  2040. // {
  2041. // /* multiplication of a shifted 2-cylic matrix c by a vector x , where
  2042. //        [D    A]  
  2043. //    c = [      ]
  2044. //        [A'   D] , where A is nrow by ncol (nrow>>ncol),
  2045. //                   and D = (alpha-shift)*I , alpha an upper bound
  2046. //                   for the largest singular value of A, and 
  2047. //                   shift is the approximate singular value of A.
  2048. //    Hence, C is of order N=nrow+ncol (y stores product vector) */
  2049. //   long i,j,upper;
  2050. //   for(i=0; i<n; i++)
  2051. //      y[i]=(nalpha-shift)*x[i];
  2052. //   for(i=0; i<ncol; i++) {
  2053. //      upper = pointr[i+1];
  2054. //      for(j=pointr[i]; j<upper; j++)
  2055. //         y[rowind[j]] += value[j]*x[nrow+i];
  2056. //   }
  2057. //   for(i=nrow; i<n; i++) {
  2058. //      upper = pointr[i-nrow+1];
  2059. //      for(j=pointr[i-nrow]; j<upper; j++)
  2060. //         y[i] += value[j]*x[rowind[j]];
  2061. //   }
  2062. //   return;
  2063. // }
  2064. /************************************************************** 
  2065.  * multiplication of matrix B by a vector x, where            *
  2066.  *       *
  2067.  * B =  A'A, where A is nrow by ncol (nrow >> ncol)           *
  2068.  * Hence, B is of order n:=ncol                               *
  2069.  * y stores product vector                                    *
  2070.  **************************************************************/ 
  2071. void opa(double *x, double *y)
  2072. {
  2073.    long i, j,end;
  2074.    for (i = 0; i < nrow; i++) y[i] = ZERO;
  2075. /* multiply by sparse C */
  2076.    for (i = 0; i < ncol; i++) {
  2077.       end = pointr[i+1];
  2078.       for (j = pointr[i]; j < end; j++)
  2079. y[rowind[j]] += value[j] * x[i];
  2080.    }
  2081.    return;
  2082. }
  2083. /***********************************************************************
  2084.  *                                                                     *
  2085.  *                        dgemv2()                                     *
  2086.  * A C-translation of the level 2 BLAS routine DGEMV by Dongarra,      *
  2087.  * du Croz, and Hammarling, and Hanson (see LAPACK Users' Guide).      *
  2088.  *                                                                     *
  2089.  ***********************************************************************
  2090.    Description
  2091.    -----------
  2092.    dgemv2() performs one of the matrix-vector operations
  2093.    y := alpha * A * x + beta * y  or  y := alpha * A' * x + beta * y
  2094.    where alpha and beta are scalars, X, Y are vectors and A is an
  2095.    m by n matrix.
  2096.    Parameters
  2097.    ----------
  2098.    (input)
  2099.    transa   TRANSP indicates op(A) = A' is to be used in the multiplication
  2100.     NTRANSP indicates op(A) = A is to be used in the multiplication
  2101.    m        on entry, m specifies the number of rows of the matrix A.
  2102.     m must be at least zero.  Unchanged upon exit.
  2103.    n        on entry, n specifies the number of columns of the matrix A.
  2104.     n must be at least zero.  Unchanged upon exit.
  2105.    alpha    a scalar multiplier.  Unchanged upon exit.
  2106.    a        matrix A as a 2-dimensional array.  Before entry, the leading
  2107.     m by n part of the array a must contain the matrix A.
  2108.    ira,ica  row and column indices of array A, where mxn part starts.
  2109.    x        linear array of dimension of at least n if transa = NTRANSP
  2110.     and at least m otherwise.
  2111.    beta     a scalar multiplier.  When beta is supplied as zero then y
  2112.     need not be set on input.  Unchanged upon exit.
  2113.    y        linear array of dimension of at least m if transa = NTRANSP
  2114.     and at leat n otherwise.  Before entry with beta nonzero,
  2115.     the array y must contain the vector y.  On exit, y is 
  2116.     overwritten by the updated vector y.
  2117. ***********************************************************************/
  2118. void dgemv2(long transa, long m, long n, 
  2119.            double alpha, double **a, long ira, long ica,
  2120.            double *x, double beta, double *y)
  2121. {
  2122.    long info, leny, i, j;
  2123.    double temp, *ptrtemp;
  2124.    info = 0;
  2125.    if      ( transa != TRANSP && transa != NTRANSP ) info = 1;
  2126.    else if ( m < 0 )       info = 2;
  2127.    else if ( n < 0 )      info = 3;
  2128.    if (info) {
  2129.       fprintf(stderr, "%s %1ld %sn",
  2130.       "*** ON ENTRY TO DGEMV, PARAMETER NUMBER",info,"HAD AN ILLEGAL VALUE");
  2131.       exit(info);
  2132.    }
  2133.    if (transa) leny = n;
  2134.    else        leny = m;
  2135.    if (!m || !n || (alpha == ZERO && beta == ONE))
  2136.       return;
  2137.    /* form Y := beta * Y */
  2138.    if (beta == 0.0) 
  2139.       for (i = 0; i < leny; i++) y[i] = ZERO;
  2140.    else if (beta != 1.0) 
  2141.       for (i = 0; i < leny; i++) y[i] *= beta;
  2142.    if (alpha == ZERO) return;
  2143.    switch(transa) {
  2144.       /* form Y := alpha * A * X + Y */
  2145.       case NTRANSP:  for(j = 0; j < n; j++) {
  2146.         temp = alpha*x[j];
  2147.         for(i = 0; i < m; i++) 
  2148. y[i] += temp*a[j+ica][i+ira];
  2149.      }
  2150.      break;
  2151.      
  2152.       /* form Y := alpha * A' * X + Y */
  2153.       case TRANSP:   for(j = 0; j < n; j++) { 
  2154.                         temp = ZERO;
  2155. for(i=0; i<m; i++) 
  2156.    temp += a[j+ica][i+ira]*x[i];
  2157.                         y[j] += alpha*temp;
  2158.      }
  2159.      break;
  2160.    }
  2161. }
  2162. void imtql2(long nm, long n, double d[], double e[], double z[])
  2163. {
  2164.    long index, nnm, j, last, l, m, i, k, iteration, convergence, underflow;
  2165.    double b, test, g, r, s, c, p, f;
  2166.    if (n == 1) return;
  2167.    ierr = 0;
  2168.    last = n - 1;
  2169.    for (i = 1; i < n; i++) e[i-1] = e[i];
  2170.    e[last] = 0.0;
  2171.    nnm = n * nm;
  2172.    for (l = 0; l < n; l++) {
  2173.       iteration = 0;
  2174.       /* look for small sub-diagonal element */
  2175.       while (iteration <= 30) {
  2176.  for (m = l; m < n; m++) {
  2177.     convergence = FALSE;
  2178.     if (m == last) break;
  2179.     else {
  2180.        test = fabs(d[m]) + fabs(d[m+1]);
  2181.        if (test + fabs(e[m]) == test) convergence = TRUE;
  2182.     }
  2183.     if (convergence) break;
  2184.  }
  2185.  if (m != l) {
  2186.     /* set error -- no convergence to an eigenvalue after
  2187.      * 30 iterations. */     
  2188.     if (iteration == 30) {
  2189.        ierr = l;
  2190.        return;
  2191.     }
  2192.     p = d[l]; 
  2193.     iteration += 1;
  2194.     /* form shift */
  2195.     g = (d[l+1] - p) / (2.0 * e[l]);
  2196.     r = pythag(g, 1.0);
  2197.     g = d[m] - p + e[l] / (g + fsign(r, g));
  2198.     s = 1.0;
  2199.     c = 1.0;
  2200.     p = 0.0;
  2201.     underflow = FALSE;
  2202.     i = m - 1;
  2203.     while (underflow == FALSE && i >= l) {
  2204.        f = s * e[i];
  2205.        b = c * e[i];
  2206.        r = pythag(f, g);
  2207.        e[i+1] = r;
  2208.        if (r == 0.0) underflow = TRUE;
  2209.        else {
  2210.   s = f / r;
  2211.   c = g / r;
  2212.   g = d[i+1] - p;
  2213.   r = (d[i] - g) * s + 2.0 * c * b;
  2214.   p = s * r;
  2215.   d[i+1] = g + p;
  2216.   g = c * r - b;
  2217.   /* form vector */
  2218.   for (k = 0; k < nnm; k += n) {
  2219.      index = k + i;
  2220.      f = z[index+1];
  2221.      z[index+1] = s * z[index] + c * f;
  2222.      z[index] = c * z[index] - s * f;
  2223.   } 
  2224.   i--;
  2225.        }
  2226.     }   /* end while (underflow != FALSE && i >= l) */
  2227.     /*........ recover from underflow .........*/
  2228.     if (underflow) {
  2229.        d[i+1] -= p;
  2230.        e[m] = 0.0;
  2231.     }
  2232.     else {
  2233.        d[l] -= p;
  2234.        e[l] = g;
  2235.        e[m] = 0.0;
  2236.     }
  2237.  }
  2238.  else break;
  2239.       } /*...... end while (iteration <= 30) .........*/
  2240.    } /*...... end for (l=0; l<n; l++) .............*/
  2241.    /* order the eigenvalues */
  2242.    for (l = 1; l < n; l++) {
  2243.       i = l - 1;
  2244.       k = i;
  2245.       p = d[i];
  2246.       for (j = l; j < n; j++) {
  2247.  if (d[j] < p) {
  2248.     k = j;
  2249.     p = d[j];
  2250.  }
  2251.       }
  2252.       /* ...and corresponding eigenvectors */
  2253.       if (k != i) {
  2254.  d[k] = d[i];
  2255.  d[i] = p;
  2256.   for (j = 0; j < nnm; j += n) {
  2257.      p = z[j+i];
  2258.      z[j+i] = z[j+k];
  2259.      z[j+k] = p;
  2260.   }
  2261.       }   
  2262.    }
  2263.    return;
  2264. }