Example #1
0
doublereal slarnd_(integer *idist, integer *iseed)
{
    /* System generated locals */
    real ret_val;

    /* Builtin functions */
    double log(doublereal), sqrt(doublereal), cos(doublereal);

    /* Local variables */
    static real t1, t2;
    extern doublereal slaran_(integer *);


/*  -- 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 */

/*     .. Scalar Arguments .. */
/*     .. */
/*     .. Array Arguments .. */
/*     .. */

/*  Purpose */
/*  ======= */

/*  SLARND returns a random real number from a uniform or normal */
/*  distribution. */

/*  Arguments */
/*  ========= */

/*  IDIST   (input) INTEGER */
/*          Specifies the distribution of the random numbers: */
/*          = 1:  uniform (0,1) */
/*          = 2:  uniform (-1,1) */
/*          = 3:  normal (0,1) */

/*  ISEED   (input/output) INTEGER array, dimension (4) */
/*          On entry, the seed of the random number generator; the array */
/*          elements must be between 0 and 4095, and ISEED(4) must be */
/*          odd. */
/*          On exit, the seed is updated. */

/*  Further Details */
/*  =============== */

/*  This routine calls the auxiliary routine SLARAN to generate a random */
/*  real number from a uniform (0,1) distribution. The Box-Muller method */
/*  is used to transform numbers from a uniform to a normal distribution. */

/*  ===================================================================== */

/*     .. Parameters .. */
/*     .. */
/*     .. Local Scalars .. */
/*     .. */
/*     .. External Functions .. */
/*     .. */
/*     .. Intrinsic Functions .. */
/*     .. */
/*     .. Executable Statements .. */

/*     Generate a real random number from a uniform (0,1) distribution */

    /* Parameter adjustments */
    --iseed;

    /* Function Body */
    t1 = slaran_(&iseed[1]);

    if (*idist == 1) {

/*        uniform (0,1) */

	ret_val = t1;
    } else if (*idist == 2) {

/*        uniform (-1,1) */

	ret_val = t1 * 2.f - 1.f;
    } else if (*idist == 3) {

/*        normal (0,1) */

	t2 = slaran_(&iseed[1]);
	ret_val = sqrt(log(t1) * -2.f) * cos(t2 * 
		6.2831853071795864769252867663f);
    }
    return ret_val;

/*     End of SLARND */

} /* slarnd_ */
Example #2
0
/* Subroutine */ int slatm4_(integer *itype, integer *n, integer *nz1, 
	integer *nz2, integer *isign, real *amagn, real *rcond, real *triang, 
	integer *idist, integer *iseed, real *a, integer *lda)
{
    /* System generated locals */
    integer a_dim1, a_offset, i__1, i__2, i__3, i__4;
    real r__1, r__2, r__3, r__4;
    doublereal d__1, d__2;

    /* Builtin functions */
    double pow_dd(doublereal *, doublereal *), pow_ri(real *, integer *), log(
	    doublereal), exp(doublereal), sqrt(doublereal);

    /* Local variables */
    static integer kbeg, isdb, kend, ioff, isde, klen;
    static real temp;
    static integer i__, k;
    static real alpha;
    static integer jc, jd;
    static real cl, cr;
    static integer jr;
    static real sl, sr;
    extern doublereal slamch_(char *);
    static real safmin;
    extern doublereal slaran_(integer *), slarnd_(integer *, integer *);
    extern /* Subroutine */ int slaset_(char *, integer *, integer *, real *, 
	    real *, real *, integer *);
    static real sv1, sv2;


#define a_ref(a_1,a_2) a[(a_2)*a_dim1 + a_1]


/*  -- LAPACK auxiliary test routine (version 3.0) --   
       Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,   
       Courant Institute, Argonne National Lab, and Rice University   
       September 30, 1994   


    Purpose   
    =======   

    SLATM4 generates basic square matrices, which may later be   
    multiplied by others in order to produce test matrices.  It is   
    intended mainly to be used to test the generalized eigenvalue   
    routines.   

    It first generates the diagonal and (possibly) subdiagonal,   
    according to the value of ITYPE, NZ1, NZ2, ISIGN, AMAGN, and RCOND.   
    It then fills in the upper triangle with random numbers, if TRIANG is   
    non-zero.   

    Arguments   
    =========   

    ITYPE   (input) INTEGER   
            The "type" of matrix on the diagonal and sub-diagonal.   
            If ITYPE < 0, then type abs(ITYPE) is generated and then   
               swapped end for end (A(I,J) := A'(N-J,N-I).)  See also   
               the description of AMAGN and ISIGN.   

            Special types:   
            = 0:  the zero matrix.   
            = 1:  the identity.   
            = 2:  a transposed Jordan block.   
            = 3:  If N is odd, then a k+1 x k+1 transposed Jordan block   
                  followed by a k x k identity block, where k=(N-1)/2.   
                  If N is even, then k=(N-2)/2, and a zero diagonal entry   
                  is tacked onto the end.   

            Diagonal types.  The diagonal consists of NZ1 zeros, then   
               k=N-NZ1-NZ2 nonzeros.  The subdiagonal is zero.  ITYPE   
               specifies the nonzero diagonal entries as follows:   
            = 4:  1, ..., k   
            = 5:  1, RCOND, ..., RCOND   
            = 6:  1, ..., 1, RCOND   
            = 7:  1, a, a^2, ..., a^(k-1)=RCOND   
            = 8:  1, 1-d, 1-2*d, ..., 1-(k-1)*d=RCOND   
            = 9:  random numbers chosen from (RCOND,1)   
            = 10: random numbers with distribution IDIST (see SLARND.)   

    N       (input) INTEGER   
            The order of the matrix.   

    NZ1     (input) INTEGER   
            If abs(ITYPE) > 3, then the first NZ1 diagonal entries will   
            be zero.   

    NZ2     (input) INTEGER   
            If abs(ITYPE) > 3, then the last NZ2 diagonal entries will   
            be zero.   

    ISIGN   (input) INTEGER   
            = 0: The sign of the diagonal and subdiagonal entries will   
                 be left unchanged.   
            = 1: The diagonal and subdiagonal entries will have their   
                 sign changed at random.   
            = 2: If ITYPE is 2 or 3, then the same as ISIGN=1.   
                 Otherwise, with probability 0.5, odd-even pairs of   
                 diagonal entries A(2*j-1,2*j-1), A(2*j,2*j) will be   
                 converted to a 2x2 block by pre- and post-multiplying   
                 by distinct random orthogonal rotations.  The remaining   
                 diagonal entries will have their sign changed at random.   

    AMAGN   (input) REAL   
            The diagonal and subdiagonal entries will be multiplied by   
            AMAGN.   

    RCOND   (input) REAL   
            If abs(ITYPE) > 4, then the smallest diagonal entry will be   
            entry will be RCOND.  RCOND must be between 0 and 1.   

    TRIANG  (input) REAL   
            The entries above the diagonal will be random numbers with   
            magnitude bounded by TRIANG (i.e., random numbers multiplied   
            by TRIANG.)   

    IDIST   (input) INTEGER   
            Specifies the type of distribution to be used to generate a   
            random matrix.   
            = 1:  UNIFORM( 0, 1 )   
            = 2:  UNIFORM( -1, 1 )   
            = 3:  NORMAL ( 0, 1 )   

    ISEED   (input/output) INTEGER array, dimension (4)   
            On entry ISEED specifies the seed of the random number   
            generator.  The values of ISEED are changed on exit, and can   
            be used in the next call to SLATM4 to continue the same   
            random number sequence.   
            Note: ISEED(4) should be odd, for the random number generator   
            used at present.   

    A       (output) REAL array, dimension (LDA, N)   
            Array to be computed.   

    LDA     (input) INTEGER   
            Leading dimension of A.  Must be at least 1 and at least N.   

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


       Parameter adjustments */
    --iseed;
    a_dim1 = *lda;
    a_offset = 1 + a_dim1 * 1;
    a -= a_offset;

    /* Function Body */
    if (*n <= 0) {
	return 0;
    }
    slaset_("Full", n, n, &c_b3, &c_b3, &a[a_offset], lda);

/*     Insure a correct ISEED */

    if (iseed[4] % 2 != 1) {
	++iseed[4];
    }

/*     Compute diagonal and subdiagonal according to ITYPE, NZ1, NZ2,   
       and RCOND */

    if (*itype != 0) {
	if (abs(*itype) >= 4) {
/* Computing MAX   
   Computing MIN */
	    i__3 = *n, i__4 = *nz1 + 1;
	    i__1 = 1, i__2 = min(i__3,i__4);
	    kbeg = max(i__1,i__2);
/* Computing MAX   
   Computing MIN */
	    i__3 = *n, i__4 = *n - *nz2;
	    i__1 = kbeg, i__2 = min(i__3,i__4);
	    kend = max(i__1,i__2);
	    klen = kend + 1 - kbeg;
	} else {
	    kbeg = 1;
	    kend = *n;
	    klen = *n;
	}
	isdb = 1;
	isde = 0;
	switch (abs(*itype)) {
	    case 1:  goto L10;
	    case 2:  goto L30;
	    case 3:  goto L50;
	    case 4:  goto L80;
	    case 5:  goto L100;
	    case 6:  goto L120;
	    case 7:  goto L140;
	    case 8:  goto L160;
	    case 9:  goto L180;
	    case 10:  goto L200;
	}

/*        |ITYPE| = 1: Identity */

L10:
	i__1 = *n;
	for (jd = 1; jd <= i__1; ++jd) {
	    a_ref(jd, jd) = 1.f;
/* L20: */
	}
	goto L220;

/*        |ITYPE| = 2: Transposed Jordan block */

L30:
	i__1 = *n - 1;
	for (jd = 1; jd <= i__1; ++jd) {
	    a_ref(jd + 1, jd) = 1.f;
/* L40: */
	}
	isdb = 1;
	isde = *n - 1;
	goto L220;

/*        |ITYPE| = 3: Transposed Jordan block, followed by the identity. */

L50:
	k = (*n - 1) / 2;
	i__1 = k;
	for (jd = 1; jd <= i__1; ++jd) {
	    a_ref(jd + 1, jd) = 1.f;
/* L60: */
	}
	isdb = 1;
	isde = k;
	i__1 = (k << 1) + 1;
	for (jd = k + 2; jd <= i__1; ++jd) {
	    a_ref(jd, jd) = 1.f;
/* L70: */
	}
	goto L220;

/*        |ITYPE| = 4: 1,...,k */

L80:
	i__1 = kend;
	for (jd = kbeg; jd <= i__1; ++jd) {
	    a_ref(jd, jd) = (real) (jd - *nz1);
/* L90: */
	}
	goto L220;

/*        |ITYPE| = 5: One large D value: */

L100:
	i__1 = kend;
	for (jd = kbeg + 1; jd <= i__1; ++jd) {
	    a_ref(jd, jd) = *rcond;
/* L110: */
	}
	a_ref(kbeg, kbeg) = 1.f;
	goto L220;

/*        |ITYPE| = 6: One small D value: */

L120:
	i__1 = kend - 1;
	for (jd = kbeg; jd <= i__1; ++jd) {
	    a_ref(jd, jd) = 1.f;
/* L130: */
	}
	a_ref(kend, kend) = *rcond;
	goto L220;

/*        |ITYPE| = 7: Exponentially distributed D values: */

L140:
	a_ref(kbeg, kbeg) = 1.f;
	if (klen > 1) {
	    d__1 = (doublereal) (*rcond);
	    d__2 = (doublereal) (1.f / (real) (klen - 1));
	    alpha = pow_dd(&d__1, &d__2);
	    i__1 = klen;
	    for (i__ = 2; i__ <= i__1; ++i__) {
		i__2 = i__ - 1;
		a_ref(*nz1 + i__, *nz1 + i__) = pow_ri(&alpha, &i__2);
/* L150: */
	    }
	}
	goto L220;

/*        |ITYPE| = 8: Arithmetically distributed D values: */

L160:
	a_ref(kbeg, kbeg) = 1.f;
	if (klen > 1) {
	    alpha = (1.f - *rcond) / (real) (klen - 1);
	    i__1 = klen;
	    for (i__ = 2; i__ <= i__1; ++i__) {
		a_ref(*nz1 + i__, *nz1 + i__) = (real) (klen - i__) * alpha + 
			*rcond;
/* L170: */
	    }
	}
	goto L220;

/*        |ITYPE| = 9: Randomly distributed D values on ( RCOND, 1): */

L180:
	alpha = log(*rcond);
	i__1 = kend;
	for (jd = kbeg; jd <= i__1; ++jd) {
	    a_ref(jd, jd) = exp(alpha * slaran_(&iseed[1]));
/* L190: */
	}
	goto L220;

/*        |ITYPE| = 10: Randomly distributed D values from DIST */

L200:
	i__1 = kend;
	for (jd = kbeg; jd <= i__1; ++jd) {
	    a_ref(jd, jd) = slarnd_(idist, &iseed[1]);
/* L210: */
	}

L220:

/*        Scale by AMAGN */

	i__1 = kend;
	for (jd = kbeg; jd <= i__1; ++jd) {
	    a_ref(jd, jd) = *amagn * a_ref(jd, jd);
/* L230: */
	}
	i__1 = isde;
	for (jd = isdb; jd <= i__1; ++jd) {
	    a_ref(jd + 1, jd) = *amagn * a_ref(jd + 1, jd);
/* L240: */
	}

/*        If ISIGN = 1 or 2, assign random signs to diagonal and   
          subdiagonal */

	if (*isign > 0) {
	    i__1 = kend;
	    for (jd = kbeg; jd <= i__1; ++jd) {
		if (a_ref(jd, jd) != 0.f) {
		    if (slaran_(&iseed[1]) > .5f) {
			a_ref(jd, jd) = -a_ref(jd, jd);
		    }
		}
/* L250: */
	    }
	    i__1 = isde;
	    for (jd = isdb; jd <= i__1; ++jd) {
		if (a_ref(jd + 1, jd) != 0.f) {
		    if (slaran_(&iseed[1]) > .5f) {
			a_ref(jd + 1, jd) = -a_ref(jd + 1, jd);
		    }
		}
/* L260: */
	    }
	}

/*        Reverse if ITYPE < 0 */

	if (*itype < 0) {
	    i__1 = (kbeg + kend - 1) / 2;
	    for (jd = kbeg; jd <= i__1; ++jd) {
		temp = a_ref(jd, jd);
		a_ref(jd, jd) = a_ref(kbeg + kend - jd, kbeg + kend - jd);
		a_ref(kbeg + kend - jd, kbeg + kend - jd) = temp;
/* L270: */
	    }
	    i__1 = (*n - 1) / 2;
	    for (jd = 1; jd <= i__1; ++jd) {
		temp = a_ref(jd + 1, jd);
		a_ref(jd + 1, jd) = a_ref(*n + 1 - jd, *n - jd);
		a_ref(*n + 1 - jd, *n - jd) = temp;
/* L280: */
	    }
	}

/*        If ISIGN = 2, and no subdiagonals already, then apply   
          random rotations to make 2x2 blocks. */

	if (*isign == 2 && *itype != 2 && *itype != 3) {
	    safmin = slamch_("S");
	    i__1 = kend - 1;
	    for (jd = kbeg; jd <= i__1; jd += 2) {
		if (slaran_(&iseed[1]) > .5f) {

/*                 Rotation on left. */

		    cl = slaran_(&iseed[1]) * 2.f - 1.f;
		    sl = slaran_(&iseed[1]) * 2.f - 1.f;
/* Computing MAX   
   Computing 2nd power */
		    r__3 = cl;
/* Computing 2nd power */
		    r__4 = sl;
		    r__1 = safmin, r__2 = sqrt(r__3 * r__3 + r__4 * r__4);
		    temp = 1.f / dmax(r__1,r__2);
		    cl *= temp;
		    sl *= temp;

/*                 Rotation on right. */

		    cr = slaran_(&iseed[1]) * 2.f - 1.f;
		    sr = slaran_(&iseed[1]) * 2.f - 1.f;
/* Computing MAX   
   Computing 2nd power */
		    r__3 = cr;
/* Computing 2nd power */
		    r__4 = sr;
		    r__1 = safmin, r__2 = sqrt(r__3 * r__3 + r__4 * r__4);
		    temp = 1.f / dmax(r__1,r__2);
		    cr *= temp;
		    sr *= temp;

/*                 Apply */

		    sv1 = a_ref(jd, jd);
		    sv2 = a_ref(jd + 1, jd + 1);
		    a_ref(jd, jd) = cl * cr * sv1 + sl * sr * sv2;
		    a_ref(jd + 1, jd) = -sl * cr * sv1 + cl * sr * sv2;
		    a_ref(jd, jd + 1) = -cl * sr * sv1 + sl * cr * sv2;
		    a_ref(jd + 1, jd + 1) = sl * sr * sv1 + cl * cr * sv2;
		}
/* L290: */
	    }
	}

    }

/*     Fill in upper triangle (except for 2x2 blocks) */

    if (*triang != 0.f) {
	if (*isign != 2 || *itype == 2 || *itype == 3) {
	    ioff = 1;
	} else {
	    ioff = 2;
	    i__1 = *n - 1;
	    for (jr = 1; jr <= i__1; ++jr) {
		if (a_ref(jr + 1, jr) == 0.f) {
		    a_ref(jr, jr + 1) = *triang * slarnd_(idist, &iseed[1]);
		}
/* L300: */
	    }
	}

	i__1 = *n;
	for (jc = 2; jc <= i__1; ++jc) {
	    i__2 = jc - ioff;
	    for (jr = 1; jr <= i__2; ++jr) {
		a_ref(jr, jc) = *triang * slarnd_(idist, &iseed[1]);
/* L310: */
	    }
/* L320: */
	}
    }

    return 0;

/*     End of SLATM4 */

} /* slatm4_ */
Example #3
0
doublereal slatm3_(integer *m, integer *n, integer *i__, integer *j, integer *
	isub, integer *jsub, integer *kl, integer *ku, integer *idist, 
	integer *iseed, real *d__, integer *igrade, real *dl, real *dr, 
	integer *ipvtng, integer *iwork, real *sparse)
{
    /* System generated locals */
    real ret_val;

    /* Local variables */
    real temp;
    extern doublereal slaran_(integer *), slarnd_(integer *, integer *);


/*  -- LAPACK auxiliary test routine (version 3.1) -- */
/*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
/*     November 2006 */

/*     .. Scalar Arguments .. */

/*     .. */

/*     .. Array Arguments .. */

/*     .. */

/*  Purpose */
/*  ======= */

/*     SLATM3 returns the (ISUB,JSUB) entry of a random matrix of */
/*     dimension (M, N) described by the other paramters. (ISUB,JSUB) */
/*     is the final position of the (I,J) entry after pivoting */
/*     according to IPVTNG and IWORK. SLATM3 is called by the */
/*     SLATMR routine in order to build random test matrices. No error */
/*     checking on parameters is done, because this routine is called in */
/*     a tight loop by SLATMR which has already checked the parameters. */

/*     Use of SLATM3 differs from SLATM2 in the order in which the random */
/*     number generator is called to fill in random matrix entries. */
/*     With SLATM2, the generator is called to fill in the pivoted matrix */
/*     columnwise. With SLATM3, the generator is called to fill in the */
/*     matrix columnwise, after which it is pivoted. Thus, SLATM3 can */
/*     be used to construct random matrices which differ only in their */
/*     order of rows and/or columns. SLATM2 is used to construct band */
/*     matrices while avoiding calling the random number generator for */
/*     entries outside the band (and therefore generating random numbers */
/*     in different orders for different pivot orders). */

/*     The matrix whose (ISUB,JSUB) entry is returned is constructed as */
/*     follows (this routine only computes one entry): */

/*       If ISUB is outside (1..M) or JSUB is outside (1..N), return zero */
/*          (this is convenient for generating matrices in band format). */

/*       Generate a matrix A with random entries of distribution IDIST. */

/*       Set the diagonal to D. */

/*       Grade the matrix, if desired, from the left (by DL) and/or */
/*          from the right (by DR or DL) as specified by IGRADE. */

/*       Permute, if desired, the rows and/or columns as specified by */
/*          IPVTNG and IWORK. */

/*       Band the matrix to have lower bandwidth KL and upper */
/*          bandwidth KU. */

/*       Set random entries to zero as specified by SPARSE. */

/*  Arguments */
/*  ========= */

/*  M      - INTEGER */
/*           Number of rows of matrix. Not modified. */

/*  N      - INTEGER */
/*           Number of columns of matrix. Not modified. */

/*  I      - INTEGER */
/*           Row of unpivoted entry to be returned. Not modified. */

/*  J      - INTEGER */
/*           Column of unpivoted entry to be returned. Not modified. */

/*  ISUB   - INTEGER */
/*           Row of pivoted entry to be returned. Changed on exit. */

/*  JSUB   - INTEGER */
/*           Column of pivoted entry to be returned. Changed on exit. */

/*  KL     - INTEGER */
/*           Lower bandwidth. Not modified. */

/*  KU     - INTEGER */
/*           Upper bandwidth. Not modified. */

/*  IDIST  - INTEGER */
/*           On entry, IDIST specifies the type of distribution to be */
/*           used to generate a random matrix . */
/*           1 => UNIFORM( 0, 1 ) */
/*           2 => UNIFORM( -1, 1 ) */
/*           3 => NORMAL( 0, 1 ) */
/*           Not modified. */

/*  ISEED  - INTEGER array of dimension ( 4 ) */
/*           Seed for random number generator. */
/*           Changed on exit. */

/*  D      - REAL array of dimension ( MIN( I , J ) ) */
/*           Diagonal entries of matrix. Not modified. */

/*  IGRADE - INTEGER */
/*           Specifies grading of matrix as follows: */
/*           0  => no grading */
/*           1  => matrix premultiplied by diag( DL ) */
/*           2  => matrix postmultiplied by diag( DR ) */
/*           3  => matrix premultiplied by diag( DL ) and */
/*                         postmultiplied by diag( DR ) */
/*           4  => matrix premultiplied by diag( DL ) and */
/*                         postmultiplied by inv( diag( DL ) ) */
/*           5  => matrix premultiplied by diag( DL ) and */
/*                         postmultiplied by diag( DL ) */
/*           Not modified. */

/*  DL     - REAL array ( I or J, as appropriate ) */
/*           Left scale factors for grading matrix.  Not modified. */

/*  DR     - REAL array ( I or J, as appropriate ) */
/*           Right scale factors for grading matrix.  Not modified. */

/*  IPVTNG - INTEGER */
/*           On entry specifies pivoting permutations as follows: */
/*           0 => none. */
/*           1 => row pivoting. */
/*           2 => column pivoting. */
/*           3 => full pivoting, i.e., on both sides. */
/*           Not modified. */

/*  IWORK  - INTEGER array ( I or J, as appropriate ) */
/*           This array specifies the permutation used. The */
/*           row (or column) originally in position K is in */
/*           position IWORK( K ) after pivoting. */
/*           This differs from IWORK for SLATM2. Not modified. */

/*  SPARSE - REAL between 0. and 1. */
/*           On entry specifies the sparsity of the matrix */
/*           if sparse matix is to be generated. */
/*           SPARSE should lie between 0 and 1. */
/*           A uniform ( 0, 1 ) random number x is generated and */
/*           compared to SPARSE; if x is larger the matrix entry */
/*           is unchanged and if x is smaller the entry is set */
/*           to zero. Thus on the average a fraction SPARSE of the */
/*           entries will be set to zero. */
/*           Not modified. */

/*  ===================================================================== */

/*     .. Parameters .. */

/*     .. */

/*     .. Local Scalars .. */

/*     .. */

/*     .. External Functions .. */

/*     .. */

/* ----------------------------------------------------------------------- */

/*     .. Executable Statements .. */


/*     Check for I and J in range */

    /* Parameter adjustments */
    --iwork;
    --dr;
    --dl;
    --d__;
    --iseed;

    /* Function Body */
    if (*i__ < 1 || *i__ > *m || *j < 1 || *j > *n) {
	*isub = *i__;
	*jsub = *j;
	ret_val = 0.f;
	return ret_val;
    }

/*     Compute subscripts depending on IPVTNG */

    if (*ipvtng == 0) {
	*isub = *i__;
	*jsub = *j;
    } else if (*ipvtng == 1) {
	*isub = iwork[*i__];
	*jsub = *j;
    } else if (*ipvtng == 2) {
	*isub = *i__;
	*jsub = iwork[*j];
    } else if (*ipvtng == 3) {
	*isub = iwork[*i__];
	*jsub = iwork[*j];
    }

/*     Check for banding */

    if (*jsub > *isub + *ku || *jsub < *isub - *kl) {
	ret_val = 0.f;
	return ret_val;
    }

/*     Check for sparsity */

    if (*sparse > 0.f) {
	if (slaran_(&iseed[1]) < *sparse) {
	    ret_val = 0.f;
	    return ret_val;
	}
    }

/*     Compute entry and grade it according to IGRADE */

    if (*i__ == *j) {
	temp = d__[*i__];
    } else {
	temp = slarnd_(idist, &iseed[1]);
    }
    if (*igrade == 1) {
	temp *= dl[*i__];
    } else if (*igrade == 2) {
	temp *= dr[*j];
    } else if (*igrade == 3) {
	temp = temp * dl[*i__] * dr[*j];
    } else if (*igrade == 4 && *i__ != *j) {
	temp = temp * dl[*i__] / dl[*j];
    } else if (*igrade == 5) {
	temp = temp * dl[*i__] * dl[*j];
    }
    ret_val = temp;
    return ret_val;

/*     End of SLATM3 */

} /* slatm3_ */
Example #4
0
/* Subroutine */ int slatme_(integer *n, char *dist, integer *iseed, real *
                             d__, integer *mode, real *cond, real *dmax__, char *ei, char *rsign,
                             char *upper, char *sim, real *ds, integer *modes, real *conds,
                             integer *kl, integer *ku, real *anorm, real *a, integer *lda, real *
                             work, integer *info)
{
    /* System generated locals */
    integer a_dim1, a_offset, i__1, i__2;
    real r__1, r__2, r__3;

    /* Local variables */
    static logical bads;
    extern /* Subroutine */ int sger_(integer *, integer *, real *, real *,
                                      integer *, real *, integer *, real *, integer *);
    static integer isim;
    static real temp;
    static logical badei;
    static integer i__, j;
    static real alpha;
    extern logical lsame_(char *, char *);
    static integer iinfo;
    extern /* Subroutine */ int sscal_(integer *, real *, real *, integer *);
    static real tempa[1];
    static integer icols;
    static logical useei;
    static integer idist;
    extern /* Subroutine */ int sgemv_(char *, integer *, integer *, real *,
                                       real *, integer *, real *, integer *, real *, real *, integer *), scopy_(integer *, real *, integer *, real *, integer *);
    static integer irows;
    extern /* Subroutine */ int slatm1_(integer *, real *, integer *, integer
                                        *, integer *, real *, integer *, integer *);
    static integer ic, jc, ir, jr;
    extern doublereal slange_(char *, integer *, integer *, real *, integer *,
                              real *);
    extern /* Subroutine */ int slarge_(integer *, real *, integer *, integer
                                        *, real *, integer *), slarfg_(integer *, real *, real *, integer
                                                *, real *), xerbla_(char *, integer *);
    extern doublereal slaran_(integer *);
    static integer irsign;
    extern /* Subroutine */ int slaset_(char *, integer *, integer *, real *,
                                        real *, real *, integer *);
    static integer iupper;
    extern /* Subroutine */ int slarnv_(integer *, integer *, integer *, real
                                        *);
    static real xnorms;
    static integer jcr;
    static real tau;


#define a_ref(a_1,a_2) a[(a_2)*a_dim1 + a_1]


    /*  -- LAPACK test routine (version 3.0) --
           Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
           Courant Institute, Argonne National Lab, and Rice University
           September 30, 1994


        Purpose
        =======

           SLATME generates random non-symmetric square matrices with
           specified eigenvalues for testing LAPACK programs.

           SLATME operates by applying the following sequence of
           operations:

           1. Set the diagonal to D, where D may be input or
                computed according to MODE, COND, DMAX, and RSIGN
                as described below.

           2. If complex conjugate pairs are desired (MODE=0 and EI(1)='R',
                or MODE=5), certain pairs of adjacent elements of D are
                interpreted as the real and complex parts of a complex
                conjugate pair; A thus becomes block diagonal, with 1x1
                and 2x2 blocks.

           3. If UPPER='T', the upper triangle of A is set to random values
                out of distribution DIST.

           4. If SIM='T', A is multiplied on the left by a random matrix
                X, whose singular values are specified by DS, MODES, and
                CONDS, and on the right by X inverse.

           5. If KL < N-1, the lower bandwidth is reduced to KL using
                Householder transformations.  If KU < N-1, the upper
                bandwidth is reduced to KU.

           6. If ANORM is not negative, the matrix is scaled to have
                maximum-element-norm ANORM.

           (Note: since the matrix cannot be reduced beyond Hessenberg form,
            no packing options are available.)

        Arguments
        =========

        N      - INTEGER
                 The number of columns (or rows) of A. Not modified.

        DIST   - CHARACTER*1
                 On entry, DIST specifies the type of distribution to be used
                 to generate the random eigen-/singular values, and for the
                 upper triangle (see UPPER).
                 'U' => UNIFORM( 0, 1 )  ( 'U' for uniform )
                 'S' => UNIFORM( -1, 1 ) ( 'S' for symmetric )
                 'N' => NORMAL( 0, 1 )   ( 'N' for normal )
                 Not modified.

        ISEED  - INTEGER array, dimension ( 4 )
                 On entry ISEED specifies the seed of the random number
                 generator. They should lie between 0 and 4095 inclusive,
                 and ISEED(4) should be odd. The random number generator
                 uses a linear congruential sequence limited to small
                 integers, and so should produce machine independent
                 random numbers. The values of ISEED are changed on
                 exit, and can be used in the next call to SLATME
                 to continue the same random number sequence.
                 Changed on exit.

        D      - REAL array, dimension ( N )
                 This array is used to specify the eigenvalues of A.  If
                 MODE=0, then D is assumed to contain the eigenvalues (but
                 see the description of EI), otherwise they will be
                 computed according to MODE, COND, DMAX, and RSIGN and
                 placed in D.
                 Modified if MODE is nonzero.

        MODE   - INTEGER
                 On entry this describes how the eigenvalues are to
                 be specified:
                 MODE = 0 means use D (with EI) as input
                 MODE = 1 sets D(1)=1 and D(2:N)=1.0/COND
                 MODE = 2 sets D(1:N-1)=1 and D(N)=1.0/COND
                 MODE = 3 sets D(I)=COND**(-(I-1)/(N-1))
                 MODE = 4 sets D(i)=1 - (i-1)/(N-1)*(1 - 1/COND)
                 MODE = 5 sets D to random numbers in the range
                          ( 1/COND , 1 ) such that their logarithms
                          are uniformly distributed.  Each odd-even pair
                          of elements will be either used as two real
                          eigenvalues or as the real and imaginary part
                          of a complex conjugate pair of eigenvalues;
                          the choice of which is done is random, with
                          50-50 probability, for each pair.
                 MODE = 6 set D to random numbers from same distribution
                          as the rest of the matrix.
                 MODE < 0 has the same meaning as ABS(MODE), except that
                    the order of the elements of D is reversed.
                 Thus if MODE is between 1 and 4, D has entries ranging
                    from 1 to 1/COND, if between -1 and -4, D has entries
                    ranging from 1/COND to 1,
                 Not modified.

        COND   - REAL
                 On entry, this is used as described under MODE above.
                 If used, it must be >= 1. Not modified.

        DMAX   - REAL
                 If MODE is neither -6, 0 nor 6, the contents of D, as
                 computed according to MODE and COND, will be scaled by
                 DMAX / max(abs(D(i))).  Note that DMAX need not be
                 positive: if DMAX is negative (or zero), D will be
                 scaled by a negative number (or zero).
                 Not modified.

        EI     - CHARACTER*1 array, dimension ( N )
                 If MODE is 0, and EI(1) is not ' ' (space character),
                 this array specifies which elements of D (on input) are
                 real eigenvalues and which are the real and imaginary parts
                 of a complex conjugate pair of eigenvalues.  The elements
                 of EI may then only have the values 'R' and 'I'.  If
                 EI(j)='R' and EI(j+1)='I', then the j-th eigenvalue is
                 CMPLX( D(j) , D(j+1) ), and the (j+1)-th is the complex
                 conjugate thereof.  If EI(j)=EI(j+1)='R', then the j-th
                 eigenvalue is D(j) (i.e., real).  EI(1) may not be 'I',
                 nor may two adjacent elements of EI both have the value 'I'.
                 If MODE is not 0, then EI is ignored.  If MODE is 0 and
                 EI(1)=' ', then the eigenvalues will all be real.
                 Not modified.

        RSIGN  - CHARACTER*1
                 If MODE is not 0, 6, or -6, and RSIGN='T', then the
                 elements of D, as computed according to MODE and COND, will
                 be multiplied by a random sign (+1 or -1).  If RSIGN='F',
                 they will not be.  RSIGN may only have the values 'T' or
                 'F'.
                 Not modified.

        UPPER  - CHARACTER*1
                 If UPPER='T', then the elements of A above the diagonal
                 (and above the 2x2 diagonal blocks, if A has complex
                 eigenvalues) will be set to random numbers out of DIST.
                 If UPPER='F', they will not.  UPPER may only have the
                 values 'T' or 'F'.
                 Not modified.

        SIM    - CHARACTER*1
                 If SIM='T', then A will be operated on by a "similarity
                 transform", i.e., multiplied on the left by a matrix X and
                 on the right by X inverse.  X = U S V, where U and V are
                 random unitary matrices and S is a (diagonal) matrix of
                 singular values specified by DS, MODES, and CONDS.  If
                 SIM='F', then A will not be transformed.
                 Not modified.

        DS     - REAL array, dimension ( N )
                 This array is used to specify the singular values of X,
                 in the same way that D specifies the eigenvalues of A.
                 If MODE=0, the DS contains the singular values, which
                 may not be zero.
                 Modified if MODE is nonzero.

        MODES  - INTEGER
        CONDS  - REAL
                 Same as MODE and COND, but for specifying the diagonal
                 of S.  MODES=-6 and +6 are not allowed (since they would
                 result in randomly ill-conditioned eigenvalues.)

        KL     - INTEGER
                 This specifies the lower bandwidth of the  matrix.  KL=1
                 specifies upper Hessenberg form.  If KL is at least N-1,
                 then A will have full lower bandwidth.  KL must be at
                 least 1.
                 Not modified.

        KU     - INTEGER
                 This specifies the upper bandwidth of the  matrix.  KU=1
                 specifies lower Hessenberg form.  If KU is at least N-1,
                 then A will have full upper bandwidth; if KU and KL
                 are both at least N-1, then A will be dense.  Only one of
                 KU and KL may be less than N-1.  KU must be at least 1.
                 Not modified.

        ANORM  - REAL
                 If ANORM is not negative, then A will be scaled by a non-
                 negative real number to make the maximum-element-norm of A
                 to be ANORM.
                 Not modified.

        A      - REAL array, dimension ( LDA, N )
                 On exit A is the desired test matrix.
                 Modified.

        LDA    - INTEGER
                 LDA specifies the first dimension of A as declared in the
                 calling program.  LDA must be at least N.
                 Not modified.

        WORK   - REAL array, dimension ( 3*N )
                 Workspace.
                 Modified.

        INFO   - INTEGER
                 Error code.  On exit, INFO will be set to one of the
                 following values:
                   0 => normal return
                  -1 => N negative
                  -2 => DIST illegal string
                  -5 => MODE not in range -6 to 6
                  -6 => COND less than 1.0, and MODE neither -6, 0 nor 6
                  -8 => EI(1) is not ' ' or 'R', EI(j) is not 'R' or 'I', or
                        two adjacent elements of EI are 'I'.
                  -9 => RSIGN is not 'T' or 'F'
                 -10 => UPPER is not 'T' or 'F'
                 -11 => SIM   is not 'T' or 'F'
                 -12 => MODES=0 and DS has a zero singular value.
                 -13 => MODES is not in the range -5 to 5.
                 -14 => MODES is nonzero and CONDS is less than 1.
                 -15 => KL is less than 1.
                 -16 => KU is less than 1, or KL and KU are both less than
                        N-1.
                 -19 => LDA is less than N.
                  1  => Error return from SLATM1 (computing D)
                  2  => Cannot scale to DMAX (max. eigenvalue is 0)
                  3  => Error return from SLATM1 (computing DS)
                  4  => Error return from SLARGE
                  5  => Zero singular value from SLATM1.

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


           1)      Decode and Test the input parameters.
                   Initialize flags & seed.

           Parameter adjustments */
    --iseed;
    --d__;
    --ei;
    --ds;
    a_dim1 = *lda;
    a_offset = 1 + a_dim1 * 1;
    a -= a_offset;
    --work;

    /* Function Body */
    *info = 0;

    /*     Quick return if possible */

    if (*n == 0) {
        return 0;
    }

    /*     Decode DIST */

    if (lsame_(dist, "U")) {
        idist = 1;
    } else if (lsame_(dist, "S")) {
        idist = 2;
    } else if (lsame_(dist, "N")) {
        idist = 3;
    } else {
        idist = -1;
    }

    /*     Check EI */

    useei = TRUE_;
    badei = FALSE_;
    if (lsame_(ei + 1, " ") || *mode != 0) {
        useei = FALSE_;
    } else {
        if (lsame_(ei + 1, "R")) {
            i__1 = *n;
            for (j = 2; j <= i__1; ++j) {
                if (lsame_(ei + j, "I")) {
                    if (lsame_(ei + (j - 1), "I")) {
                        badei = TRUE_;
                    }
                } else {
                    if (! lsame_(ei + j, "R")) {
                        badei = TRUE_;
                    }
                }
                /* L10: */
            }
        } else {
            badei = TRUE_;
        }
    }

    /*     Decode RSIGN */

    if (lsame_(rsign, "T")) {
        irsign = 1;
    } else if (lsame_(rsign, "F")) {
        irsign = 0;
    } else {
        irsign = -1;
    }

    /*     Decode UPPER */

    if (lsame_(upper, "T")) {
        iupper = 1;
    } else if (lsame_(upper, "F")) {
        iupper = 0;
    } else {
        iupper = -1;
    }

    /*     Decode SIM */

    if (lsame_(sim, "T")) {
        isim = 1;
    } else if (lsame_(sim, "F")) {
        isim = 0;
    } else {
        isim = -1;
    }

    /*     Check DS, if MODES=0 and ISIM=1 */

    bads = FALSE_;
    if (*modes == 0 && isim == 1) {
        i__1 = *n;
        for (j = 1; j <= i__1; ++j) {
            if (ds[j] == 0.f) {
                bads = TRUE_;
            }
            /* L20: */
        }
    }

    /*     Set INFO if an error */

    if (*n < 0) {
        *info = -1;
    } else if (idist == -1) {
        *info = -2;
    } else if (abs(*mode) > 6) {
        *info = -5;
    } else if (*mode != 0 && abs(*mode) != 6 && *cond < 1.f) {
        *info = -6;
    } else if (badei) {
        *info = -8;
    } else if (irsign == -1) {
        *info = -9;
    } else if (iupper == -1) {
        *info = -10;
    } else if (isim == -1) {
        *info = -11;
    } else if (bads) {
        *info = -12;
    } else if (isim == 1 && abs(*modes) > 5) {
        *info = -13;
    } else if (isim == 1 && *modes != 0 && *conds < 1.f) {
        *info = -14;
    } else if (*kl < 1) {
        *info = -15;
    } else if (*ku < 1 || *ku < *n - 1 && *kl < *n - 1) {
        *info = -16;
    } else if (*lda < max(1,*n)) {
        *info = -19;
    }

    if (*info != 0) {
        i__1 = -(*info);
        xerbla_("SLATME", &i__1);
        return 0;
    }

    /*     Initialize random number generator */

    for (i__ = 1; i__ <= 4; ++i__) {
        iseed[i__] = (i__1 = iseed[i__], abs(i__1)) % 4096;
        /* L30: */
    }

    if (iseed[4] % 2 != 1) {
        ++iseed[4];
    }

    /*     2)      Set up diagonal of A

                   Compute D according to COND and MODE */

    slatm1_(mode, cond, &irsign, &idist, &iseed[1], &d__[1], n, &iinfo);
    if (iinfo != 0) {
        *info = 1;
        return 0;
    }
    if (*mode != 0 && abs(*mode) != 6) {

        /*        Scale by DMAX */

        temp = dabs(d__[1]);
        i__1 = *n;
        for (i__ = 2; i__ <= i__1; ++i__) {
            /* Computing MAX */
            r__2 = temp, r__3 = (r__1 = d__[i__], dabs(r__1));
            temp = dmax(r__2,r__3);
            /* L40: */
        }

        if (temp > 0.f) {
            alpha = *dmax__ / temp;
        } else if (*dmax__ != 0.f) {
            *info = 2;
            return 0;
        } else {
            alpha = 0.f;
        }

        sscal_(n, &alpha, &d__[1], &c__1);

    }

    slaset_("Full", n, n, &c_b23, &c_b23, &a[a_offset], lda);
    i__1 = *lda + 1;
    scopy_(n, &d__[1], &c__1, &a[a_offset], &i__1);

    /*     Set up complex conjugate pairs */

    if (*mode == 0) {
        if (useei) {
            i__1 = *n;
            for (j = 2; j <= i__1; ++j) {
                if (lsame_(ei + j, "I")) {
                    a_ref(j - 1, j) = a_ref(j, j);
                    a_ref(j, j - 1) = -a_ref(j, j);
                    a_ref(j, j) = a_ref(j - 1, j - 1);
                }
                /* L50: */
            }
        }

    } else if (abs(*mode) == 5) {

        i__1 = *n;
        for (j = 2; j <= i__1; j += 2) {
            if (slaran_(&iseed[1]) > .5f) {
                a_ref(j - 1, j) = a_ref(j, j);
                a_ref(j, j - 1) = -a_ref(j, j);
                a_ref(j, j) = a_ref(j - 1, j - 1);
            }
            /* L60: */
        }
    }

    /*     3)      If UPPER='T', set upper triangle of A to random numbers.
                   (but don't modify the corners of 2x2 blocks.) */

    if (iupper != 0) {
        i__1 = *n;
        for (jc = 2; jc <= i__1; ++jc) {
            if (a_ref(jc - 1, jc) != 0.f) {
                jr = jc - 2;
            } else {
                jr = jc - 1;
            }
            slarnv_(&idist, &iseed[1], &jr, &a_ref(1, jc));
            /* L70: */
        }
    }

    /*     4)      If SIM='T', apply similarity transformation.

                                      -1
                   Transform is  X A X  , where X = U S V, thus

                   it is  U S V A V' (1/S) U' */

    if (isim != 0) {

        /*        Compute S (singular values of the eigenvector matrix)
                  according to CONDS and MODES */

        slatm1_(modes, conds, &c__0, &c__0, &iseed[1], &ds[1], n, &iinfo);
        if (iinfo != 0) {
            *info = 3;
            return 0;
        }

        /*        Multiply by V and V' */

        slarge_(n, &a[a_offset], lda, &iseed[1], &work[1], &iinfo);
        if (iinfo != 0) {
            *info = 4;
            return 0;
        }

        /*        Multiply by S and (1/S) */

        i__1 = *n;
        for (j = 1; j <= i__1; ++j) {
            sscal_(n, &ds[j], &a_ref(j, 1), lda);
            if (ds[j] != 0.f) {
                r__1 = 1.f / ds[j];
                sscal_(n, &r__1, &a_ref(1, j), &c__1);
            } else {
                *info = 5;
                return 0;
            }
            /* L80: */
        }

        /*        Multiply by U and U' */

        slarge_(n, &a[a_offset], lda, &iseed[1], &work[1], &iinfo);
        if (iinfo != 0) {
            *info = 4;
            return 0;
        }
    }

    /*     5)      Reduce the bandwidth. */

    if (*kl < *n - 1) {

        /*        Reduce bandwidth -- kill column */

        i__1 = *n - 1;
        for (jcr = *kl + 1; jcr <= i__1; ++jcr) {
            ic = jcr - *kl;
            irows = *n + 1 - jcr;
            icols = *n + *kl - jcr;

            scopy_(&irows, &a_ref(jcr, ic), &c__1, &work[1], &c__1);
            xnorms = work[1];
            slarfg_(&irows, &xnorms, &work[2], &c__1, &tau);
            work[1] = 1.f;

            sgemv_("T", &irows, &icols, &c_b39, &a_ref(jcr, ic + 1), lda, &
                   work[1], &c__1, &c_b23, &work[irows + 1], &c__1);
            r__1 = -tau;
            sger_(&irows, &icols, &r__1, &work[1], &c__1, &work[irows + 1], &
                  c__1, &a_ref(jcr, ic + 1), lda);

            sgemv_("N", n, &irows, &c_b39, &a_ref(1, jcr), lda, &work[1], &
                   c__1, &c_b23, &work[irows + 1], &c__1);
            r__1 = -tau;
            sger_(n, &irows, &r__1, &work[irows + 1], &c__1, &work[1], &c__1,
                  &a_ref(1, jcr), lda);

            a_ref(jcr, ic) = xnorms;
            i__2 = irows - 1;
            slaset_("Full", &i__2, &c__1, &c_b23, &c_b23, &a_ref(jcr + 1, ic),
                    lda);
            /* L90: */
        }
    } else if (*ku < *n - 1) {

        /*        Reduce upper bandwidth -- kill a row at a time. */

        i__1 = *n - 1;
        for (jcr = *ku + 1; jcr <= i__1; ++jcr) {
            ir = jcr - *ku;
            irows = *n + *ku - jcr;
            icols = *n + 1 - jcr;

            scopy_(&icols, &a_ref(ir, jcr), lda, &work[1], &c__1);
            xnorms = work[1];
            slarfg_(&icols, &xnorms, &work[2], &c__1, &tau);
            work[1] = 1.f;

            sgemv_("N", &irows, &icols, &c_b39, &a_ref(ir + 1, jcr), lda, &
                   work[1], &c__1, &c_b23, &work[icols + 1], &c__1);
            r__1 = -tau;
            sger_(&irows, &icols, &r__1, &work[icols + 1], &c__1, &work[1], &
                  c__1, &a_ref(ir + 1, jcr), lda);

            sgemv_("C", &icols, n, &c_b39, &a_ref(jcr, 1), lda, &work[1], &
                   c__1, &c_b23, &work[icols + 1], &c__1);
            r__1 = -tau;
            sger_(&icols, n, &r__1, &work[1], &c__1, &work[icols + 1], &c__1,
                  &a_ref(jcr, 1), lda);

            a_ref(ir, jcr) = xnorms;
            i__2 = icols - 1;
            slaset_("Full", &c__1, &i__2, &c_b23, &c_b23, &a_ref(ir, jcr + 1),
                    lda);
            /* L100: */
        }
    }

    /*     Scale the matrix to have norm ANORM */

    if (*anorm >= 0.f) {
        temp = slange_("M", n, n, &a[a_offset], lda, tempa);
        if (temp > 0.f) {
            alpha = *anorm / temp;
            i__1 = *n;
            for (j = 1; j <= i__1; ++j) {
                sscal_(n, &alpha, &a_ref(1, j), &c__1);
                /* L110: */
            }
        }
    }

    return 0;

    /*     End of SLATME */

} /* slatme_ */
Example #5
0
/* Complex */ VOID clarnd_(complex * ret_val, integer *idist, integer *iseed)
{
    /* System generated locals */
    doublereal d__1, d__2;
    complex q__1, q__2, q__3;

    /* Builtin functions */
    double log(doublereal), sqrt(doublereal);
    void c_exp(complex *, complex *);

    /* Local variables */
    static real t1, t2;
    extern doublereal slaran_(integer *);


/*  -- 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
    =======

    CLARND returns a random complex number from a uniform or normal
    distribution.

    Arguments
    =========

    IDIST   (input) INTEGER
            Specifies the distribution of the random numbers:
            = 1:  real and imaginary parts each uniform (0,1)
            = 2:  real and imaginary parts each uniform (-1,1)
            = 3:  real and imaginary parts each normal (0,1)
            = 4:  uniformly distributed on the disc abs(z) <= 1
            = 5:  uniformly distributed on the circle abs(z) = 1

    ISEED   (input/output) INTEGER array, dimension (4)
            On entry, the seed of the random number generator; the array

            elements must be between 0 and 4095, and ISEED(4) must be
            odd.
            On exit, the seed is updated.

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

    This routine calls the auxiliary routine SLARAN to generate a random

    real number from a uniform (0,1) distribution. The Box-Muller method

    is used to transform numbers from a uniform to a normal distribution.


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



       Generate a pair of real random numbers from a uniform (0,1)
       distribution

       Parameter adjustments */
    --iseed;

    /* Function Body */
    t1 = slaran_(&iseed[1]);
    t2 = slaran_(&iseed[1]);

    if (*idist == 1) {

/*        real and imaginary parts each uniform (0,1) */

        q__1.r = t1, q__1.i = t2;
         ret_val->r = q__1.r,  ret_val->i = q__1.i;
    } else if (*idist == 2) {

/*        real and imaginary parts each uniform (-1,1) */

        d__1 = t1 * 2.f - 1.f;
        d__2 = t2 * 2.f - 1.f;
        q__1.r = d__1, q__1.i = d__2;
         ret_val->r = q__1.r,  ret_val->i = q__1.i;
    } else if (*idist == 3) {

/*        real and imaginary parts each normal (0,1) */

        d__1 = sqrt(log(t1) * -2.f);
        d__2 = t2 * 6.2831853071795864769252867663f;
        q__3.r = 0.f, q__3.i = d__2;
        c_exp(&q__2, &q__3);
        q__1.r = d__1 * q__2.r, q__1.i = d__1 * q__2.i;
         ret_val->r = q__1.r,  ret_val->i = q__1.i;
    } else if (*idist == 4) {

/*        uniform distribution on the unit disc abs(z) <= 1 */

        d__1 = sqrt(t1);
        d__2 = t2 * 6.2831853071795864769252867663f;
        q__3.r = 0.f, q__3.i = d__2;
        c_exp(&q__2, &q__3);
        q__1.r = d__1 * q__2.r, q__1.i = d__1 * q__2.i;
         ret_val->r = q__1.r,  ret_val->i = q__1.i;
    } else if (*idist == 5) {

/*        uniform distribution on the unit circle abs(z) = 1 */

        d__1 = t2 * 6.2831853071795864769252867663f;
        q__2.r = 0.f, q__2.i = d__1;
        c_exp(&q__1, &q__2);
         ret_val->r = q__1.r,  ret_val->i = q__1.i;
    }
    return ;

/*     End of CLARND */

} /* clarnd_ */
Example #6
0
/* Subroutine */ int slatm1_(integer *mode, real *cond, integer *irsign, 
	integer *idist, integer *iseed, real *d__, integer *n, integer *info)
{
    /* System generated locals */
    integer i__1, i__2;
    doublereal d__1, d__2;

    /* Builtin functions */
    double pow_dd(doublereal *, doublereal *), pow_ri(real *, integer *), log(
	    doublereal), exp(doublereal);

    /* Local variables */
    integer i__;
    real temp, alpha;
    extern /* Subroutine */ int xerbla_(char *, integer *);
    extern doublereal slaran_(integer *);
    extern /* Subroutine */ int slarnv_(integer *, integer *, integer *, real 
	    *);


/*  -- LAPACK auxiliary test routine (version 3.1) -- */
/*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
/*     November 2006 */

/*     .. Scalar Arguments .. */
/*     .. */
/*     .. Array Arguments .. */
/*     .. */

/*  Purpose */
/*  ======= */

/*     SLATM1 computes the entries of D(1..N) as specified by */
/*     MODE, COND and IRSIGN. IDIST and ISEED determine the generation */
/*     of random numbers. SLATM1 is called by SLATMR to generate */
/*     random test matrices for LAPACK programs. */

/*  Arguments */
/*  ========= */

/*  MODE   - INTEGER */
/*           On entry describes how D is to be computed: */
/*           MODE = 0 means do not change D. */
/*           MODE = 1 sets D(1)=1 and D(2:N)=1.0/COND */
/*           MODE = 2 sets D(1:N-1)=1 and D(N)=1.0/COND */
/*           MODE = 3 sets D(I)=COND**(-(I-1)/(N-1)) */
/*           MODE = 4 sets D(i)=1 - (i-1)/(N-1)*(1 - 1/COND) */
/*           MODE = 5 sets D to random numbers in the range */
/*                    ( 1/COND , 1 ) such that their logarithms */
/*                    are uniformly distributed. */
/*           MODE = 6 set D to random numbers from same distribution */
/*                    as the rest of the matrix. */
/*           MODE < 0 has the same meaning as ABS(MODE), except that */
/*              the order of the elements of D is reversed. */
/*           Thus if MODE is positive, D has entries ranging from */
/*              1 to 1/COND, if negative, from 1/COND to 1, */
/*           Not modified. */

/*  COND   - REAL */
/*           On entry, used as described under MODE above. */
/*           If used, it must be >= 1. Not modified. */

/*  IRSIGN - INTEGER */
/*           On entry, if MODE neither -6, 0 nor 6, determines sign of */
/*           entries of D */
/*           0 => leave entries of D unchanged */
/*           1 => multiply each entry of D by 1 or -1 with probability .5 */

/*  IDIST  - CHARACTER*1 */
/*           On entry, IDIST specifies the type of distribution to be */
/*           used to generate a random matrix . */
/*           1 => UNIFORM( 0, 1 ) */
/*           2 => UNIFORM( -1, 1 ) */
/*           3 => NORMAL( 0, 1 ) */
/*           Not modified. */

/*  ISEED  - INTEGER array, dimension ( 4 ) */
/*           On entry ISEED specifies the seed of the random number */
/*           generator. The random number generator uses a */
/*           linear congruential sequence limited to small */
/*           integers, and so should produce machine independent */
/*           random numbers. The values of ISEED are changed on */
/*           exit, and can be used in the next call to SLATM1 */
/*           to continue the same random number sequence. */
/*           Changed on exit. */

/*  D      - REAL array, dimension ( MIN( M , N ) ) */
/*           Array to be computed according to MODE, COND and IRSIGN. */
/*           May be changed on exit if MODE is nonzero. */

/*  N      - INTEGER */
/*           Number of entries of D. Not modified. */

/*  INFO   - INTEGER */
/*            0  => normal termination */
/*           -1  => if MODE not in range -6 to 6 */
/*           -2  => if MODE neither -6, 0 nor 6, and */
/*                  IRSIGN neither 0 nor 1 */
/*           -3  => if MODE neither -6, 0 nor 6 and COND less than 1 */
/*           -4  => if MODE equals 6 or -6 and IDIST not in range 1 to 3 */
/*           -7  => if N negative */

/*  ===================================================================== */

/*     .. Parameters .. */
/*     .. */
/*     .. Local Scalars .. */
/*     .. */
/*     .. External Functions .. */
/*     .. */
/*     .. External Subroutines .. */
/*     .. */
/*     .. Intrinsic Functions .. */
/*     .. */
/*     .. Executable Statements .. */

/*     Decode and Test the input parameters. Initialize flags & seed. */

    /* Parameter adjustments */
    --d__;
    --iseed;

    /* Function Body */
    *info = 0;

/*     Quick return if possible */

    if (*n == 0) {
	return 0;
    }

/*     Set INFO if an error */

    if (*mode < -6 || *mode > 6) {
	*info = -1;
    } else if (*mode != -6 && *mode != 0 && *mode != 6 && (*irsign != 0 && *
	    irsign != 1)) {
	*info = -2;
    } else if (*mode != -6 && *mode != 0 && *mode != 6 && *cond < 1.f) {
	*info = -3;
    } else if ((*mode == 6 || *mode == -6) && (*idist < 1 || *idist > 3)) {
	*info = -4;
    } else if (*n < 0) {
	*info = -7;
    }

    if (*info != 0) {
	i__1 = -(*info);
	xerbla_("SLATM1", &i__1);
	return 0;
    }

/*     Compute D according to COND and MODE */

    if (*mode != 0) {
	switch (abs(*mode)) {
	    case 1:  goto L10;
	    case 2:  goto L30;
	    case 3:  goto L50;
	    case 4:  goto L70;
	    case 5:  goto L90;
	    case 6:  goto L110;
	}

/*        One large D value: */

L10:
	i__1 = *n;
	for (i__ = 1; i__ <= i__1; ++i__) {
	    d__[i__] = 1.f / *cond;
/* L20: */
	}
	d__[1] = 1.f;
	goto L120;

/*        One small D value: */

L30:
	i__1 = *n;
	for (i__ = 1; i__ <= i__1; ++i__) {
	    d__[i__] = 1.f;
/* L40: */
	}
	d__[*n] = 1.f / *cond;
	goto L120;

/*        Exponentially distributed D values: */

L50:
	d__[1] = 1.f;
	if (*n > 1) {
	    d__1 = (doublereal) (*cond);
	    d__2 = (doublereal) (-1.f / (real) (*n - 1));
	    alpha = pow_dd(&d__1, &d__2);
	    i__1 = *n;
	    for (i__ = 2; i__ <= i__1; ++i__) {
		i__2 = i__ - 1;
		d__[i__] = pow_ri(&alpha, &i__2);
/* L60: */
	    }
	}
	goto L120;

/*        Arithmetically distributed D values: */

L70:
	d__[1] = 1.f;
	if (*n > 1) {
	    temp = 1.f / *cond;
	    alpha = (1.f - temp) / (real) (*n - 1);
	    i__1 = *n;
	    for (i__ = 2; i__ <= i__1; ++i__) {
		d__[i__] = (real) (*n - i__) * alpha + temp;
/* L80: */
	    }
	}
	goto L120;

/*        Randomly distributed D values on ( 1/COND , 1): */

L90:
	alpha = log(1.f / *cond);
	i__1 = *n;
	for (i__ = 1; i__ <= i__1; ++i__) {
	    d__[i__] = exp(alpha * slaran_(&iseed[1]));
/* L100: */
	}
	goto L120;

/*        Randomly distributed D values from IDIST */

L110:
	slarnv_(idist, &iseed[1], n, &d__[1]);

L120:

/*        If MODE neither -6 nor 0 nor 6, and IRSIGN = 1, assign */
/*        random signs to D */

	if (*mode != -6 && *mode != 0 && *mode != 6 && *irsign == 1) {
	    i__1 = *n;
	    for (i__ = 1; i__ <= i__1; ++i__) {
		temp = slaran_(&iseed[1]);
		if (temp > .5f) {
		    d__[i__] = -d__[i__];
		}
/* L130: */
	    }
	}

/*        Reverse if MODE < 0 */

	if (*mode < 0) {
	    i__1 = *n / 2;
	    for (i__ = 1; i__ <= i__1; ++i__) {
		temp = d__[i__];
		d__[i__] = d__[*n + 1 - i__];
		d__[*n + 1 - i__] = temp;
/* L140: */
	    }
	}

    }

    return 0;

/*     End of SLATM1 */

} /* slatm1_ */
Example #7
0
doublereal slatm2_(integer *m, integer *n, integer *i__, integer *j, integer *
	kl, integer *ku, integer *idist, integer *iseed, real *d__, integer *
	igrade, real *dl, real *dr, integer *ipvtng, integer *iwork, real *
	sparse)
{
    /* System generated locals */
    real ret_val;

    /* Local variables */
    static integer isub, jsub;
    static real temp;
    extern doublereal slaran_(integer *), slarnd_(integer *, integer *);


/*  -- LAPACK auxiliary test routine (version 3.0) --   
       Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,   
       Courant Institute, Argonne National Lab, and Rice University   
       February 29, 1992   





    Purpose   
    =======   

       SLATM2 returns the (I,J) entry of a random matrix of dimension   
       (M, N) described by the other paramters. It is called by the   
       SLATMR routine in order to build random test matrices. No error   
       checking on parameters is done, because this routine is called in   
       a tight loop by SLATMR which has already checked the parameters.   

       Use of SLATM2 differs from SLATM3 in the order in which the random   
       number generator is called to fill in random matrix entries.   
       With SLATM2, the generator is called to fill in the pivoted matrix   
       columnwise. With SLATM3, the generator is called to fill in the   
       matrix columnwise, after which it is pivoted. Thus, SLATM3 can   
       be used to construct random matrices which differ only in their   
       order of rows and/or columns. SLATM2 is used to construct band   
       matrices while avoiding calling the random number generator for   
       entries outside the band (and therefore generating random numbers   

       The matrix whose (I,J) entry is returned is constructed as   
       follows (this routine only computes one entry):   

         If I is outside (1..M) or J is outside (1..N), return zero   
            (this is convenient for generating matrices in band format).   

         Generate a matrix A with random entries of distribution IDIST.   

         Set the diagonal to D.   

         Grade the matrix, if desired, from the left (by DL) and/or   
            from the right (by DR or DL) as specified by IGRADE.   

         Permute, if desired, the rows and/or columns as specified by   
            IPVTNG and IWORK.   

         Band the matrix to have lower bandwidth KL and upper   
            bandwidth KU.   

         Set random entries to zero as specified by SPARSE.   

    Arguments   
    =========   

    M      - INTEGER   
             Number of rows of matrix. Not modified.   

    N      - INTEGER   
             Number of columns of matrix. Not modified.   

    I      - INTEGER   
             Row of entry to be returned. Not modified.   

    J      - INTEGER   
             Column of entry to be returned. Not modified.   

    KL     - INTEGER   
             Lower bandwidth. Not modified.   

    KU     - INTEGER   
             Upper bandwidth. Not modified.   

    IDIST  - INTEGER   
             On entry, IDIST specifies the type of distribution to be   
             used to generate a random matrix .   
             1 => UNIFORM( 0, 1 )   
             2 => UNIFORM( -1, 1 )   
             3 => NORMAL( 0, 1 )   
             Not modified.   

    ISEED  - INTEGER array of dimension ( 4 )   
             Seed for random number generator.   
             Changed on exit.   

    D      - REAL array of dimension ( MIN( I , J ) )   
             Diagonal entries of matrix. Not modified.   

    IGRADE - INTEGER   
             Specifies grading of matrix as follows:   
             0  => no grading   
             1  => matrix premultiplied by diag( DL )   
             2  => matrix postmultiplied by diag( DR )   
             3  => matrix premultiplied by diag( DL ) and   
                           postmultiplied by diag( DR )   
             4  => matrix premultiplied by diag( DL ) and   
                           postmultiplied by inv( diag( DL ) )   
             5  => matrix premultiplied by diag( DL ) and   
                           postmultiplied by diag( DL )   
             Not modified.   

    DL     - REAL array ( I or J, as appropriate )   
             Left scale factors for grading matrix.  Not modified.   

    DR     - REAL array ( I or J, as appropriate )   
             Right scale factors for grading matrix.  Not modified.   

    IPVTNG - INTEGER   
             On entry specifies pivoting permutations as follows:   
             0 => none.   
             1 => row pivoting.   
             2 => column pivoting.   
             3 => full pivoting, i.e., on both sides.   
             Not modified.   

    IWORK  - INTEGER array ( I or J, as appropriate )   
             This array specifies the permutation used. The   
             row (or column) in position K was originally in   
             position IWORK( K ).   
             This differs from IWORK for SLATM3. Not modified.   

    SPARSE - REAL    between 0. and 1.   
             On entry specifies the sparsity of the matrix   
             if sparse matix is to be generated.   
             SPARSE should lie between 0 and 1.   
             A uniform ( 0, 1 ) random number x is generated and   
             compared to SPARSE; if x is larger the matrix entry   
             is unchanged and if x is smaller the entry is set   
             to zero. Thus on the average a fraction SPARSE of the   
             entries will be set to zero.   
             Not modified.   

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







   -----------------------------------------------------------------------   



       Check for I and J in range   

       Parameter adjustments */
    --iwork;
    --dr;
    --dl;
    --d__;
    --iseed;

    /* Function Body */
    if (*i__ < 1 || *i__ > *m || *j < 1 || *j > *n) {
	ret_val = 0.f;
	return ret_val;
    }

/*     Check for banding */

    if (*j > *i__ + *ku || *j < *i__ - *kl) {
	ret_val = 0.f;
	return ret_val;
    }

/*     Check for sparsity */

    if (*sparse > 0.f) {
	if (slaran_(&iseed[1]) < *sparse) {
	    ret_val = 0.f;
	    return ret_val;
	}
    }

/*     Compute subscripts depending on IPVTNG */

    if (*ipvtng == 0) {
	isub = *i__;
	jsub = *j;
    } else if (*ipvtng == 1) {
	isub = iwork[*i__];
	jsub = *j;
    } else if (*ipvtng == 2) {
	isub = *i__;
	jsub = iwork[*j];
    } else if (*ipvtng == 3) {
	isub = iwork[*i__];
	jsub = iwork[*j];
    }

/*     Compute entry and grade it according to IGRADE */

    if (isub == jsub) {
	temp = d__[isub];
    } else {
	temp = slarnd_(idist, &iseed[1]);
    }
    if (*igrade == 1) {
	temp *= dl[isub];
    } else if (*igrade == 2) {
	temp *= dr[jsub];
    } else if (*igrade == 3) {
	temp = temp * dl[isub] * dr[jsub];
    } else if (*igrade == 4 && isub != jsub) {
	temp = temp * dl[isub] / dl[jsub];
    } else if (*igrade == 5) {
	temp = temp * dl[isub] * dl[jsub];
    }
    ret_val = temp;
    return ret_val;

/*     End of SLATM2 */

} /* slatm2_ */
Example #8
0
/* Subroutine */ int clatm4_(integer *itype, integer *n, integer *nz1, 
	integer *nz2, logical *rsign, real *amagn, real *rcond, real *triang, 
	integer *idist, integer *iseed, complex *a, integer *lda)
{
    /* System generated locals */
    integer a_dim1, a_offset, i__1, i__2, i__3, i__4;
    real r__1;
    doublereal d__1, d__2;
    complex q__1, q__2;

    /* Builtin functions */
    double pow_dd(doublereal *, doublereal *), pow_ri(real *, integer *), log(
	    doublereal), exp(doublereal), c_abs(complex *);

    /* Local variables */
    static integer kbeg, isdb, kend, isde, klen, i__, k;
    static real alpha;
    static complex ctemp;
    static integer jc, jd, jr;
    extern /* Complex */ VOID clarnd_(complex *, integer *, integer *);
    extern /* Subroutine */ int claset_(char *, integer *, integer *, complex 
	    *, complex *, complex *, integer *);
    extern doublereal slaran_(integer *);


#define a_subscr(a_1,a_2) (a_2)*a_dim1 + a_1
#define a_ref(a_1,a_2) a[a_subscr(a_1,a_2)]


/*  -- LAPACK auxiliary test routine (version 3.0) --   
       Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,   
       Courant Institute, Argonne National Lab, and Rice University   
       September 30, 1994   


    Purpose   
    =======   

    CLATM4 generates basic square matrices, which may later be   
    multiplied by others in order to produce test matrices.  It is   
    intended mainly to be used to test the generalized eigenvalue   
    routines.   

    It first generates the diagonal and (possibly) subdiagonal,   
    according to the value of ITYPE, NZ1, NZ2, RSIGN, AMAGN, and RCOND.   
    It then fills in the upper triangle with random numbers, if TRIANG is   
    non-zero.   

    Arguments   
    =========   

    ITYPE   (input) INTEGER   
            The "type" of matrix on the diagonal and sub-diagonal.   
            If ITYPE < 0, then type abs(ITYPE) is generated and then   
               swapped end for end (A(I,J) := A'(N-J,N-I).)  See also   
               the description of AMAGN and RSIGN.   

            Special types:   
            = 0:  the zero matrix.   
            = 1:  the identity.   
            = 2:  a transposed Jordan block.   
            = 3:  If N is odd, then a k+1 x k+1 transposed Jordan block   
                  followed by a k x k identity block, where k=(N-1)/2.   
                  If N is even, then k=(N-2)/2, and a zero diagonal entry   
                  is tacked onto the end.   

            Diagonal types.  The diagonal consists of NZ1 zeros, then   
               k=N-NZ1-NZ2 nonzeros.  The subdiagonal is zero.  ITYPE   
               specifies the nonzero diagonal entries as follows:   
            = 4:  1, ..., k   
            = 5:  1, RCOND, ..., RCOND   
            = 6:  1, ..., 1, RCOND   
            = 7:  1, a, a^2, ..., a^(k-1)=RCOND   
            = 8:  1, 1-d, 1-2*d, ..., 1-(k-1)*d=RCOND   
            = 9:  random numbers chosen from (RCOND,1)   
            = 10: random numbers with distribution IDIST (see CLARND.)   

    N       (input) INTEGER   
            The order of the matrix.   

    NZ1     (input) INTEGER   
            If abs(ITYPE) > 3, then the first NZ1 diagonal entries will   
            be zero.   

    NZ2     (input) INTEGER   
            If abs(ITYPE) > 3, then the last NZ2 diagonal entries will   
            be zero.   

    RSIGN   (input) LOGICAL   
            = .TRUE.:  The diagonal and subdiagonal entries will be   
                       multiplied by random numbers of magnitude 1.   
            = .FALSE.: The diagonal and subdiagonal entries will be   
                       left as they are (usually non-negative real.)   

    AMAGN   (input) REAL   
            The diagonal and subdiagonal entries will be multiplied by   
            AMAGN.   

    RCOND   (input) REAL   
            If abs(ITYPE) > 4, then the smallest diagonal entry will be   
            RCOND.  RCOND must be between 0 and 1.   

    TRIANG  (input) REAL   
            The entries above the diagonal will be random numbers with   
            magnitude bounded by TRIANG (i.e., random numbers multiplied   
            by TRIANG.)   

    IDIST   (input) INTEGER   
            On entry, DIST specifies the type of distribution to be used   
            to generate a random matrix .   
            = 1: real and imaginary parts each UNIFORM( 0, 1 )   
            = 2: real and imaginary parts each UNIFORM( -1, 1 )   
            = 3: real and imaginary parts each NORMAL( 0, 1 )   
            = 4: complex number uniform in DISK( 0, 1 )   

    ISEED   (input/output) INTEGER array, dimension (4)   
            On entry ISEED specifies the seed of the random number   
            generator.  The values of ISEED are changed on exit, and can   
            be used in the next call to CLATM4 to continue the same   
            random number sequence.   
            Note: ISEED(4) should be odd, for the random number generator   
            used at present.   

    A       (output) COMPLEX array, dimension (LDA, N)   
            Array to be computed.   

    LDA     (input) INTEGER   
            Leading dimension of A.  Must be at least 1 and at least N.   

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


       Parameter adjustments */
    --iseed;
    a_dim1 = *lda;
    a_offset = 1 + a_dim1 * 1;
    a -= a_offset;

    /* Function Body */
    if (*n <= 0) {
	return 0;
    }
    claset_("Full", n, n, &c_b1, &c_b1, &a[a_offset], lda);

/*     Insure a correct ISEED */

    if (iseed[4] % 2 != 1) {
	++iseed[4];
    }

/*     Compute diagonal and subdiagonal according to ITYPE, NZ1, NZ2,   
       and RCOND */

    if (*itype != 0) {
	if (abs(*itype) >= 4) {
/* Computing MAX   
   Computing MIN */
	    i__3 = *n, i__4 = *nz1 + 1;
	    i__1 = 1, i__2 = min(i__3,i__4);
	    kbeg = max(i__1,i__2);
/* Computing MAX   
   Computing MIN */
	    i__3 = *n, i__4 = *n - *nz2;
	    i__1 = kbeg, i__2 = min(i__3,i__4);
	    kend = max(i__1,i__2);
	    klen = kend + 1 - kbeg;
	} else {
	    kbeg = 1;
	    kend = *n;
	    klen = *n;
	}
	isdb = 1;
	isde = 0;
	switch (abs(*itype)) {
	    case 1:  goto L10;
	    case 2:  goto L30;
	    case 3:  goto L50;
	    case 4:  goto L80;
	    case 5:  goto L100;
	    case 6:  goto L120;
	    case 7:  goto L140;
	    case 8:  goto L160;
	    case 9:  goto L180;
	    case 10:  goto L200;
	}

/*        |ITYPE| = 1: Identity */

L10:
	i__1 = *n;
	for (jd = 1; jd <= i__1; ++jd) {
	    i__2 = a_subscr(jd, jd);
	    a[i__2].r = 1.f, a[i__2].i = 0.f;
/* L20: */
	}
	goto L220;

/*        |ITYPE| = 2: Transposed Jordan block */

L30:
	i__1 = *n - 1;
	for (jd = 1; jd <= i__1; ++jd) {
	    i__2 = a_subscr(jd + 1, jd);
	    a[i__2].r = 1.f, a[i__2].i = 0.f;
/* L40: */
	}
	isdb = 1;
	isde = *n - 1;
	goto L220;

/*        |ITYPE| = 3: Transposed Jordan block, followed by the identity. */

L50:
	k = (*n - 1) / 2;
	i__1 = k;
	for (jd = 1; jd <= i__1; ++jd) {
	    i__2 = a_subscr(jd + 1, jd);
	    a[i__2].r = 1.f, a[i__2].i = 0.f;
/* L60: */
	}
	isdb = 1;
	isde = k;
	i__1 = (k << 1) + 1;
	for (jd = k + 2; jd <= i__1; ++jd) {
	    i__2 = a_subscr(jd, jd);
	    a[i__2].r = 1.f, a[i__2].i = 0.f;
/* L70: */
	}
	goto L220;

/*        |ITYPE| = 4: 1,...,k */

L80:
	i__1 = kend;
	for (jd = kbeg; jd <= i__1; ++jd) {
	    i__2 = a_subscr(jd, jd);
	    i__3 = jd - *nz1;
	    q__1.r = (real) i__3, q__1.i = 0.f;
	    a[i__2].r = q__1.r, a[i__2].i = q__1.i;
/* L90: */
	}
	goto L220;

/*        |ITYPE| = 5: One large D value: */

L100:
	i__1 = kend;
	for (jd = kbeg + 1; jd <= i__1; ++jd) {
	    i__2 = a_subscr(jd, jd);
	    q__1.r = *rcond, q__1.i = 0.f;
	    a[i__2].r = q__1.r, a[i__2].i = q__1.i;
/* L110: */
	}
	i__1 = a_subscr(kbeg, kbeg);
	a[i__1].r = 1.f, a[i__1].i = 0.f;
	goto L220;

/*        |ITYPE| = 6: One small D value: */

L120:
	i__1 = kend - 1;
	for (jd = kbeg; jd <= i__1; ++jd) {
	    i__2 = a_subscr(jd, jd);
	    a[i__2].r = 1.f, a[i__2].i = 0.f;
/* L130: */
	}
	i__1 = a_subscr(kend, kend);
	q__1.r = *rcond, q__1.i = 0.f;
	a[i__1].r = q__1.r, a[i__1].i = q__1.i;
	goto L220;

/*        |ITYPE| = 7: Exponentially distributed D values: */

L140:
	i__1 = a_subscr(kbeg, kbeg);
	a[i__1].r = 1.f, a[i__1].i = 0.f;
	if (klen > 1) {
	    d__1 = (doublereal) (*rcond);
	    d__2 = (doublereal) (1.f / (real) (klen - 1));
	    alpha = pow_dd(&d__1, &d__2);
	    i__1 = klen;
	    for (i__ = 2; i__ <= i__1; ++i__) {
		i__2 = a_subscr(*nz1 + i__, *nz1 + i__);
		i__3 = i__ - 1;
		r__1 = pow_ri(&alpha, &i__3);
		q__1.r = r__1, q__1.i = 0.f;
		a[i__2].r = q__1.r, a[i__2].i = q__1.i;
/* L150: */
	    }
	}
	goto L220;

/*        |ITYPE| = 8: Arithmetically distributed D values: */

L160:
	i__1 = a_subscr(kbeg, kbeg);
	a[i__1].r = 1.f, a[i__1].i = 0.f;
	if (klen > 1) {
	    alpha = (1.f - *rcond) / (real) (klen - 1);
	    i__1 = klen;
	    for (i__ = 2; i__ <= i__1; ++i__) {
		i__2 = a_subscr(*nz1 + i__, *nz1 + i__);
		r__1 = (real) (klen - i__) * alpha + *rcond;
		q__1.r = r__1, q__1.i = 0.f;
		a[i__2].r = q__1.r, a[i__2].i = q__1.i;
/* L170: */
	    }
	}
	goto L220;

/*        |ITYPE| = 9: Randomly distributed D values on ( RCOND, 1): */

L180:
	alpha = log(*rcond);
	i__1 = kend;
	for (jd = kbeg; jd <= i__1; ++jd) {
	    i__2 = a_subscr(jd, jd);
	    r__1 = exp(alpha * slaran_(&iseed[1]));
	    a[i__2].r = r__1, a[i__2].i = 0.f;
/* L190: */
	}
	goto L220;

/*        |ITYPE| = 10: Randomly distributed D values from DIST */

L200:
	i__1 = kend;
	for (jd = kbeg; jd <= i__1; ++jd) {
	    i__2 = a_subscr(jd, jd);
	    clarnd_(&q__1, idist, &iseed[1]);
	    a[i__2].r = q__1.r, a[i__2].i = q__1.i;
/* L210: */
	}

L220:

/*        Scale by AMAGN */

	i__1 = kend;
	for (jd = kbeg; jd <= i__1; ++jd) {
	    i__2 = a_subscr(jd, jd);
	    i__3 = a_subscr(jd, jd);
	    r__1 = *amagn * a[i__3].r;
	    a[i__2].r = r__1, a[i__2].i = 0.f;
/* L230: */
	}
	i__1 = isde;
	for (jd = isdb; jd <= i__1; ++jd) {
	    i__2 = a_subscr(jd + 1, jd);
	    i__3 = a_subscr(jd + 1, jd);
	    r__1 = *amagn * a[i__3].r;
	    a[i__2].r = r__1, a[i__2].i = 0.f;
/* L240: */
	}

/*        If RSIGN = .TRUE., assign random signs to diagonal and   
          subdiagonal */

	if (*rsign) {
	    i__1 = kend;
	    for (jd = kbeg; jd <= i__1; ++jd) {
		i__2 = a_subscr(jd, jd);
		if (a[i__2].r != 0.f) {
		    clarnd_(&q__1, &c__3, &iseed[1]);
		    ctemp.r = q__1.r, ctemp.i = q__1.i;
		    r__1 = c_abs(&ctemp);
		    q__1.r = ctemp.r / r__1, q__1.i = ctemp.i / r__1;
		    ctemp.r = q__1.r, ctemp.i = q__1.i;
		    i__2 = a_subscr(jd, jd);
		    i__3 = a_subscr(jd, jd);
		    r__1 = a[i__3].r;
		    q__1.r = r__1 * ctemp.r, q__1.i = r__1 * ctemp.i;
		    a[i__2].r = q__1.r, a[i__2].i = q__1.i;
		}
/* L250: */
	    }
	    i__1 = isde;
	    for (jd = isdb; jd <= i__1; ++jd) {
		i__2 = a_subscr(jd + 1, jd);
		if (a[i__2].r != 0.f) {
		    clarnd_(&q__1, &c__3, &iseed[1]);
		    ctemp.r = q__1.r, ctemp.i = q__1.i;
		    r__1 = c_abs(&ctemp);
		    q__1.r = ctemp.r / r__1, q__1.i = ctemp.i / r__1;
		    ctemp.r = q__1.r, ctemp.i = q__1.i;
		    i__2 = a_subscr(jd + 1, jd);
		    i__3 = a_subscr(jd + 1, jd);
		    r__1 = a[i__3].r;
		    q__1.r = r__1 * ctemp.r, q__1.i = r__1 * ctemp.i;
		    a[i__2].r = q__1.r, a[i__2].i = q__1.i;
		}
/* L260: */
	    }
	}

/*        Reverse if ITYPE < 0 */

	if (*itype < 0) {
	    i__1 = (kbeg + kend - 1) / 2;
	    for (jd = kbeg; jd <= i__1; ++jd) {
		i__2 = a_subscr(jd, jd);
		ctemp.r = a[i__2].r, ctemp.i = a[i__2].i;
		i__2 = a_subscr(jd, jd);
		i__3 = a_subscr(kbeg + kend - jd, kbeg + kend - jd);
		a[i__2].r = a[i__3].r, a[i__2].i = a[i__3].i;
		i__2 = a_subscr(kbeg + kend - jd, kbeg + kend - jd);
		a[i__2].r = ctemp.r, a[i__2].i = ctemp.i;
/* L270: */
	    }
	    i__1 = (*n - 1) / 2;
	    for (jd = 1; jd <= i__1; ++jd) {
		i__2 = a_subscr(jd + 1, jd);
		ctemp.r = a[i__2].r, ctemp.i = a[i__2].i;
		i__2 = a_subscr(jd + 1, jd);
		i__3 = a_subscr(*n + 1 - jd, *n - jd);
		a[i__2].r = a[i__3].r, a[i__2].i = a[i__3].i;
		i__2 = a_subscr(*n + 1 - jd, *n - jd);
		a[i__2].r = ctemp.r, a[i__2].i = ctemp.i;
/* L280: */
	    }
	}

    }

/*     Fill in upper triangle */

    if (*triang != 0.f) {
	i__1 = *n;
	for (jc = 2; jc <= i__1; ++jc) {
	    i__2 = jc - 1;
	    for (jr = 1; jr <= i__2; ++jr) {
		i__3 = a_subscr(jr, jc);
		clarnd_(&q__2, idist, &iseed[1]);
		q__1.r = *triang * q__2.r, q__1.i = *triang * q__2.i;
		a[i__3].r = q__1.r, a[i__3].i = q__1.i;
/* L290: */
	    }
/* L300: */
	}
    }

    return 0;

/*     End of CLATM4 */

} /* clatm4_ */
Example #9
0
/* Complex */ VOID clatm3_(complex * ret_val, integer *m, integer *n, integer 
	*i, integer *j, integer *isub, integer *jsub, integer *kl, integer *
	ku, integer *idist, integer *iseed, complex *d, integer *igrade, 
	complex *dl, complex *dr, integer *ipvtng, integer *iwork, real *
	sparse)
{
    /* System generated locals */
    integer i__1, i__2;
    complex q__1, q__2, q__3;

    /* Builtin functions */
    void c_div(complex *, complex *, complex *), r_cnjg(complex *, complex *);

    /* Local variables */
    static complex ctemp;
    extern /* Complex */ VOID clarnd_(complex *, integer *, integer *);
    extern doublereal slaran_(integer *);


/*  -- LAPACK auxiliary test 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   
    =======   

       CLATM3 returns the (ISUB,JSUB) entry of a random matrix of   
       dimension (M, N) described by the other paramters. (ISUB,JSUB)   
       is the final position of the (I,J) entry after pivoting   
       according to IPVTNG and IWORK. CLATM3 is called by the   
       CLATMR routine in order to build random test matrices. No error   
       checking on parameters is done, because this routine is called in 
  
       a tight loop by CLATMR which has already checked the parameters.   

       Use of CLATM3 differs from CLATM2 in the order in which the random 
  
       number generator is called to fill in random matrix entries.   
       With CLATM2, the generator is called to fill in the pivoted matrix 
  
       columnwise. With CLATM3, the generator is called to fill in the   
       matrix columnwise, after which it is pivoted. Thus, CLATM3 can   
       be used to construct random matrices which differ only in their   
       order of rows and/or columns. CLATM2 is used to construct band   
       matrices while avoiding calling the random number generator for   
       entries outside the band (and therefore generating random numbers 
  
       in different orders for different pivot orders).   

       The matrix whose (ISUB,JSUB) entry is returned is constructed as   
       follows (this routine only computes one entry):   

         If ISUB is outside (1..M) or JSUB is outside (1..N), return zero 
  
            (this is convenient for generating matrices in band format). 
  

         Generate a matrix A with random entries of distribution IDIST.   

         Set the diagonal to D.   

         Grade the matrix, if desired, from the left (by DL) and/or   
            from the right (by DR or DL) as specified by IGRADE.   

         Permute, if desired, the rows and/or columns as specified by   
            IPVTNG and IWORK.   

         Band the matrix to have lower bandwidth KL and upper   
            bandwidth KU.   

         Set random entries to zero as specified by SPARSE.   

    Arguments   
    =========   

    M      - INTEGER   
             Number of rows of matrix. Not modified.   

    N      - INTEGER   
             Number of columns of matrix. Not modified.   

    I      - INTEGER   
             Row of unpivoted entry to be returned. Not modified.   

    J      - INTEGER   
             Column of unpivoted entry to be returned. Not modified.   

    ISUB   - INTEGER   
             Row of pivoted entry to be returned. Changed on exit.   

    JSUB   - INTEGER   
             Column of pivoted entry to be returned. Changed on exit.   

    KL     - INTEGER   
             Lower bandwidth. Not modified.   

    KU     - INTEGER   
             Upper bandwidth. Not modified.   

    IDIST  - INTEGER   
             On entry, IDIST specifies the type of distribution to be   
             used to generate a random matrix .   
             1 => real and imaginary parts each UNIFORM( 0, 1 )   
             2 => real and imaginary parts each UNIFORM( -1, 1 )   
             3 => real and imaginary parts each NORMAL( 0, 1 )   
             4 => complex number uniform in DISK( 0 , 1 )   
             Not modified.   

    ISEED  - INTEGER            array of dimension ( 4 )   
             Seed for random number generator.   
             Changed on exit.   

    D      - COMPLEX            array of dimension ( MIN( I , J ) )   
             Diagonal entries of matrix. Not modified.   

    IGRADE - INTEGER   
             Specifies grading of matrix as follows:   
             0  => no grading   
             1  => matrix premultiplied by diag( DL )   
             2  => matrix postmultiplied by diag( DR )   
             3  => matrix premultiplied by diag( DL ) and   
                           postmultiplied by diag( DR )   
             4  => matrix premultiplied by diag( DL ) and   
                           postmultiplied by inv( diag( DL ) )   
             5  => matrix premultiplied by diag( DL ) and   
                           postmultiplied by diag( CONJG(DL) )   
             6  => matrix premultiplied by diag( DL ) and   
                           postmultiplied by diag( DL )   
             Not modified.   

    DL     - COMPLEX            array ( I or J, as appropriate )   
             Left scale factors for grading matrix.  Not modified.   

    DR     - COMPLEX            array ( I or J, as appropriate )   
             Right scale factors for grading matrix.  Not modified.   

    IPVTNG - INTEGER   
             On entry specifies pivoting permutations as follows:   
             0 => none.   
             1 => row pivoting.   
             2 => column pivoting.   
             3 => full pivoting, i.e., on both sides.   
             Not modified.   

    IWORK  - INTEGER            array ( I or J, as appropriate )   
             This array specifies the permutation used. The   
             row (or column) originally in position K is in   
             position IWORK( K ) after pivoting.   
             This differs from IWORK for CLATM2. Not modified.   

    SPARSE - REAL               between 0. and 1.   
             On entry specifies the sparsity of the matrix   
             if sparse matix is to be generated.   
             SPARSE should lie between 0 and 1.   
             A uniform ( 0, 1 ) random number x is generated and   
             compared to SPARSE; if x is larger the matrix entry   
             is unchanged and if x is smaller the entry is set   
             to zero. Thus on the average a fraction SPARSE of the   
             entries will be set to zero.   
             Not modified.   

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









   -----------------------------------------------------------------------
   



       Check for I and J in range   

       Parameter adjustments */
    --iwork;
    --dr;
    --dl;
    --d;
    --iseed;

    /* Function Body */
    if (*i < 1 || *i > *m || *j < 1 || *j > *n) {
	*isub = *i;
	*jsub = *j;
	 ret_val->r = 0.f,  ret_val->i = 0.f;
	return ;
    }

/*     Compute subscripts depending on IPVTNG */

    if (*ipvtng == 0) {
	*isub = *i;
	*jsub = *j;
    } else if (*ipvtng == 1) {
	*isub = iwork[*i];
	*jsub = *j;
    } else if (*ipvtng == 2) {
	*isub = *i;
	*jsub = iwork[*j];
    } else if (*ipvtng == 3) {
	*isub = iwork[*i];
	*jsub = iwork[*j];
    }

/*     Check for banding */

    if (*jsub > *isub + *ku || *jsub < *isub - *kl) {
	 ret_val->r = 0.f,  ret_val->i = 0.f;
	return ;
    }

/*     Check for sparsity */

    if (*sparse > 0.f) {
	if (slaran_(&iseed[1]) < *sparse) {
	     ret_val->r = 0.f,  ret_val->i = 0.f;
	    return ;
	}
    }

/*     Compute entry and grade it according to IGRADE */

    if (*i == *j) {
	i__1 = *i;
	ctemp.r = d[i__1].r, ctemp.i = d[i__1].i;
    } else {
	clarnd_(&q__1, idist, &iseed[1]);
	ctemp.r = q__1.r, ctemp.i = q__1.i;
    }
    if (*igrade == 1) {
	i__1 = *i;
	q__1.r = ctemp.r * dl[i__1].r - ctemp.i * dl[i__1].i, q__1.i = 
		ctemp.r * dl[i__1].i + ctemp.i * dl[i__1].r;
	ctemp.r = q__1.r, ctemp.i = q__1.i;
    } else if (*igrade == 2) {
	i__1 = *j;
	q__1.r = ctemp.r * dr[i__1].r - ctemp.i * dr[i__1].i, q__1.i = 
		ctemp.r * dr[i__1].i + ctemp.i * dr[i__1].r;
	ctemp.r = q__1.r, ctemp.i = q__1.i;
    } else if (*igrade == 3) {
	i__1 = *i;
	q__2.r = ctemp.r * dl[i__1].r - ctemp.i * dl[i__1].i, q__2.i = 
		ctemp.r * dl[i__1].i + ctemp.i * dl[i__1].r;
	i__2 = *j;
	q__1.r = q__2.r * dr[i__2].r - q__2.i * dr[i__2].i, q__1.i = q__2.r * 
		dr[i__2].i + q__2.i * dr[i__2].r;
	ctemp.r = q__1.r, ctemp.i = q__1.i;
    } else if (*igrade == 4 && *i != *j) {
	i__1 = *i;
	q__2.r = ctemp.r * dl[i__1].r - ctemp.i * dl[i__1].i, q__2.i = 
		ctemp.r * dl[i__1].i + ctemp.i * dl[i__1].r;
	c_div(&q__1, &q__2, &dl[*j]);
	ctemp.r = q__1.r, ctemp.i = q__1.i;
    } else if (*igrade == 5) {
	i__1 = *i;
	q__2.r = ctemp.r * dl[i__1].r - ctemp.i * dl[i__1].i, q__2.i = 
		ctemp.r * dl[i__1].i + ctemp.i * dl[i__1].r;
	r_cnjg(&q__3, &dl[*j]);
	q__1.r = q__2.r * q__3.r - q__2.i * q__3.i, q__1.i = q__2.r * q__3.i 
		+ q__2.i * q__3.r;
	ctemp.r = q__1.r, ctemp.i = q__1.i;
    } else if (*igrade == 6) {
	i__1 = *i;
	q__2.r = ctemp.r * dl[i__1].r - ctemp.i * dl[i__1].i, q__2.i = 
		ctemp.r * dl[i__1].i + ctemp.i * dl[i__1].r;
	i__2 = *j;
	q__1.r = q__2.r * dl[i__2].r - q__2.i * dl[i__2].i, q__1.i = q__2.r * 
		dl[i__2].i + q__2.i * dl[i__2].r;
	ctemp.r = q__1.r, ctemp.i = q__1.i;
    }
     ret_val->r = ctemp.r,  ret_val->i = ctemp.i;
    return ;

/*     End of CLATM3 */

} /* clatm3_ */