Пример #1
0
void dgetrs( char trans, long n, long nrhs, double a[], long lda,
            long ipiv[], double b[], long ldb, long *info )
{
  /**
   *  -- LAPACK routine (version 1.1) --
   *     Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
   *     Courant Institute, Argonne National Lab, and Rice University
   *     March 31, 1993
   *
   *     .. Scalar Arguments ..*/
  /**     ..
   *     .. Array Arguments ..*/
#undef ipiv_1
#define ipiv_1(a1) ipiv[a1-1]
#undef b_2
#define b_2(a1,a2) b[a1-1+ldb*(a2-1)]
#undef a_2
#define a_2(a1,a2) a[a1-1+lda*(a2-1)]
  /**     ..
   *
   *  Purpose
   *  =======
   *
   *  DGETRS solves a system of linear equations
   *     A * X = B  or  A' * X = B
   *  with a general N-by-N matrix A using the LU factorization computed
   *  by DGETRF.
   *
   *  Arguments
   *  =========
   *
   *  TRANS   (input) CHARACTER*1
   *          Specifies the form of the system of equations:
   *          = 'N':  A * X = B  (No transpose)
   *          = 'T':  A'* X = B  (Transpose)
   *          = 'C':  A'* X = B  (Conjugate transpose = Transpose)
   *
   *  N       (input) INTEGER
   *          The order of the matrix A.  N >= 0.
   *
   *  NRHS    (input) INTEGER
   *          The number of right hand sides, i.e., the number of columns
   *          of the matrix B.  NRHS >= 0.
   *
   *  A       (input) DOUBLE PRECISION array, dimension (LDA,N)
   *          The factors L and U from the factorization A = P*L*U
   *          as computed by DGETRF.
   *
   *  LDA     (input) INTEGER
   *          The leading dimension of the array A.  LDA >= max(1,N).
   *
   *  IPIV    (input) INTEGER array, dimension (N)
   *          The pivot indices from DGETRF; for 1<=i<=N, row i of the
   *          matrix was interchanged with row IPIV(i).
   *
   *  B       (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
   *          On entry, the right hand side matrix B.
   *          On exit, the solution matrix X.
   *
   *  LDB     (input) INTEGER
   *          The leading dimension of the array B.  LDB >= max(1,N).
   *
   *  INFO    (output) INTEGER
   *          = 0:  successful exit
   *          < 0:  if INFO = -i, the i-th argument had an illegal value
   *
   *  =====================================================================
   *
   *     .. Parameters ..*/
#undef one
#define one 1.0e+0
  /**     ..
   *     .. Local Scalars ..*/
  int            notran;
  /**     ..
   *     .. Intrinsic Functions ..*/
  /*      intrinsic          max;*/
  /**     ..
   *     .. Executable Statements ..
   *
   *     Test the input parameters.
   **/
  /*-----implicit-declarations-----*/
  /*-----end-of-declarations-----*/
  *info = 0;
  notran = lsame( trans, 'n' );
  if( !notran && !lsame( trans, 't' ) && !
     lsame( trans, 'c' ) ) {
    *info = -1;
  } else if( n<0 ) {
    *info = -2;
  } else if( nrhs<0 ) {
    *info = -3;
  } else if( lda<max( 1, n ) ) {
    *info = -5;
  } else if( ldb<max( 1, n ) ) {
    *info = -8;
  }
  if( *info!=0 ) {
    xerbla( "dgetrs", -*info );
    return;
  }
  /**
   *     Quick return if possible
   **/
  if( n==0 || nrhs==0 )
    return;

  if( notran ) {
    /**
     *        Solve A * X = B.
     *
     *        Apply row interchanges to the right hand sides.
     **/
    dlaswp( nrhs, b, ldb, 1, n, ipiv, 1 );
    /**
     *        Solve L*X = B, overwriting B with X.
     **/
    cblas_dtrsm(CblasColMajor, CblasLeft, CblasLower, CblasNoTrans,
                CblasUnit, n, nrhs, one, a, lda, b, ldb );
    /**
     *        Solve U*X = B, overwriting B with X.
     **/
    cblas_dtrsm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans,
                CblasNonUnit, n, nrhs, one, a, lda, b, ldb );
  } else {
    /**
     *        Solve A' * X = B.
     *
     *        Solve U'*X = B, overwriting B with X.
     **/
    cblas_dtrsm(CblasColMajor, CblasLeft, CblasUpper, CblasTrans,
                CblasNonUnit, n, nrhs, one, a, lda, b, ldb );
    /**
     *        Solve L'*X = B, overwriting B with X.
     **/
    cblas_dtrsm(CblasColMajor, CblasLeft, CblasLower, CblasTrans,
                CblasUnit, n, nrhs, one, a, lda, b, ldb );
    /**
     *        Apply row interchanges to the solution vectors.
     **/
    dlaswp( nrhs, b, ldb, 1, n, ipiv, -1 );
  }

  return;
  /**
   *     End of DGETRS
   **/
}
Пример #2
0
void chseqr(char *job, char *compz, int n__, int ilo,
	    int ihi, fcomplex *h, int ldh, fcomplex *w, fcomplex *z, 
	    int ldz, fcomplex *work, int lwork, int *info)
{
/*  -- LAPACK routine (version 2.0) --   
       Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,   
       Courant Institute, Argonne National Lab, and Rice University   
       September 30, 1994   


    Purpose   
    =======   

    CHSEQR computes the eigenvalues of a complex upper Hessenberg   
    matrix H, and, optionally, the matrices T and Z from the Schur   
    decomposition H = Z T Z**H, where T is an upper triangular matrix   
    (the Schur form), and Z is the unitary matrix of Schur vectors.   

    Optionally Z may be postmultiplied into an input unitary matrix Q,   
    so that this routine can give the Schur factorization of a matrix A   
    which has been reduced to the Hessenberg form H by the unitary   
    matrix Q:  A = Q*H*Q**H = (QZ)*T*(QZ)**H.   

    Arguments   
    =========   

    JOB     (input) CHARACTER*1   
            = 'E': compute eigenvalues only;   
            = 'S': compute eigenvalues and the Schur form T.   

    COMPZ   (input) CHARACTER*1   
            = 'N': no Schur vectors are computed;   
            = 'I': Z is initialized to the unit matrix and the matrix Z   
                   of Schur vectors of H is returned;   
            = 'V': Z must contain an unitary matrix Q on entry, and   
                   the product Q*Z is returned.   

    N       (input) INTEGER   
            The order of the matrix H.  N >= 0.   

    ILO     (input) INTEGER   
    IHI     (input) INTEGER   
            It is assumed that H is already upper triangular in rows   
            and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally   
            set by a previous call to CGEBAL, and then passed to CGEHRD   
            when the matrix output by CGEBAL is reduced to Hessenberg   
            form. Otherwise ILO and IHI should be set to 1 and N   
            respectively.   
            1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.   

    H       (input/output) COMPLEX array, dimension (LDH,N)   
            On entry, the upper Hessenberg matrix H.   
            On exit, if JOB = 'S', H contains the upper triangular matrix 
  
            T from the Schur decomposition (the Schur form). If   
            JOB = 'E', the contents of H are unspecified on exit.   

    LDH     (input) INTEGER   
            The leading dimension of the array H. LDH >= max(1,N).   

    W       (output) COMPLEX array, dimension (N)   
            The computed eigenvalues. If JOB = 'S', the eigenvalues are   
            stored in the same order as on the diagonal of the Schur form 
  
            returned in H, with W(i) = H(i,i).   

    Z       (input/output) COMPLEX array, dimension (LDZ,N)   
            If COMPZ = 'N': Z is not referenced.   
            If COMPZ = 'I': on entry, Z need not be set, and on exit, Z   
            contains the unitary matrix Z of the Schur vectors of H.   
            If COMPZ = 'V': on entry Z must contain an N-by-N matrix Q,   
            which is assumed to be equal to the unit matrix except for   
            the submatrix Z(ILO:IHI,ILO:IHI); on exit Z contains Q*Z.   
            Normally Q is the unitary matrix generated by CUNGHR after   
            the call to CGEHRD which formed the Hessenberg matrix H.   

    LDZ     (input) INTEGER   
            The leading dimension of the array Z.   
            LDZ >= max(1,N) if COMPZ = 'I' or 'V'; LDZ >= 1 otherwise.   

    WORK    (workspace) COMPLEX array, dimension (N)   

    LWORK   (input) INTEGER   
            This argument is currently redundant.   

    INFO    (output) INTEGER   
            = 0:  successful exit   
            < 0:  if INFO = -i, the i-th argument had an illegal value   
            > 0:  if INFO = i, CHSEQR failed to compute all the   
                  eigenvalues in a total of 30*(IHI-ILO+1) iterations;   
                  elements 1:ilo-1 and i+1:n of W contain those   
                  eigenvalues which have been successfully computed.   

    ===================================================================== 
  


       Decode and test the input parameters   

    
   Parameter adjustments   
       Function Body */
    /* Table of constant values */
    static fcomplex c_b1 = {0.f,0.f};
    static fcomplex c_b2 = {1.f,0.f};
    static int c__1 = 1;
    static int c__4 = 4;
    static int c_n1 = -1;
    static int c__2 = 2;
    static int c__8 = 8;
    static int c__15 = 15;
    static int c_false = FALSE;
    
    /* System generated locals */
    char* a__1[2];
    int h_dim1, i__1, i__2, i__3, i__4[2], 
	    i__5, i__6;
    float r__1, r__2, r__3, r__4;
    double d__1;
    fcomplex q__1;
    char ch__1[2];
    /* Builtin functions */


    /* Local variables */
    static int maxb, ierr;
    static float unfl;
    static fcomplex temp;
    static float ovfl;
    static int i, j, k, l;
    static fcomplex s[225]	/* was [15][15] */;
    static fcomplex v[16];
    static int itemp;
    static float rtemp;
    static int i1, i2;
    static int initz, wantt, wantz;
    static float rwork[1];
    static int ii, nh;
    static int nr, ns;
    static int nv;
    static fcomplex vv[16];
    static float smlnum;
    static int itn;
    static fcomplex tau;
    static int its;
    static float ulp, tst1;



#define W(I) w[(I)-1]
#define WORK(I) work[(I)-1]

#define H(I,J) h[(I)-1 + ((J)-1)* ( ldh)]
#define Z(I,J) z[(I)-1 + ((J)-1)* ( ldz)]

h_dim1 = ldh;

    wantt = lsame(job, "S");
    initz = lsame(compz, "I");
    wantz = initz || lsame(compz, "V");

    *info = 0;
    if (! lsame(job, "E") && ! wantt) {
	*info = -1;
    } else if (! lsame(compz, "N") && ! wantz) {
	*info = -2;
    } else if (n__ < 0) {
	*info = -3;
    } else if (ilo < 1 || ilo > max(1,n__)) {
	*info = -4;
    } else if (ihi < min(ilo,n__) || ihi > n__) {
	*info = -5;
    } else if (ldh < max(1,n__)) {
	*info = -7;
    } else if (ldz < 1 || (wantz && ldz < max(1,n__))) {
	*info = -10;
    }
    if (*info != 0) {
	i__1 = -(*info);
	return ;
    }

/*     Initialize Z, if necessary */

    if (initz) {
	claset("Full", n__, n__, c_b1, c_b2, &Z(1,1), ldz);
    }

/*     Store the eigenvalues isolated by CGEBAL. */

    i__1 = ilo - 1;
    for (i = 1; i <= ilo-1; ++i) {
	i__2 = i;
	i__3 = i + i * h_dim1;
	W(i).r = H(i,i).r, W(i).i = H(i,i).i;
    }
    i__1 = n__;
    for (i = ihi + 1; i <= n__; ++i) {
	i__2 = i;
	i__3 = i + i * h_dim1;
	W(i).r = H(i,i).r, W(i).i = H(i,i).i;
    }

/*     Quick return if possible. */

    if (n__ == 0) {
	return ;
    }
    if (ilo == ihi) {
	i__1 = ilo;
	i__2 = ilo + ilo * h_dim1;
	W(ilo).r = H(ilo,ilo).r, W(ilo).i = H(ilo,ilo).i;
	return ;
    }

/*     Set rows and columns ILO to IHI to zero below the first   
       subdiagonal. */

    i__1 = ihi - 2;
    for (j = ilo; j <= ihi-2; ++j) {
	i__2 = n__;
	for (i = j + 2; i <= n__; ++i) {
	    i__3 = i + j * h_dim1;
	    H(i,j).r = 0.f, H(i,j).i = 0.f;
	}
    }
    nh = ihi - ilo + 1;

/*     I1 and I2 are the indices of the first row and last column of H   
       to which transformations must be applied. If eigenvalues only are 
  
       being computed, I1 and I2 are re-set inside the main loop. */

    if (wantt) {
	i1 = 1;
	i2 = n__;
    } else {
	i1 = ilo;
	i2 = ihi;
    }

/*     Ensure that the subdiagonal elements are real. */

    i__1 = ihi;
    for (i = ilo + 1; i <= ihi; ++i) {
	i__2 = i + (i - 1) * h_dim1;
	temp.r = H(i,i-1).r, temp.i = H(i,i-1).i;
	if (temp.i != 0.f) {
	    r__1 = temp.r;
	    r__2 = temp.i;
	    rtemp = slapy2(r__1, r__2);
	    i__2 = i + (i - 1) * h_dim1;
	    H(i,i-1).r = rtemp, H(i,i-1).i = 0.f;
	    q__1.r = temp.r / rtemp, q__1.i = temp.i / rtemp;
	    temp.r = q__1.r, temp.i = q__1.i;
	    if (i2 > i) {
		i__2 = i2 - i;
		r_cnjg(&q__1, &temp);
		cscal(i__2, q__1, &H(i,i+1), ldh);
	    }
	    i__2 = i - i1;
	    cscal(i__2, temp, &H(i1,i), c__1);
	    if (i < ihi) {
		i__2 = i + 1 + i * h_dim1;
		i__3 = i + 1 + i * h_dim1;
		q__1.r = temp.r * H(i+1,i).r - temp.i * H(i+1,i).i, q__1.i = 
			temp.r * H(i+1,i).i + temp.i * H(i+1,i).r;
		H(i+1,i).r = q__1.r, H(i+1,i).i = q__1.i;
	    }
	    if (wantz) {
		cscal(nh, temp, &Z(ilo,i), c__1);
	    }
	}
    }

/*     Determine the order of the multi-shift QR algorithm to be used.   

   Writing concatenation */
    i__4[0] = 1, a__1[0] = job;
    i__4[1] = 1, a__1[1] = compz;
    s_cat(ch__1, a__1, i__4, &c__2, 2L);
    ns = ilaenv(c__4, "CHSEQR", ch__1, n__, ilo, ihi, c_n1, 6L, 2L);
/* Writing concatenation */
    i__4[0] = 1, a__1[0] = job;
    i__4[1] = 1, a__1[1] = compz;
    s_cat(ch__1, a__1, i__4, &c__2, 2L);
    maxb = ilaenv(c__8, "CHSEQR", ch__1, n__, ilo, ihi, c_n1, 6L, 2L);
    if (ns <= 1 || ns > nh || maxb >= nh) {

/*        Use the standard double-shift algorithm */

	clahqr(wantt, wantz, n__, ilo, ihi, &H(1,1), ldh, &W(1), ilo, 
		ihi, &Z(1,1), ldz, info);
	return ;
    }
    maxb = max(2,maxb);
/* Computing MIN */
    i__1 = min(ns,maxb);
    ns = min(i__1,15);

/*     Now 1 < NS <= MAXB < NH.   

       Set machine-dependent constants for the stopping criterion.   
       If norm(H) <= sqrt(OVFL), overflow should not occur. */

    unfl = slamch("Safe minimum");
    ovfl = 1.f / unfl;
    slabad(&unfl, &ovfl);
    ulp = slamch("Precision");
    smlnum = unfl * (nh / ulp);

/*     ITN is the total number of multiple-shift QR iterations allowed. */

    itn = nh * 30;

/*     The main loop begins here. I is the loop index and decreases from 
  
       IHI to ILO in steps of at most MAXB. Each iteration of the loop   
       works with the active submatrix in rows and columns L to I.   
       Eigenvalues I+1 to IHI have already converged. Either L = ILO, or 
  
       H(L,L-1) is negligible so that the matrix splits. */

    i = ihi;
L60:
    if (i < ilo) {
	goto L180;
    }

/*     Perform multiple-shift QR iterations on rows and columns ILO to I 
  
       until a submatrix of order at most MAXB splits off at the bottom   
       because a subdiagonal element has become negligible. */

    l = ilo;
    i__1 = itn;
    for (its = 0; its <= itn; ++its) {

/*        Look for a single small subdiagonal element. */

	i__2 = l + 1;
	for (k = i; k >= l+1; --k) {
	    i__3 = k - 1 + (k - 1) * h_dim1;
	    i__5 = k + k * h_dim1;
	    tst1 = (r__1 = H(k-1,k-1).r, fabs(r__1)) + (r__2 = H(k-1,k-1).i, fabs(r__2)) + ((r__3 = H(k,k).r, 
		    fabs(r__3)) + (r__4 = H(k,k).i, fabs(
		    r__4)));
	    if (tst1 == 0.f) {
		i__3 = i - l + 1;
		tst1 = clanhs("1", i__3, &H(l,l), ldh, rwork);
	    }
	    i__3 = k + (k - 1) * h_dim1;
/* Computing MAX */
	    r__2 = ulp * tst1;
	    if ((r__1 = H(k,k-1).r, fabs(r__1)) <= max(r__2,smlnum)) {
		goto L80;
	    }
	}
L80:
	l = k;
	if (l > ilo) {

/*           H(L,L-1) is negligible. */

	    i__2 = l + (l - 1) * h_dim1;
	    H(l,l-1).r = 0.f, H(l,l-1).i = 0.f;
	}

/*        Exit from loop if a submatrix of order <= MAXB has split off. */

	if (l >= i - maxb + 1) {
	    goto L170;
	}

/*        Now the active submatrix is in rows and columns L to I. If 
  
          eigenvalues only are being computed, only the active submatrix   
          need be transformed. */

	if (! wantt) {
	    i1 = l;
	    i2 = i;
	}

	if (its == 20 || its == 30) {

/*           Exceptional shifts. */

	    i__2 = i;
	    for (ii = i - ns + 1; ii <= i; ++ii) {
		i__3 = ii;
		i__5 = ii + (ii - 1) * h_dim1;
		i__6 = ii + ii * h_dim1;
		d__1 = ((r__1 = H(ii,ii-1).r, fabs(r__1)) + (r__2 = H(ii,ii).r, 
			fabs(r__2))) * 1.5f;
		W(ii).r = d__1, W(ii).i = 0.f;
	    }
	} else {

/*           Use eigenvalues of trailing submatrix of order NS as shifts. */

	    clacpy("Full", ns, ns, &H(i-ns+1,i-ns+1), 
		    ldh, s, c__15);
	    clahqr(c_false, c_false, ns, c__1, ns, s, c__15, &W(i - ns 
		    + 1), c__1, ns, &Z(1,1), ldz, &ierr);
	    if (ierr > 0) {

/*              If CLAHQR failed to compute all NS eigenvalues, use the   
                unconverged diagonal elements as the remaining shifts. */

		i__2 = ierr;
		for (ii = 1; ii <= ierr; ++ii) {
		    i__3 = i - ns + ii;
		    i__5 = ii + ii * 15 - 16;
		    W(i-ns+ii).r = s[ii+ii*15-16].r, W(i-ns+ii).i = s[ii+ii*15-16].i;
		}
	    }
	}

/*        Form the first column of (G-w(1)) (G-w(2)) . . . (G-w(ns)) 
  
          where G is the Hessenberg submatrix H(L:I,L:I) and w is   
          the vector of shifts (stored in W). The result is   
          stored in the local array V. */

	v[0].r = 1.f, v[0].i = 0.f;
	i__2 = ns + 1;
	for (ii = 2; ii <= ns+1; ++ii) {
	    i__3 = ii - 1;
	    v[ii-1].r = 0.f, v[ii-1].i = 0.f;
	}
	nv = 1;
	i__2 = i;
	for (j = i - ns + 1; j <= i; ++j) {
	    i__3 = nv + 1;
	    ccopy(i__3, v,c__1, vv, c__1);
	    i__3 = nv + 1;
	    i__5 = j;
	    q__1.r = -(double)W(j).r, q__1.i = -(double)W(j).i;
	    cgemv("No transpose", i__3, nv, c_b2, &H(l,l), ldh,
		     vv, c__1, q__1, v, c__1);
	    ++nv;

/*           Scale V(1:NV) so that max(abs(V(i))) = 1. If V is zero,   
             reset it to the unit vector. */

	    itemp = icamax(nv, v, c__1);
	    i__3 = itemp - 1;
	    rtemp = (r__1 = v[itemp-1].r, fabs(r__1)) + (r__2 = v[itemp 
		    - 1].i, fabs(r__2));
	    if (rtemp == 0.f) {
		v[0].r = 1.f, v[0].i = 0.f;
		i__3 = nv;
		for (ii = 2; ii <= nv; ++ii) {
		    i__5 = ii - 1;
		    v[ii-1].r = 0.f, v[ii-1].i = 0.f;
		}
	    } else {
		rtemp = max(rtemp,smlnum);
		r__1 = 1.f / rtemp;
		csscal(nv, r__1, v, c__1);
	    }
	}

/*        Multiple-shift QR step */

	i__2 = i - 1;
	for (k = l; k <= i-1; ++k) {

/*           The first iteration of this loop determines a reflection G   
             from the vector V and applies it from left and right to H,   
             thus creating a nonzero bulge below the subdiagonal. 
  

             Each subsequent iteration determines a reflection G to   
             restore the Hessenberg form in the (K-1)th column, and thus   
             chases the bulge one step toward the bottom of the active   
             submatrix. NR is the order of G.   

   Computing MIN */
	    i__3 = ns + 1, i__5 = i - k + 1;
	    nr = min(i__3,i__5);
	    if (k > l) {
		ccopy(nr, &H(k,k-1), c__1, v, c__1);
	    }
	    clarfg(nr, v, &v[1], c__1, &tau);
	    if (k > l) {
		i__3 = k + (k - 1) * h_dim1;
		H(k,k-1).r = v[0].r, H(k,k-1).i = v[0].i;
		i__3 = i;
		for (ii = k + 1; ii <= i; ++ii) {
		    i__5 = ii + (k - 1) * h_dim1;
		    H(ii,k-1).r = 0.f, H(ii,k-1).i = 0.f;
		}
	    }
	    v[0].r = 1.f, v[0].i = 0.f;

/*           Apply G' from the left to transform the rows of the matrix   
             in columns K to I2. */

	    i__3 = i2 - k + 1;
	    r_cnjg(&q__1, &tau);
	    clarfx("Left", nr, i__3, v, q__1, &H(k,k), ldh, &
		    WORK(1));

/*           Apply G from the right to transform the columns of the   
             matrix in rows I1 to min(K+NR,I).   

   Computing MIN */
	    i__5 = k + nr;
	    i__3 = min(i__5,i) - i1 + 1;
	    clarfx("Right", i__3, nr, v, tau, &H(i1,k), ldh, &
		    WORK(1));

	    if (wantz) {

/*              Accumulate transformations in the matrix Z */

		clarfx("Right", nh, nr, v, tau, &Z(ilo,k), 
			ldz, &WORK(1));
	    }
	}

/*        Ensure that H(I,I-1) is real. */

	i__2 = i + (i - 1) * h_dim1;
	temp.r = H(i,i-1).r, temp.i = H(i,i-1).i;
	if (temp.i != 0.f) {
	    r__1 = temp.r;
	    r__2 = temp.i;
	    rtemp = slapy2(r__1, r__2);
	    i__2 = i + (i - 1) * h_dim1;
	    H(i,i-1).r = rtemp, H(i,i-1).i = 0.f;
	    q__1.r = temp.r / rtemp, q__1.i = temp.i / rtemp;
	    temp.r = q__1.r, temp.i = q__1.i;
	    if (i2 > i) {
		i__2 = i2 - i;
		r_cnjg(&q__1, &temp);
		cscal(i__2, q__1, &H(i,i+1), ldh);
	    }
	    i__2 = i - i1;
	    cscal(i__2, temp, &H(i1,i), c__1);
	    if (wantz) {
		cscal(nh, temp, &Z(ilo,i), c__1);
	    }
	}
    }

/*     Failure to converge in remaining number of iterations */

    *info = i;
    return ;

L170:

/*     A submatrix of order <= MAXB in rows and columns L to I has split 
  
       off. Use the double-shift QR algorithm to handle it. */

    clahqr(wantt, wantz, n__, l, i, &H(1,1), ldh, &W(1), ilo, ihi, 
           &Z(1,1), ldz, info);
    if (*info > 0) {
	return ;
    }

/*     Decrement number of remaining iterations, and return to start of   
       the main loop with a new value of I. */

    itn -= its;
    i = l - 1;
    goto L60;

L180:
    return ;



} 
Пример #3
0
void clascl(char *type, int kl_, int ku_, float cfrom, float cto,
            int m__, int n__, fcomplex *a, int lda, int *info)
{
/*  -- LAPACK auxiliary routine (version 2.0) --   
       Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,   
       Courant Institute, Argonne National Lab, and Rice University   
       February 29, 1992   


    Purpose   
    =======   

    CLASCL multiplies the M by N complex matrix A by the real scalar   
    CTO/CFROM.  This is done without over/underflow as long as the final 
  
    result CTO*A(I,J)/CFROM does not over/underflow. TYPE specifies that 
  
    A may be full, upper triangular, lower triangular, upper Hessenberg, 
  
    or banded.   

    Arguments   
    =========   

    TYPE    (input) CHARACTER*1   
            TYPE indices the storage type of the input matrix.   
            = 'G':  A is a full matrix.   
            = 'L':  A is a lower triangular matrix.   
            = 'U':  A is an upper triangular matrix.   
            = 'H':  A is an upper Hessenberg matrix.   
            = 'B':  A is a symmetric band matrix with lower bandwidth KL 
  
                    and upper bandwidth KU and with the only the lower   
                    half stored.   
            = 'Q':  A is a symmetric band matrix with lower bandwidth KL 
  
                    and upper bandwidth KU and with the only the upper   
                    half stored.   
            = 'Z':  A is a band matrix with lower bandwidth KL and upper 
  
                    bandwidth KU.   

    KL      (input) INTEGER   
            The lower bandwidth of A.  Referenced only if TYPE = 'B',   
            'Q' or 'Z'.   

    KU      (input) INTEGER   
            The upper bandwidth of A.  Referenced only if TYPE = 'B',   
            'Q' or 'Z'.   

    CFROM   (input) REAL   
    CTO     (input) REAL   
            The matrix A is multiplied by CTO/CFROM. A(I,J) is computed   
            without over/underflow if the final result CTO*A(I,J)/CFROM   
            can be represented without over/underflow.  CFROM must be   
            nonzero.   

    M       (input) INTEGER   
            The number of rows of the matrix A.  M >= 0.   

    N       (input) INTEGER   
            The number of columns of the matrix A.  N >= 0.   

    A       (input/output) COMPLEX array, dimension (LDA,M)   
            The matrix to be multiplied by CTO/CFROM.  See TYPE for the   
            storage type.   

    LDA     (input) INTEGER   
            The leading dimension of the array A.  LDA >= max(1,M).   

    INFO    (output) INTEGER   
            0  - successful exit   
            <0 - if INFO = -i, the i-th argument had an illegal value.   

    ===================================================================== 
  


       Test the input arguments   

    
   Parameter adjustments   
       Function Body */
    /* System generated locals */
    int a_dim1, i__1, i__2, i__3, i__4, i__5;
    fcomplex q__1;
    /* Local variables */
    static int done;
    static float ctoc;
    static int i, j;
    static int itype, k1, k2, k3, k4;
    static float cfrom1;
    static float cfromc;
    static float bignum, smlnum, mul, cto1;



#define A(I,J) a[(I)-1 + ((J)-1)* ( lda)]

    *info = 0;

    if (lsame(type, "G")) {
	itype = 0;
    } else if (lsame(type, "L")) {
	itype = 1;
    } else if (lsame(type, "U")) {
	itype = 2;
    } else if (lsame(type, "H")) {
	itype = 3;
    } else if (lsame(type, "B")) {
	itype = 4;
    } else if (lsame(type, "Q")) {
	itype = 5;
    } else if (lsame(type, "Z")) {
	itype = 6;
    } else {
	itype = -1;
    }

    if (itype == -1) {
	*info = -1;
    } else if (cfrom == 0.f) {
	*info = -4;
    } else if (m__ < 0) {
	*info = -6;
    } else if (n__ < 0 || (itype == 4 && n__ != m__) || 
              (itype == 5 && n__ != m__)) {
	*info = -7;
    } else if (itype <= 3 && lda < max(1,m__)) {
	*info = -9;
    } else if (itype >= 4) {
/* Computing MAX */
	i__1 = m__ - 1;
	if (kl_ < 0 || kl_ > max(i__1,0)) {
	    *info = -2;
	} else /* if(complicated condition) */ {
/* Computing MAX */
	    i__1 = n__ - 1;
	    if (ku_ < 0 || ku_ > max(i__1,0) || ((itype == 4 || itype == 5) && 
		    kl_ != ku_)) {
		*info = -3;
	    } else if ((itype == 4 && lda < kl_ + 1) || (itype == 5 && lda < 
		    ku_ + 1) || (itype == 6 && lda < (kl_ << 1) + ku_ + 1)) {
		*info = -9;
	    }
	}
    }

    if (*info != 0) {
	i__1 = -(*info);
	return ;
    }

    /*
     *     Quick return if possible 
     */

    if (n__ == 0 || m__ == 0) {
	return ;
    }

    /*
     *     Get machine parameters 
     */

    smlnum = slamch("S");
    bignum = 1.f / smlnum;

    cfromc = cfrom;
    ctoc = cto;

L10:
    cfrom1 = cfromc * smlnum;
    cto1 = ctoc / bignum;
    if (fabs(cfrom1) > fabs(ctoc) && ctoc != 0.f) {
	mul = smlnum;
	done = FALSE;
	cfromc = cfrom1;
    } else if (fabs(cto1) > fabs(cfromc)) {
	mul = bignum;
	done = FALSE;
	ctoc = cto1;
    } else {
	mul = ctoc / cfromc;
	done = TRUE;
    }

    if (itype == 0) {

        /*
         *        Full matrix 
         */

	i__1 = n__;
	for (j = 1; j <= n__; ++j) {
	    i__2 = m__;
	    for (i = 1; i <= m__; ++i) {
		i__3 = i + j * a_dim1;
		i__4 = i + j * a_dim1;
		q__1.r = mul * A(i,j).r, q__1.i = mul * A(i,j).i;
		A(i,j).r = q__1.r, A(i,j).i = q__1.i;
	    }
	}

    } else if (itype == 1) {

        /*
         *        Lower triangular matrix 
         */

	i__1 = n__;
	for (j = 1; j <= n__; ++j) {
	    i__2 = m__;
	    for (i = j; i <= m__; ++i) {
		i__3 = i + j * a_dim1;
		i__4 = i + j * a_dim1;
		q__1.r = mul * A(i,j).r, q__1.i = mul * A(i,j).i;
		A(i,j).r = q__1.r, A(i,j).i = q__1.i;
	    }
	}

    } else if (itype == 2) {

        /*
         *        Upper triangular matrix 
         */

	i__1 = n__;
	for (j = 1; j <= n__; ++j) {
	    i__2 = min(j,m__);
	    for (i = 1; i <= min(j,m__); ++i) {
		i__3 = i + j * a_dim1;
		i__4 = i + j * a_dim1;
		q__1.r = mul * A(i,j).r, q__1.i = mul * A(i,j).i;
		A(i,j).r = q__1.r, A(i,j).i = q__1.i;
	    }
	}

    } else if (itype == 3) {

        /*
         *        Upper Hessenberg matrix 
         */

	i__1 = n__;
	for (j = 1; j <= n__; ++j) {
            /*
             * Computing MIN 
             */
	    i__3 = j + 1;
	    i__2 = min(i__3,m__);
	    for (i = 1; i <= min(j+1,m__); ++i) {
		i__3 = i + j * a_dim1;
		i__4 = i + j * a_dim1;
		q__1.r = mul * A(i,j).r, q__1.i = mul * A(i,j).i;
		A(i,j).r = q__1.r, A(i,j).i = q__1.i;
	    }
	}

    } else if (itype == 4) {

        /*
         *        Lower half of a symmetric band matrix 
         */

	k3 = kl_ + 1;
	k4 = n__ + 1;
	i__1 = n__;
	for (j = 1; j <= n__; ++j) {
            /*
             * Computing MIN 
             */
	    i__3 = k3, i__4 = k4 - j;
	    i__2 = min(i__3,i__4);
	    for (i = 1; i <= min(k3,k4-j); ++i) {
		i__3 = i + j * a_dim1;
		i__4 = i + j * a_dim1;
		q__1.r = mul * A(i,j).r, q__1.i = mul * A(i,j).i;
		A(i,j).r = q__1.r, A(i,j).i = q__1.i;
	    }
	}

    } else if (itype == 5) {

        /*
         *        Upper half of a symmetric band matrix 
         */

	k1 = ku_ + 2;
	k3 = ku_ + 1;
	i__1 = n__;
	for (j = 1; j <= n__; ++j) {
            /*
             * Computing MAX 
             */
	    i__2 = k1 - j;
	    i__3 = k3;
	    for (i = max(k1-j,1); i <= k3; ++i) {
		i__2 = i + j * a_dim1;
		i__4 = i + j * a_dim1;
		q__1.r = mul * A(i,j).r, q__1.i = mul * A(i,j).i;
		A(i,j).r = q__1.r, A(i,j).i = q__1.i;
	    }
	}

    } else if (itype == 6) {

        /*
         *        Band matrix 
         */

	k1 = kl_ + ku_ + 2;
	k2 = kl_ + 1;
	k3 = (kl_ << 1) + ku_ + 1;
	k4 = kl_ + ku_ + 1 + m__;
	i__1 = n__;
	for (j = 1; j <= n__; ++j) {
            /*
             * Computing MAX 
             */
    	    i__3 = k1 - j;
            /*
             * Computing MIN 
             */
	    i__4 = k3, i__5 = k4 - j;
	    i__2 = min(i__4,i__5);
	    for (i = max(k1-j,k2); i <= min(k3,k4-j); ++i) {
		i__3 = i + j * a_dim1;
		i__4 = i + j * a_dim1;
		q__1.r = mul * A(i,j).r, q__1.i = mul * A(i,j).i;
		A(i,j).r = q__1.r, A(i,j).i = q__1.i;
	    }
	}

    }

    if (! done) {
	goto L10;
    }


} 
Пример #4
0
void clarft(char *direct, char *storev, int n__, int k__,
	    fcomplex *v, int ldv, fcomplex *tau, fcomplex *t, int ldt)
{
/*  -- LAPACK auxiliary routine (version 2.0) --   
       Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,   
       Courant Institute, Argonne National Lab, and Rice University   
       September 30, 1994   


    Purpose   
    =======   

    CLARFT forms the triangular factor T of a complex block reflector H   
    of order n, which is defined as a product of k elementary reflectors. 
  

    If DIRECT = 'F', H = H(1) H(2) . . . H(k) and T is upper triangular; 
  

    If DIRECT = 'B', H = H(k) . . . H(2) H(1) and T is lower triangular. 
  

    If STOREV = 'C', the vector which defines the elementary reflector   
    H(i) is stored in the i-th column of the array V, and   

       H  =  I - V * T * V'   

    If STOREV = 'R', the vector which defines the elementary reflector   
    H(i) is stored in the i-th row of the array V, and   

       H  =  I - V' * T * V   

    Arguments   
    =========   

    DIRECT  (input) CHARACTER*1   
            Specifies the order in which the elementary reflectors are   
            multiplied to form the block reflector:   
            = 'F': H = H(1) H(2) . . . H(k) (Forward)   
            = 'B': H = H(k) . . . H(2) H(1) (Backward)   

    STOREV  (input) CHARACTER*1   
            Specifies how the vectors which define the elementary   
            reflectors are stored (see also Further Details):   
            = 'C': columnwise   
            = 'R': rowwise   

    N       (input) INTEGER   
            The order of the block reflector H. N >= 0.   

    K       (input) INTEGER   
            The order of the triangular factor T (= the number of   
            elementary reflectors). K >= 1.   

    V       (input/output) COMPLEX array, dimension   
                                 (LDV,K) if STOREV = 'C'   
                                 (LDV,N) if STOREV = 'R'   
            The matrix V. See further details.   

    LDV     (input) INTEGER   
            The leading dimension of the array V.   
            If STOREV = 'C', LDV >= max(1,N); if STOREV = 'R', LDV >= K. 
  

    TAU     (input) COMPLEX array, dimension (K)   
            TAU(i) must contain the scalar factor of the elementary   
            reflector H(i).   

    T       (output) COMPLEX array, dimension (LDT,K)   
            The k by k triangular factor T of the block reflector.   
            If DIRECT = 'F', T is upper triangular; if DIRECT = 'B', T is 
  
            lower triangular. The rest of the array is not used.   

    LDT     (input) INTEGER   
            The leading dimension of the array T. LDT >= K.   

    Further Details   
    ===============   

    The shape of the matrix V and the storage of the vectors which define 
  
    the H(i) is best illustrated by the following example with n = 5 and 
  
    k = 3. The elements equal to 1 are not stored; the corresponding   
    array elements are modified but restored on exit. The rest of the   
    array is not used.   

    DIRECT = 'F' and STOREV = 'C':         DIRECT = 'F' and STOREV = 'R': 
  

                 V = (  1       )                 V = (  1 v1 v1 v1 v1 ) 
  
                     ( v1  1    )                     (     1 v2 v2 v2 ) 
  
                     ( v1 v2  1 )                     (        1 v3 v3 ) 
  
                     ( v1 v2 v3 )   
                     ( v1 v2 v3 )   

    DIRECT = 'B' and STOREV = 'C':         DIRECT = 'B' and STOREV = 'R': 
  

                 V = ( v1 v2 v3 )                 V = ( v1 v1  1       ) 
  
                     ( v1 v2 v3 )                     ( v2 v2 v2  1    ) 
  
                     (  1 v2 v3 )                     ( v3 v3 v3 v3  1 ) 
  
                     (     1 v3 )   
                     (        1 )   

    ===================================================================== 
  


       Quick return if possible   

    
   Parameter adjustments   
       Function Body */
    /* Table of constant values */
    static fcomplex c_b2 = {0.f,0.f};
    static int c__1 = 1;
    
    /* System generated locals */
    int t_dim1, v_dim1, i__1, i__2, i__3, i__4;
    fcomplex q__1;
    /* Local variables */
    static int i, j;
    static fcomplex vii;



#define TAU(I) tau[(I)-1]

#define V(I,J) v[(I)-1 + ((J)-1)* ( ldv)]
#define T(I,J) t[(I)-1 + ((J)-1)* ( ldt)]

    if (n__ == 0) {
	return;
    }

    if (lsame(direct, "F")) {
	i__1 = k__;
	for (i = 1; i <= k__; ++i) {
	    i__2 = i;
	    if (TAU(i).r == 0.f && TAU(i).i == 0.f) {

/*              H(i)  =  I */

		i__2 = i;
		for (j = 1; j <= i; ++j) {
		    i__3 = j + i * t_dim1;
		    T(j,i).r = 0.f, T(j,i).i = 0.f;
		}
	    } else {

/*              general case */

		i__2 = i + i * v_dim1;
		vii.r = V(i,i).r, vii.i = V(i,i).i;
		i__2 = i + i * v_dim1;
		V(i,i).r = 1.f, V(i,i).i = 0.f;
		if (lsame(storev, "C")) {

/*                 T(1:i-1,i) := - tau(i) * V(i:n,1:i-1)' * V(i:n,i) */

		    i__2 = n__ - i + 1;
		    i__3 = i - 1;
		    i__4 = i;
		    q__1.r = -(double)TAU(i).r, q__1.i = -(double)
			    TAU(i).i;
		    cgemv("Conjugate transpose", i__2, i__3, q__1,
                           &V(i,1), ldv, &V(i,i), c__1, c_b2, &
			    T(1,i), c__1);
		} else {

/*                 T(1:i-1,i) := - tau(i) * V(1:i-1,i:n) * V(i,i:n)' */

		    if (i < n__) {
			i__2 = n__ - i;
			clacgv(i__2, &V(i,i+1), ldv);
		    }
		    i__2 = i - 1;
		    i__3 = n__ - i + 1;
		    i__4 = i;
		    q__1.r = -(double)TAU(i).r, q__1.i = -(double)
			    TAU(i).i;
		    cgemv("No transpose", i__2, i__3, q__1, &V(1,i), 
                            ldv, &V(i,i), ldv, c_b2, &T(1,i), c__1);
		    if (i < n__) {
			i__2 = n__ - i;
			clacgv(i__2, &V(i,i+1), ldv);
		    }
		}
		i__2 = i + i * v_dim1;
		V(i,i).r = vii.r, V(i,i).i = vii.i;

/*              T(1:i-1,i) := T(1:i-1,1:i-1) * T(1:i-1,i) */

		i__2 = i - 1;
		ctrmv("Upper", "No transpose", "Non-unit", i__2, &T(1,1), 
                         ldt, &T(1,i), c__1);
		i__2 = i + i * t_dim1;
		i__3 = i;
		T(i,i).r = TAU(i).r, T(i,i).i = TAU(i).i;
	    }
	}
    } else {
	for (i = k__; i >= 1; --i) {
	    i__1 = i;
	    if (TAU(i).r == 0.f && TAU(i).i == 0.f) {

/*              H(i)  =  I */

		i__1 = k__;
		for (j = i; j <= k__; ++j) {
		    i__2 = j + i * t_dim1;
		    T(j,i).r = 0.f, T(j,i).i = 0.f;
		}
	    } else {

/*              general case */

		if (i < k__) {
		    if (lsame(storev, "C")) {
			i__1 = n__ - k__ + i + i * v_dim1;
			vii.r = V(n__-k__+i,i).r, vii.i = V(n__-k__+i,i).i;
			i__1 = n__ - k__ + i + i * v_dim1;
			V(n__-k__+i,i).r = 1.f, V(n__-k__+i,i).i = 0.f;

/*                    T(i+1:k,i) :=   
                              - tau(i) * V(1:n-k+i,i+1:k)' * V(1:n-k+i,i) */

			i__1 = n__ - k__ + i;
			i__2 = k__ - i;
			i__3 = i;
			q__1.r = -(double)TAU(i).r, q__1.i = -(
				double)TAU(i).i;
			cgemv("Conjugate transpose", i__1, i__2, q__1, 
                                &V(1,i+1), ldv, &V(1,i)
				, c__1, c_b2, &T(i+1,i), c__1);
			i__1 = n__ - k__ + i + i * v_dim1;
			V(n__-k__+i,i).r = vii.r, V(n__-k__+i,i).i = vii.i;
		    } else {
			i__1 = i + (n__ - k__ + i) * v_dim1;
			vii.r = V(i,n__-k__+i).r, vii.i = V(i,n__-k__+i).i;
			i__1 = i + (n__ - k__ + i) * v_dim1;
			V(i,n__-k__+i).r = 1.f, V(i,n__-k__+i).i = 0.f;

/*                    T(i+1:k,i) :=   
                              - tau(i) * V(i+1:k,1:n-k+i) * V(i,1:n-k+i)' */

			i__1 = n__ - k__ + i - 1;
			clacgv(i__1, &V(i,1), ldv);
			i__1 = k__ - i;
			i__2 = n__ - k__ + i;
			i__3 = i;
			q__1.r = -(double)TAU(i).r, q__1.i = -(
				double)TAU(i).i;
			cgemv("No transpose", i__1, i__2, q__1, &V(i+1,1), 
                               ldv, &V(i,1), ldv, c_b2, &
			       T(i+1,i), c__1);
			i__1 = n__ - k__ + i - 1;
			clacgv(i__1, &V(i,1), ldv);
			i__1 = i + (n__ - k__ + i) * v_dim1;
			V(i,n__-k__+i).r = vii.r, V(i,n__-k__+i).i = vii.i;
		    }

/*                 T(i+1:k,i) := T(i+1:k,i+1:k) * T(i+1:k,i) */

		    i__1 = k__ - i;
		    ctrmv("Lower", "No transpose", "Non-unit", i__1, &T(i+1,i+1), 
                             ldt, &T(i+1,i), c__1);
		}
		i__1 = i + i * t_dim1;
		i__2 = i;
		T(i,i).r = TAU(i).r, T(i,i).i = TAU(i).i;
	    }
	}
    }

}