LAPACK 3.3.1 Linear Algebra PACKage

# dlascl.f

Go to the documentation of this file.
```00001       SUBROUTINE DLASCL( TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO )
00002 *
00003 *  -- LAPACK auxiliary routine (version 3.3.0) --
00004 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
00005 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
00006 *     November 2010
00007 *
00008 *     .. Scalar Arguments ..
00009       CHARACTER          TYPE
00010       INTEGER            INFO, KL, KU, LDA, M, N
00011       DOUBLE PRECISION   CFROM, CTO
00012 *     ..
00013 *     .. Array Arguments ..
00014       DOUBLE PRECISION   A( LDA, * )
00015 *     ..
00016 *
00017 *  Purpose
00018 *  =======
00019 *
00020 *  DLASCL multiplies the M by N real matrix A by the real scalar
00021 *  CTO/CFROM.  This is done without over/underflow as long as the final
00022 *  result CTO*A(I,J)/CFROM does not over/underflow. TYPE specifies that
00023 *  A may be full, upper triangular, lower triangular, upper Hessenberg,
00024 *  or banded.
00025 *
00026 *  Arguments
00027 *  =========
00028 *
00029 *  TYPE    (input) CHARACTER*1
00030 *          TYPE indices the storage type of the input matrix.
00031 *          = 'G':  A is a full matrix.
00032 *          = 'L':  A is a lower triangular matrix.
00033 *          = 'U':  A is an upper triangular matrix.
00034 *          = 'H':  A is an upper Hessenberg matrix.
00035 *          = 'B':  A is a symmetric band matrix with lower bandwidth KL
00036 *                  and upper bandwidth KU and with the only the lower
00037 *                  half stored.
00038 *          = 'Q':  A is a symmetric band matrix with lower bandwidth KL
00039 *                  and upper bandwidth KU and with the only the upper
00040 *                  half stored.
00041 *          = 'Z':  A is a band matrix with lower bandwidth KL and upper
00042 *                  bandwidth KU. See DGBTRF for storage details.
00043 *
00044 *  KL      (input) INTEGER
00045 *          The lower bandwidth of A.  Referenced only if TYPE = 'B',
00046 *          'Q' or 'Z'.
00047 *
00048 *  KU      (input) INTEGER
00049 *          The upper bandwidth of A.  Referenced only if TYPE = 'B',
00050 *          'Q' or 'Z'.
00051 *
00052 *  CFROM   (input) DOUBLE PRECISION
00053 *  CTO     (input) DOUBLE PRECISION
00054 *          The matrix A is multiplied by CTO/CFROM. A(I,J) is computed
00055 *          without over/underflow if the final result CTO*A(I,J)/CFROM
00056 *          can be represented without over/underflow.  CFROM must be
00057 *          nonzero.
00058 *
00059 *  M       (input) INTEGER
00060 *          The number of rows of the matrix A.  M >= 0.
00061 *
00062 *  N       (input) INTEGER
00063 *          The number of columns of the matrix A.  N >= 0.
00064 *
00065 *  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
00066 *          The matrix to be multiplied by CTO/CFROM.  See TYPE for the
00067 *          storage type.
00068 *
00069 *  LDA     (input) INTEGER
00070 *          The leading dimension of the array A.  LDA >= max(1,M).
00071 *
00072 *  INFO    (output) INTEGER
00073 *          0  - successful exit
00074 *          <0 - if INFO = -i, the i-th argument had an illegal value.
00075 *
00076 *  =====================================================================
00077 *
00078 *     .. Parameters ..
00079       DOUBLE PRECISION   ZERO, ONE
00080       PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
00081 *     ..
00082 *     .. Local Scalars ..
00083       LOGICAL            DONE
00084       INTEGER            I, ITYPE, J, K1, K2, K3, K4
00085       DOUBLE PRECISION   BIGNUM, CFROM1, CFROMC, CTO1, CTOC, MUL, SMLNUM
00086 *     ..
00087 *     .. External Functions ..
00088       LOGICAL            LSAME, DISNAN
00089       DOUBLE PRECISION   DLAMCH
00090       EXTERNAL           LSAME, DLAMCH, DISNAN
00091 *     ..
00092 *     .. Intrinsic Functions ..
00093       INTRINSIC          ABS, MAX, MIN
00094 *     ..
00095 *     .. External Subroutines ..
00096       EXTERNAL           XERBLA
00097 *     ..
00098 *     .. Executable Statements ..
00099 *
00100 *     Test the input arguments
00101 *
00102       INFO = 0
00103 *
00104       IF( LSAME( TYPE, 'G' ) ) THEN
00105          ITYPE = 0
00106       ELSE IF( LSAME( TYPE, 'L' ) ) THEN
00107          ITYPE = 1
00108       ELSE IF( LSAME( TYPE, 'U' ) ) THEN
00109          ITYPE = 2
00110       ELSE IF( LSAME( TYPE, 'H' ) ) THEN
00111          ITYPE = 3
00112       ELSE IF( LSAME( TYPE, 'B' ) ) THEN
00113          ITYPE = 4
00114       ELSE IF( LSAME( TYPE, 'Q' ) ) THEN
00115          ITYPE = 5
00116       ELSE IF( LSAME( TYPE, 'Z' ) ) THEN
00117          ITYPE = 6
00118       ELSE
00119          ITYPE = -1
00120       END IF
00121 *
00122       IF( ITYPE.EQ.-1 ) THEN
00123          INFO = -1
00124       ELSE IF( CFROM.EQ.ZERO .OR. DISNAN(CFROM) ) THEN
00125          INFO = -4
00126       ELSE IF( DISNAN(CTO) ) THEN
00127          INFO = -5
00128       ELSE IF( M.LT.0 ) THEN
00129          INFO = -6
00130       ELSE IF( N.LT.0 .OR. ( ITYPE.EQ.4 .AND. N.NE.M ) .OR.
00131      \$         ( ITYPE.EQ.5 .AND. N.NE.M ) ) THEN
00132          INFO = -7
00133       ELSE IF( ITYPE.LE.3 .AND. LDA.LT.MAX( 1, M ) ) THEN
00134          INFO = -9
00135       ELSE IF( ITYPE.GE.4 ) THEN
00136          IF( KL.LT.0 .OR. KL.GT.MAX( M-1, 0 ) ) THEN
00137             INFO = -2
00138          ELSE IF( KU.LT.0 .OR. KU.GT.MAX( N-1, 0 ) .OR.
00139      \$            ( ( ITYPE.EQ.4 .OR. ITYPE.EQ.5 ) .AND. KL.NE.KU ) )
00140      \$             THEN
00141             INFO = -3
00142          ELSE IF( ( ITYPE.EQ.4 .AND. LDA.LT.KL+1 ) .OR.
00143      \$            ( ITYPE.EQ.5 .AND. LDA.LT.KU+1 ) .OR.
00144      \$            ( ITYPE.EQ.6 .AND. LDA.LT.2*KL+KU+1 ) ) THEN
00145             INFO = -9
00146          END IF
00147       END IF
00148 *
00149       IF( INFO.NE.0 ) THEN
00150          CALL XERBLA( 'DLASCL', -INFO )
00151          RETURN
00152       END IF
00153 *
00154 *     Quick return if possible
00155 *
00156       IF( N.EQ.0 .OR. M.EQ.0 )
00157      \$   RETURN
00158 *
00159 *     Get machine parameters
00160 *
00161       SMLNUM = DLAMCH( 'S' )
00162       BIGNUM = ONE / SMLNUM
00163 *
00164       CFROMC = CFROM
00165       CTOC = CTO
00166 *
00167    10 CONTINUE
00168       CFROM1 = CFROMC*SMLNUM
00169       IF( CFROM1.EQ.CFROMC ) THEN
00170 !        CFROMC is an inf.  Multiply by a correctly signed zero for
00171 !        finite CTOC, or a NaN if CTOC is infinite.
00172          MUL = CTOC / CFROMC
00173          DONE = .TRUE.
00174          CTO1 = CTOC
00175       ELSE
00176          CTO1 = CTOC / BIGNUM
00177          IF( CTO1.EQ.CTOC ) THEN
00178 !           CTOC is either 0 or an inf.  In both cases, CTOC itself
00179 !           serves as the correct multiplication factor.
00180             MUL = CTOC
00181             DONE = .TRUE.
00182             CFROMC = ONE
00183          ELSE IF( ABS( CFROM1 ).GT.ABS( CTOC ) .AND. CTOC.NE.ZERO ) THEN
00184             MUL = SMLNUM
00185             DONE = .FALSE.
00186             CFROMC = CFROM1
00187          ELSE IF( ABS( CTO1 ).GT.ABS( CFROMC ) ) THEN
00188             MUL = BIGNUM
00189             DONE = .FALSE.
00190             CTOC = CTO1
00191          ELSE
00192             MUL = CTOC / CFROMC
00193             DONE = .TRUE.
00194          END IF
00195       END IF
00196 *
00197       IF( ITYPE.EQ.0 ) THEN
00198 *
00199 *        Full matrix
00200 *
00201          DO 30 J = 1, N
00202             DO 20 I = 1, M
00203                A( I, J ) = A( I, J )*MUL
00204    20       CONTINUE
00205    30    CONTINUE
00206 *
00207       ELSE IF( ITYPE.EQ.1 ) THEN
00208 *
00209 *        Lower triangular matrix
00210 *
00211          DO 50 J = 1, N
00212             DO 40 I = J, M
00213                A( I, J ) = A( I, J )*MUL
00214    40       CONTINUE
00215    50    CONTINUE
00216 *
00217       ELSE IF( ITYPE.EQ.2 ) THEN
00218 *
00219 *        Upper triangular matrix
00220 *
00221          DO 70 J = 1, N
00222             DO 60 I = 1, MIN( J, M )
00223                A( I, J ) = A( I, J )*MUL
00224    60       CONTINUE
00225    70    CONTINUE
00226 *
00227       ELSE IF( ITYPE.EQ.3 ) THEN
00228 *
00229 *        Upper Hessenberg matrix
00230 *
00231          DO 90 J = 1, N
00232             DO 80 I = 1, MIN( J+1, M )
00233                A( I, J ) = A( I, J )*MUL
00234    80       CONTINUE
00235    90    CONTINUE
00236 *
00237       ELSE IF( ITYPE.EQ.4 ) THEN
00238 *
00239 *        Lower half of a symmetric band matrix
00240 *
00241          K3 = KL + 1
00242          K4 = N + 1
00243          DO 110 J = 1, N
00244             DO 100 I = 1, MIN( K3, K4-J )
00245                A( I, J ) = A( I, J )*MUL
00246   100       CONTINUE
00247   110    CONTINUE
00248 *
00249       ELSE IF( ITYPE.EQ.5 ) THEN
00250 *
00251 *        Upper half of a symmetric band matrix
00252 *
00253          K1 = KU + 2
00254          K3 = KU + 1
00255          DO 130 J = 1, N
00256             DO 120 I = MAX( K1-J, 1 ), K3
00257                A( I, J ) = A( I, J )*MUL
00258   120       CONTINUE
00259   130    CONTINUE
00260 *
00261       ELSE IF( ITYPE.EQ.6 ) THEN
00262 *
00263 *        Band matrix
00264 *
00265          K1 = KL + KU + 2
00266          K2 = KL + 1
00267          K3 = 2*KL + KU + 1
00268          K4 = KL + KU + 1 + M
00269          DO 150 J = 1, N
00270             DO 140 I = MAX( K1-J, K2 ), MIN( K3, K4-J )
00271                A( I, J ) = A( I, J )*MUL
00272   140       CONTINUE
00273   150    CONTINUE
00274 *
00275       END IF
00276 *
00277       IF( .NOT.DONE )
00278      \$   GO TO 10
00279 *
00280       RETURN
00281 *
00282 *     End of DLASCL
00283 *
00284       END
```