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

Unix_Linux

  1. // File: tms.cc -- Implements class tms
  2. // Author: Suvrit Sra
  3. // Date: 15, nov 2003
  4. /*************************************************************************
  5.  THE ORIGINAL SVDPAKC COPYRIGHT
  6.                            (c) Copyright 1993
  7.                         University of Tennessee
  8.                           All Rights Reserved                          
  9.  *************************************************************************/
  10. #include <cmath>
  11. #include "tms.h"
  12. using namespace ssvd;
  13. double tms::epslon(double x)
  14. {
  15.   /* Estimate unit roundoff in quantities of size x 
  16.      
  17.      This function should work properly on all systems
  18.      satisfying the following two assumptions,
  19.      1. The base used in representiong floating point
  20.         numbers is not a power of three.
  21.      2. The quantity a in statement 10 is represented to 
  22.         the accuracy used in floating point variables
  23.         that are stored in memory.
  24.      The statement number 10 and the while are intended 
  25.      to force optimizing compilers to generate code
  26.      satisfying assumption 2.
  27.      Under these assumptions, it should be true that,
  28.          A is not exactly equal to four-thirds,
  29.          B has a zero for its last bit or digit,
  30.          C is not exactly equal to one,
  31.          EPS measures the separation of 1.0 from
  32.              the next larger floating point number.
  33.      This routine is based on Eispack. The developers of
  34.      Eispack would appreciate being informed about any
  35.      systems where these assumptions do not hold. */
  36.   double  a,b,c,eps;
  37.   a = 4.0/3.0;
  38.   do {
  39.      b = a - ONE; /* statement 10 */
  40.      c = b + b + b;
  41.      eps = fabs(c -ONE);
  42.   }
  43.   while (eps == ZERO);  
  44.   eps = eps*fabs(x);
  45.   return(eps);
  46. }
  47. void tms::disk(long n, double *sig, double *rad, long *csize, long *clus)
  48. {
  49.   /* monitor separation of gershgorin disks */
  50.   double radi,radipi,tmp;
  51.   long   cptr,i,k,flag,upper;
  52.   /* assume ordering: sig[0] <= sig[1] <= ...<= sig[n-1] for sig 
  53.      array in tsvd1.
  54.      rad := radii for approximate e-values  
  55.      csize array indicates location and size of clusters:
  56.      csize[i]=k  (k != 0) gives cluster of size k with first disk
  57.      centered at sig[i]. */
  58.   upper = n-1;
  59.   for(i=0; i<upper; i++) {
  60.      radi = rad[i];
  61.      radipi = rad[i+1];
  62.      tmp = (radi+radipi) - (sig[i+1] - sig[i]);
  63.      if(tmp<=0.0) clus[i] = 1;
  64.      else  clus[i] = 0;
  65.   }
  66.   /* clustering vector filled, now locate clusters and their size */
  67.   for(i=0; i<n; i++) csize[i] = 1;
  68.   for(i=0; i<upper; i++) {
  69.      cptr = i;
  70.      flag = 1;
  71.      k = i-1;
  72.      while((flag) && (k>=0)) {
  73.         if(csize[k])  flag = 0;
  74.         else  cptr=k;
  75.         k -= 1;
  76.      }
  77.    if(!clus[i]) {
  78.      if(csize[i]) csize[i] += 1;
  79.      else csize[cptr-1] += 1;
  80.      csize[i+1] -= 1;
  81.    }
  82.   }
  83. return;
  84. }
  85. void tms::isol(long i, double resid, double tol, long *init, double *ireso,
  86.           double *creso, long s)
  87. {
  88.   /* monitor residual reduction for isolated singuar value
  89.      approximations.
  90.      Assume ordering : sig[0]<=sig[1]<=...<=sig[s-1] for sig 
  91.      array in tsvd1. 
  92.      Resid : 2-norm of B-eigenpair residual   */
  93.   if((ireso[i]<ZERO) || (creso[i]>=ZERO)) {
  94.       if(creso[i]<ZERO) ireso[i]=resid;
  95.       else {
  96.            ireso[i]=resid;
  97.            creso[i]=-ONE;
  98.       }
  99.     }
  100.   else 
  101.        if(resid<=tol*ireso[i]) init[i] = TRUE;
  102.   return;
  103. }
  104. void tms::clus(long i, long size, double *resid, double tol, long *init,
  105.           double *ireso, double *creso, double *tmp, long s)
  106. {
  107.   /* Monitor residual reduction for clustered singular value 
  108.      approxmations.
  109.      Assume ordering : sig[0] <= sig[1] <=...<= sig[n-1] for 
  110.      sig array in tsvd1.
  111.      resid = 2-norm of B-eigenpair residuals. 
  112.      i     = first disk in cluster.
  113.      size  = number of disks in cluster. */
  114.   double error;
  115.   long   k,upper;
  116.   for(k=0; k<size; k++) tmp[k] = resid[k]*resid[k];
  117.   error = sqrt(dasum(size, tmp, 1));
  118.   if(creso[i] < ZERO) { 
  119.     if(ireso[i] < ZERO) creso[i] = error;
  120.     else {
  121.          creso[i] = error;
  122.          ireso[i] = -ONE;
  123.     }
  124.   }
  125.   else
  126.      if(error <= (tol*creso[i])) {
  127.        upper = i+size;
  128.        for(k=i; k<upper; k++) init[k] = TRUE;
  129.      }
  130.   return;
  131. }
  132. void tms::cgts(long n, long left, double *w, double **v, long *cgiter,
  133.           double sig, double sigold, double sigmax, double shift,
  134.           long *kount, double eps)
  135. {
  136.   /* cg for independent systems in trace min. optimization step.
  137.    (shift incorporated)
  138.    v stores current orthog basis for r[y]. */
  139.   double denom, bound, a, a0, b, error, rnorm, rnorm0, vnorm;
  140.   long   maxi, i, j, k, ii;
  141.   a0 = 0;
  142.   maxi = n;
  143.   *kount = 0;
  144.   if(sig!=shift) {
  145.     bound = (sig-shift)/(sigmax-shift);
  146.     bound=bound*bound;
  147.   }
  148.   else {
  149.        bound = (sigold-shift)/(sigmax-shift);
  150.        bound=bound*bound;
  151.   }
  152.   /* w0=w by definition , get first redidual residual via orthog.
  153.      projector */
  154.   myopb(n, w, z, shift);
  155.   *kount += 1;
  156.   dgemv2(TRANSP, n, left, ONE, v, 0, 0, z, ZERO, r);
  157.   dgemv2(NTRANSP, n, left, ONE, v, 0, 0, r, ZERO, v2);
  158.   for(i=0; i<n; i++) r[i] = z[i]-v2[i];
  159.   rnorm0 = sqrt(ddot(n,r,1,r,1));
  160.   for(i=0; i<n; i++) pp[i] = r[i];
  161.   /* main iteration loop 30*/
  162.   for( ii=0; ii<maxi; ii++) {
  163.      myopb(n, pp, v2, shift);
  164.      *kount += 1;
  165.      denom = ddot(n,pp,1,v2,1);
  166.      if(denom<=ZERO){
  167.        return;
  168.      }
  169.      a = ddot(n, r, 1, r, 1) / denom;
  170.      if(ii==0) a0 = a;
  171.      daxpy(n, -a, pp, 1, w, 1);
  172.      for(j=0; j<n; j++) r2[j] = r[j];
  173.      dgemv2(TRANSP, n, left, ONE, v, 0, 0, v2, ZERO, z);
  174.      dgemv2(NTRANSP, n, left, ONE, v, 0, 0, z, ZERO, z2);
  175.      for(i=0; i<n; i++) v2[i] -= z2[i];
  176.      daxpy(n, -a, v2, 1, r2, 1);
  177.      rnorm = sqrt(ddot(n,r2,1,r2,1));
  178.      for(k=0; k<n; k++) v2[k] = pp[k];
  179.      dscal(n, a, v2, 1);
  180.      vnorm = sqrt(ddot(n,v2,1,v2,1));
  181.   /* early termination code: */
  182.      error = fabs(a*rnorm*rnorm/(a0*rnorm0*rnorm0));
  183.      if((error<=bound) || (vnorm <= eps))  {
  184.        *cgiter += ii+1;
  185.        return;
  186.        }
  187.      else if (ii==maxi-1) {
  188.           *cgiter += maxi;
  189.            printf("cgts failed to converge in  %ld  iterationsn",maxi);
  190.            return;
  191.           }
  192.      for(j=0; j<n; j++) v2[j] = r2[j];
  193.      b=ddot(n, r2, 1, r2, 1) / ddot(n, r, 1, r, 1);
  194.      daxpy(n, b, pp, 1, v2, 1);
  195.      for(j=0; j<n; j++) pp[j] = v2[j];
  196.      for(j=0; j<n; j++) r[j] = r2[j];
  197.   }
  198. return;
  199. }
  200. void tms::cgt(long n, long left, double *w, double **v, long *cgiter, 
  201.          double sig, double sigmax, long *kount, double eps)
  202. {
  203.   /* cg for independent systems in trace min. optimization step.
  204.      v stores current orthog basis for r[y]. */
  205.   double denom, bound, a, a0, b, error, rnorm, rnorm0, vnorm;
  206.   long   maxi, i, j, k, ii;
  207.   a0 = 0;                       // keep compiler happy
  208.   maxi = n;
  209.   *kount = 0;
  210.   bound = sig/sigmax ;
  211.   bound = bound*bound;
  212.   /* w0=w by definition , get first residual via orthog, projector */
  213.   myopb(n, w, z, ZERO);
  214.   *kount += 1;
  215.   dgemv2(TRANSP, n, left, ONE, v, 0, 0, z, ZERO, r);
  216.   dgemv2(NTRANSP, n, left, ONE, v, 0, 0, r, ZERO, v2);
  217.   for(i=0; i<n; i++) r[i] = z[i]-v2[i];
  218.   rnorm0 = sqrt(ddot(n,r,1,r,1));
  219.   for(i=0; i<n; i++) pp[i] = r[i];
  220.   /* main iteration loop */
  221.   for( ii=0; ii<maxi; ii++) {
  222.      myopb(n, pp, v2, ZERO);
  223.      *kount += 1;
  224.      denom = ddot(n, pp, 1, v2, 1);
  225.      if(denom <= ZERO) {
  226.        return;
  227.      }
  228.      a = ddot(n, r, 1, r, 1)/denom;
  229.      if(ii==0) a0 = a;
  230.      daxpy(n, -a, pp, 1, w, 1);
  231.      for(j=0; j<n; j++) r2[j] = r[j];
  232.      dgemv2(TRANSP, n, left, ONE, v, 0, 0, v2, ZERO, z);
  233.      dgemv2(NTRANSP, n, left, ONE, v, 0, 0, z, ZERO, z2);
  234.      for(i=0; i<n; i++) v2[i] -= z2[i];
  235.      daxpy(n, -a, v2, 1, r2, 1);
  236.      rnorm = sqrt(ddot(n, r2, 1,r2,1));
  237.      for(k=0; k<n; k++) v2[k] = pp[k];
  238.      dscal(n, a, v2, 1);
  239.      vnorm = sqrt(ddot(n,v2,1,v2,1));
  240.     /* early termination code: */
  241.      error = fabs(a*rnorm*rnorm/(a0*rnorm0*rnorm0));
  242.      if((error <= bound) || (vnorm <= eps))  {
  243.        *cgiter += ii+1;
  244.        return;
  245.      }
  246.      else if(ii==maxi-1) {
  247.            *cgiter += maxi;
  248.            printf("cgt failed to converge in  %ld   iterationsn",maxi);
  249.            return;
  250.           }
  251.    
  252.      for(j=0; j<n; j++) v2[j] = r2[j];
  253.      b=ddot(n, r2, 1, r2, 1)/ddot(n, r, 1, r, 1);
  254.      daxpy(n, b, pp, 1, v2, 1);
  255.      for(j=0; j<n; j++) pp[j]=v2[j];
  256.      for(j=0; j<n; j++) r[j]=r2[j];
  257.   }
  258.   return;
  259. }
  260. void tms::porth(long p, long f, long n, double **x, double *tmp,
  261.            double *tmp1, double *tmp2, double *tmp3,
  262.            double *tmp4, double e, long degree, double alpha)
  263. /* 
  264.      C translation of blas2  Gram-Schmidt orthogonalization procedure 
  265.      for polynomial accelerated trace minimization (job=2)
  266.      the n by p matrix z stored in columns f+1 to f+p of
  267.      array x is reorthogonalized w.r.t. the first f columns of
  268.      array x.  the resulting matrix z contains the desired P-orthogonal
  269.      columns, where P is a polynomial in the matrix b from tsvd2.
  270.      (based on orthog from Rutishauser)  */
  271. {
  272. long fpp,k,km1,j;
  273. double s,t;
  274.   if(!p) return;
  275.   fpp = f+p;
  276.   for(k=f; k<fpp; k++) {
  277.      km1 = k-1;
  278. L10:
  279.     t = 0.0;
  280.     if(km1<0) goto L25;
  281.     pmul(n,x[k],tmp1,tmp2,tmp3,tmp4,e,degree,alpha);
  282.   if(km1>0) {
  283.     dgemv2(TRANSP,n,km1+1,1.0,x,0,0,tmp1,0.0,tmp);
  284.     t += ddot(km1+1,tmp,1,tmp,1);
  285.   }
  286.   else {
  287.      tmp[0] = ddot(n,x[0],1,tmp1,1);
  288.      t += tmp[0]*tmp[0];
  289.   }
  290.   if(km1>0) dgemv2(NTRANSP,n,km1+1,-1.0,x,0,0,tmp,1.0,x[k]);
  291.   else daxpy(n,-tmp[0],x[0],1,x[k],1);
  292.   if(p==0) goto L50;
  293. L25:
  294.   pmul(n,x[k],tmp1,tmp2,tmp3,tmp4,e,degree,alpha);
  295.   s = ddot(n,x[k],1,tmp1,1);
  296.   t += s;
  297.   if(s>t/100.0) goto L40;
  298.   goto L10;
  299. L40:
  300.   s = sqrt(s);
  301.   if(s!=0.0) s = 1.0/s;
  302.   dscal(n,s,x[k],1);
  303. L50:
  304.   j=0;
  305.   }
  306.    return;
  307. }
  308. void tms::dtrsm(char side, char uplo, long transa, char diag, long m,
  309.            long n, double alpha, double **a, double **b)
  310. /*  dtrsm  solves one of the matrix equations
  311.  *
  312.  *     op( a )*x = alpha*b,   or   x*op( a ) = alpha*b,
  313.  *
  314.  *  where alpha is a scalar, x and b are m by n matrices, a is a unit, or
  315.  *  non-unit,  upper or lower triangular matrix  and  op( a )  is one  of
  316.  *
  317.  *     op( a ) = a   or   op( a ) = a'.
  318.  *
  319.  *  the matrix x is overwritten on b.
  320.  *
  321.  *  parameters
  322.  *  ==========
  323.  *
  324.  *  side   - character*1.
  325.  *           on entry, side specifies whether op( a ) appears on the left
  326.  *           or right of x as follows:
  327.  *
  328.  *              side = 'l' or 'l'   op( a )*x = alpha*b.
  329.  *
  330.  *              side = 'r' or 'r'   x*op( a ) = alpha*b.
  331.  *
  332.  *           unchanged on exit.
  333.  *
  334.  *  uplo   - character*1.
  335.  *           on entry, uplo specifies whether the matrix a is an upper or
  336.  *           lower triangular matrix as follows:
  337.  *
  338.  *              uplo = 'u' or 'u'   a is an upper triangular matrix.
  339.  *
  340.  *              uplo = 'l' or 'l'   a is a lower triangular matrix.
  341.  *
  342.  *           unchanged on exit.
  343.  *
  344.  *  transa - long.
  345.  *           on entry, transa specifies the form of op( a ) to be used in
  346.  *           the matrix multiplication as follows:
  347.  *
  348.  *              transa = 0    op( a ) = a.
  349.  *
  350.  *              transa = 1    op( a ) = a'.
  351.  *
  352.  *
  353.  *           unchanged on exit.
  354.  *
  355.  *  diag   - character*1.
  356.  *           on entry, diag specifies whether or not a is unit triangular
  357.  *           as follows:
  358.  *
  359.  *              diag = 'u' or 'u'   a is assumed to be unit triangular.
  360.  *
  361.  *              diag = 'n' or 'n'   a is not assumed to be unit
  362.  *                                  triangular.
  363.  *           unchanged on exit.
  364.  *
  365.  *  m      - integer.
  366.  *           on entry, m specifies the number of rows of b. m must be at
  367.  *           least zero.
  368.  *           unchanged on exit.
  369.  *
  370.  *  n      - integer.
  371.  *           on entry, n specifies the number of columns of b.  n must be
  372.  *           at least zero.
  373.  *           unchanged on exit.
  374.  *
  375.  *  alpha  - double precision.
  376.  *           on entry,  alpha specifies the scalar  alpha. when  alpha is
  377.  *           zero then  a is not referenced and  b need not be set before
  378.  *           entry.
  379.  *           unchanged on exit.
  380.  *
  381.  *  a      - double precision array of dimension ( lda, k ), where k is m
  382.  *           when  side = 'l' or 'l'  and is  n  when  side = 'r' or 'r'.
  383.  *           before entry  with  uplo = 'u' or 'u',  the  leading  k by k
  384.  *           upper triangular part of the array  a must contain the upper
  385.  *           triangular matrix  and the strictly lower triangular part of
  386.  *           a is not referenced.
  387.  *           before entry  with  uplo = 'l' or 'l',  the  leading  k by k
  388.  *           lower triangular part of the array  a must contain the lower
  389.  *           triangular matrix  and the strictly upper triangular part of
  390.  *           a is not referenced.
  391.  *           note that when  diag = 'u' or 'u',  the diagonal elements of
  392.  *           a  are not referenced either,  but are assumed to be  unity.
  393.  *           unchanged on exit.
  394.  *
  395.  *  lda    - integer.
  396.  *           on entry, lda specifies the first dimension of a as declared
  397.  *           in the calling (sub) program.  when  side = 'l' or 'l'  then
  398.  *           lda  must be at least  max( 1, m ),  when  side = 'r' or 'r'
  399.  *           then lda must be at least max( 1, n ).
  400.  *           unchanged on exit.
  401.  *
  402.  *  b      - double precision array of dimension ( ldb, n ).
  403.  *           before entry,  the leading  m by n part of the array  b must
  404.  *           contain  the  right-hand  side  matrix  b,  and  on exit  is
  405.  *           overwritten by the solution matrix  x.
  406.  *
  407.  *  ldb    - integer.
  408.  *           on entry, ldb specifies the first dimension of b as declared
  409.  *           in  the  calling  (sub)  program.   ldb  must  be  at  least
  410.  *           max( 1, m ).
  411.  *           unchanged on exit.
  412.  *
  413.  *
  414.  *  C translation of level 3 blas routine.
  415.  *  -- written on 8-february-1989.
  416.  *     jack dongarra, argonne national laboratory.
  417.  *     iain duff, aere harwell.
  418.  *     jeremy du croz, numerical algorithms group ltd.
  419.  *     sven hammarling, numerical algorithms group ltd.   */
  420.  
  421. {
  422. long i,j,k,lside,nounit,upper,nrowa;
  423. double temp;
  424.   if(side=='L') { 
  425.     nrowa = m;
  426.     lside=1;
  427.   }
  428.   else {
  429.     nrowa = n;
  430.     lside = 0;
  431.   }
  432.   if(diag=='N') nounit = 1; 
  433.   else nounit = 0;
  434.   if(uplo == 'U') upper = 1;
  435.   else upper = 0;
  436.   /*info = 0;
  437.   if((!lside) && (!lsame(side,'R')) info =1; */
  438.   
  439.   
  440.   if(alpha==ZERO) {
  441.   for(j=0; j<n; j++)
  442.      for(i=0; i<m; i++)
  443.         b[j][i] = ZERO;
  444.   return;
  445.   }
  446. if(lside) {
  447.   if(!transa) {
  448.     if(upper) {
  449.       for(j=0; j<n; j++) {
  450.          if(alpha!=ONE) for(i=0; i<m; i++) b[j][i] *= alpha;
  451.          for(k=m-1; k>=0; k--) {
  452.             if(b[j][k]!=ZERO) {
  453.               if(nounit) b[j][k] /= a[k][k];
  454.               for(i = 0; i<k; i++) b[j][i] -= b[j][k]*a[k][i];
  455.             }
  456.          }
  457.       }
  458.      }
  459.     else {
  460.      for(j=0; j<n; j++) {
  461.         if(alpha!=ONE) for(i=0; i<m; i++) b[j][i] *= alpha;
  462.         for(k=0; k<m; k++) {
  463.              if(b[j][k]!=ZERO) {
  464.                if(nounit) b[j][k] /= a[k][k];
  465.                for(i=k+1; i<m; i++) b[j][i] -= b[j][k]*a[k][i];
  466.              }
  467.         }
  468.      }
  469.     }
  470.  }
  471.  else {
  472. /* b = alpha*inv(a') *b */
  473.     if(upper) {
  474.       for(j=0; j<n; j++) {
  475.          for(i=0; i<m; i++) {
  476.             temp = alpha*b[j][i];
  477.             for(k=0; k<i; k++) temp -= a[i][k]*b[j][k];
  478.             if(nounit) temp /= a[i][i];
  479.             b[j][i] = temp;
  480.          }
  481.       }
  482.     }
  483.     else {
  484.        for(j=0; j<n; j++) {
  485.           for(i=m-1; i>=0; i--) {
  486.               temp = alpha*b[j][i];
  487.               for(k=i+1; k<m; k++) temp -= a[i][k]*b[j][k];
  488.               if(nounit) temp /= a[i][i];
  489.               b[j][i] = temp;
  490.           }
  491.        }
  492.     }
  493.  }
  494. }
  495. else {
  496. /* b = alpha*b*inv(a) */
  497.      if(!transa) {
  498.        if(upper) {
  499.          for(j=0; j<n; j++) { 
  500.             if(alpha!=ONE) for(i=0; i<m; i++) b[j][i] *= alpha;
  501.             for(k=0; k<j; k++) {
  502.                if(a[j][k]!=ZERO) {
  503.                  for(i=0; i<m; i++) b[j][i] -= a[j][k]*b[k][i];
  504.                }
  505.             }
  506.             if(nounit) {
  507.               temp = ONE/a[j][j];
  508.               for(i=0; i<m; i++) b[j][i] *= temp;
  509.             }
  510.          }
  511.         }
  512.       else {
  513.         for(j=n-1; j>=0; j--) {
  514.            if(alpha!=ONE) for(i=0; i<m; i++) b[j][i] *= alpha;
  515.            for(k=j+1; k<n; k++) {
  516.               if(a[j][k] !=ZERO) 
  517.                 for(i=0; i<m; i++) b[j][i] -= a[j][k]*b[k][i];
  518.             }
  519.            if(nounit) {
  520.              temp = ONE/a[j][j];
  521.              for(i=0; i<m; i++) b[j][i] *= temp;
  522.            }
  523.         }
  524.       }
  525.      }
  526.    else {
  527. /* form b = alpha*b*inv[a']. */
  528.    if(upper) {
  529.     for(k=n-1; k>=0; k--) {
  530.        if(nounit) {
  531.          temp = ONE/a[k][k];
  532.          for(i=0; i<m; i++) b[k][i] *= temp;
  533.        }
  534.        for(j=0; j<k; j++) {
  535.           if(a[k][j]!=ZERO) {
  536.             temp = a[k][j];
  537.             for(i=0; i<m; i++) b[j][i] -=temp*b[k][i];
  538.           }
  539.        }
  540.        if(alpha !=ONE) for(i=0; i<m; i++) b[k][i] *= alpha;
  541.     }
  542.    } 
  543.    else {
  544.       for(k=0; k<n; k++) {
  545.          if(nounit) {
  546.            temp = ONE/a[k][k];
  547.            for(i=0; i<m; i++) b[k][i] *= temp;
  548.          }
  549.          for(j=k+1; j<n; j++) {
  550.             if(a[k][j]!=ZERO) {
  551.               temp = a[k][j];
  552.               for(i=0; i<m; i++) b[j][i] -= temp*b[k][i];
  553.             }
  554.          }
  555.          if(alpha!=ONE) for(i=0; i<m; i++) b[k][i] *= alpha;
  556.      }
  557.    }
  558.  }
  559. }
  560. }
  561. void tms::pmul(long n, double *y, double *z, double *z2, double *z3,
  562.           double *z4, double e, long degree, double alpha)
  563. /* Compute the multiplication z=P(B)*y (and leave y untouched).
  564.    P(B) is constructed from chebyshev polynomials. The input
  565.    parameter degree specifies the polynomial degree to be used.
  566.    Polynomials are constructed on interval (-e,e) as in Rutishauser's
  567.    ritzit code                                                    */
  568. {
  569. double tmp2,alpha2,eps,tmp;
  570.  
  571. long i,kk;
  572.   alpha2 = alpha*alpha;
  573.   tmp2 = 1.0;
  574.   eps = tmp2 + 1.0e-6;
  575.   if(!degree) for(i=0; i<n; i++) z[i] = y[i];
  576.   else if(degree==1) myopb(n,y,z,alpha2);
  577.      else if(degree>1) {
  578.           tmp2 = 2.0/e;
  579.           tmp = 5.1e-1*tmp2;
  580.           for(i=0; i<n; i++)
  581.              z[i] = y[i];
  582.           dscal(n,tmp,z,1);
  583.           myopb(n,z,z3,alpha2);
  584.           for(kk=1; kk<degree; kk++) {
  585.              for(i=0; i<n; i++) {
  586.                 z4[i] = z3[i];
  587.                 z[i] = -z[i];
  588.              }
  589.              myopb(n,z3,z2,alpha2);
  590.              daxpy(n,tmp2,z2,1,z,1);
  591.              if(kk != degree-1) {
  592.                for(i=0; i<n; i++) z3[i] = z[i];
  593.                for(i=0; i<n; i++) z[i] = z4[i];
  594.              }
  595.          }
  596.         }
  597.   daxpy(n,eps,y,1,z,1);
  598.   return;
  599. }
  600. void tms::myopb(long n, double *x, double *y, double shift)
  601. {
  602. /* multiplication of B = [(alpha*alpha-shift)*I - A'A] by a vector x , where
  603.         where A is nrow by ncol (nrow>>ncol), and alpha an upper bound
  604.         for the largest singular value of A, and 
  605.         shift is the approximate singular value of A.
  606.         (y stores product vector)                                          */
  607.   long i,j,last;
  608.   for(i=0; i<n; i++)
  609.      y[i]=(alpha*alpha-shift)*x[i];
  610.   for(i=0; i<nrow; i++) zz[i] = 0.0;
  611.   for(i=0; i<ncol; i++) {
  612.      last = pointr[i+1];
  613.      for(j=pointr[i]; j<last; j++)
  614.         zz[rowind[j]] += value[j]*x[i];
  615.   }
  616.   for(i=0; i<ncol; i++) {
  617.      for(j=pointr[i]; j<pointr[i+1]; j++)
  618.         y[i] -= value[j]*zz[rowind[j]];
  619.   }
  620.   return;
  621. }