ScaLAPACK  2.0.2
ScaLAPACK: Scalable Linear Algebra PACKage
pcbmatgen.f
Go to the documentation of this file.
00001       SUBROUTINE PCBMATGEN( ICTXT, AFORM, AFORM2, BWL, BWU, N,
00002      $                     MB, NB, A,
00003      $                     LDA, IAROW, IACOL, ISEED,
00004      $                     MYROW, MYCOL, NPROW, NPCOL )
00005 *
00006 *
00007 *
00008 *  -- ScaLAPACK routine (version 1.7) --
00009 *     University of Tennessee, Knoxville, Oak Ridge National Laboratory,
00010 *     and University of California, Berkeley.
00011 *     November 15, 1997
00012 *
00013 *     .. Scalar Arguments ..
00014 *     .. Scalar Arguments ..
00015       CHARACTER*1        AFORM, AFORM2
00016       INTEGER            IACOL, IAROW, ICTXT,
00017      $                   ISEED, LDA, MB, MYCOL, MYROW, N,
00018      $                   NB, NPCOL, NPROW, BWL, BWU
00019 *     ..
00020 *     .. Array Arguments ..
00021       COMPLEX            A( LDA, * )
00022 *     ..
00023 *
00024 *  Purpose
00025 *  =======
00026 *
00027 *  PCBMATGEN : Parallel Complex Single precision Band MATrix GENerator.
00028 *  (Re)Generate a distributed Band matrix A (or sub-matrix of A).
00029 *
00030 *  Arguments
00031 *  =========
00032 *
00033 *  ICTXT   (global input) INTEGER
00034 *          The BLACS context handle, indicating the global context of
00035 *          the operation. The context itself is global.
00036 *
00037 *  AFORM   (global input) CHARACTER*1
00038 *          if AFORM = 'L' : A is returned as a hermitian lower
00039 *            triangular matrix, and is diagonally dominant.
00040 *          if AFORM = 'U' : A is returned as a hermitian upper
00041 *            triangular matrix, and is diagonally dominant.
00042 *          if AFORM = 'G' : A is returned as a general matrix.
00043 *          if AFORM = 'T' : A is returned as a general matrix in
00044 *            tridiagonal-compatible form.
00045 *
00046 *  AFORM2  (global input) CHARACTER*1
00047 *          if the matrix is general:
00048 *            if AFORM2 = 'D' : A is returned diagonally dominant.
00049 *            if AFORM2 != 'D' : A is not returned diagonally dominant.
00050 *          if the matrix is symmetric or hermitian:
00051 *            if AFORM2 = 'T' : A is returned in tridiagonally-compatible
00052 *              form (a transpose form).
00053 *            if AFORM2 != 'T' : A is returned in banded-compatible form.
00054 *
00055 *  M       (global input) INTEGER
00056 *          The number of nonzero rows in the generated distributed
00057 *           band matrix.
00058 *
00059 *  N       (global input) INTEGER
00060 *          The number of columns in the generated distributed
00061 *          matrix.
00062 *
00063 *  MB      (global input) INTEGER
00064 *          The row blocking factor of the distributed matrix A.
00065 *
00066 *  NB      (global input) INTEGER
00067 *          The column blocking factor of the distributed matrix A.
00068 *
00069 *  A       (local output) COMPLEX, pointer into the local memory to
00070 *          an array of dimension ( LDA, * ) containing the local
00071 *          pieces of the distributed matrix.
00072 *
00073 *  LDA     (local input) INTEGER
00074 *          The leading dimension of the array containing the local
00075 *          pieces of the distributed matrix A.
00076 *
00077 *  IAROW   (global input) INTEGER
00078 *          The row processor coordinate which holds the first block
00079 *          of the distributed matrix A.
00080 *            A( DIAG_INDEX, I ) = A( DIAG_INDEX, I ) + BWL+BWU
00081 *
00082 *  IACOL   (global input) INTEGER
00083 *          The column processor coordinate which holds the first
00084 *          block of the distributed matrix A.
00085 *
00086 *  ISEED   (global input) INTEGER
00087 *          The seed number to generate the distributed matrix A.
00088 *
00089 *  MYROW   (local input) INTEGER
00090 *          The row process coordinate of the calling process.
00091 *
00092 *  MYCOL   (local input) INTEGER
00093 *          The column process coordinate of the calling process.
00094 *
00095 *  NPROW   (global input) INTEGER
00096 *          The number of process rows in the grid.
00097 *
00098 *  NPCOL   (global input) INTEGER
00099 *          The number of process columns in the grid.
00100 *
00101 *  Notes
00102 *  =====
00103 *
00104 *  This code is a simple wrapper around PCMATGEN, for band matrices.
00105 *
00106 *  =====================================================================
00107 *
00108 *  Code Developer: Andrew J. Cleary, University of Tennessee.
00109 *    Current address: Lawrence Livermore National Labs.
00110 *  This version released: August, 2001.
00111 *
00112 *  =====================================================================
00113 *
00114 *     ..
00115 *     .. Parameters ..
00116       REAL               ONE, ZERO
00117       PARAMETER          ( ONE = 1.0E+0 )
00118       PARAMETER          ( ZERO = 0.0E+0 )
00119       COMPLEX            CONE, CZERO
00120       PARAMETER          ( CONE = ( 1.0E+0, 0.0E+0 ) )
00121       PARAMETER          ( CZERO = ( 0.0E+0, 0.0E+0 ) )
00122 *     ..
00123 *     .. Local Scalars ..
00124       INTEGER           DIAG_INDEX, I, J, M_MATGEN, NQ, N_MATGEN,
00125      $                  START_INDEX
00126 *     ..
00127 *     .. External Subroutines ..
00128       EXTERNAL           PCMATGEN
00129 *     ..
00130 *     .. External Functions ..
00131       LOGICAL            LSAME
00132       INTEGER            ICEIL, NUMROC
00133       EXTERNAL           ICEIL, NUMROC, LSAME
00134 *     ..
00135 *     .. Executable Statements ..
00136 *
00137 *
00138       IF( LSAME( AFORM, 'L' ).OR.LSAME( AFORM, 'U' ) ) THEN
00139          M_MATGEN = BWL + 1
00140          N_MATGEN = N
00141          START_INDEX = 1
00142          IF( LSAME( AFORM, 'L' ) ) THEN
00143             DIAG_INDEX = 1
00144          ELSE
00145             DIAG_INDEX = BWL + 1
00146          ENDIF
00147       ELSE
00148          M_MATGEN = BWL + BWU + 1
00149          N_MATGEN = N
00150          DIAG_INDEX = BWU + 1
00151          START_INDEX = 1
00152       ENDIF
00153 *
00154       NQ = NUMROC( N, NB, MYCOL, IACOL, NPCOL )
00155 *
00156 *
00157 *     Generate a random matrix initially
00158 *
00159       IF( LSAME( AFORM, 'T' ) .OR.
00160      $  ( LSAME( AFORM2, 'T' ) ) ) THEN
00161 *
00162           CALL PCMATGEN( ICTXT, 'T', 'N',
00163      $                        N_MATGEN, M_MATGEN,
00164      $                        NB, M_MATGEN, A( START_INDEX, 1 ),
00165      $                        LDA, IAROW, IACOL,
00166      $                        ISEED, 0, NQ, 0, M_MATGEN,
00167      $                        MYCOL, MYROW, NPCOL, NPROW )
00168 *
00169       ELSE
00170 *
00171           CALL PCMATGEN( ICTXT, 'N', 'N',
00172      $                        M_MATGEN, N_MATGEN,
00173      $                        M_MATGEN, NB, A( START_INDEX, 1 ),
00174      $                        LDA, IAROW, IACOL,
00175      $                        ISEED, 0, M_MATGEN, 0, NQ,
00176      $                        MYROW, MYCOL, NPROW, NPCOL )
00177 *
00178 *        Zero out padding at tops of columns
00179 *
00180          DO 1000 J=1,NB
00181 *
00182             DO 2000 I=1, LDA-M_MATGEN
00183 *
00184 *              Indexing goes negative; BMATGEN assumes that space
00185 *              has been preallocated above the first column as it
00186 *              has to be if the matrix is to be input to
00187 *              Scalapack's band solvers.
00188 *
00189                A( I-LDA+M_MATGEN, J ) = CZERO
00190 *
00191  2000       CONTINUE
00192 *
00193  1000    CONTINUE
00194 *
00195       ENDIF
00196 *
00197       IF( LSAME( AFORM2, 'D' ).OR.
00198      $  ( LSAME( AFORM, 'L' ).OR.LSAME( AFORM, 'U' ) ) ) THEN
00199 *
00200 *       Loop over diagonal elements stored on this processor.
00201 *
00202 *
00203        DO 330 I=1, NQ
00204          IF( LSAME( AFORM, 'T' ) .OR.
00205      $     ( LSAME( AFORM2, 'T' ) ) ) THEN
00206              IF( NPROW .EQ. 1 ) THEN
00207                 A( I, DIAG_INDEX ) = CMPLX( REAL( A( I, DIAG_INDEX ) )
00208      $                               + REAL( 2*( BWL+BWU+1 ) ) )
00209              ENDIF
00210           ELSE
00211              IF( NPROW .EQ. 1 ) THEN
00212                 A( DIAG_INDEX, I ) = CMPLX( REAL( A( DIAG_INDEX, I ) )
00213      $                               + REAL( 2*( BWL+BWU+1 ) ) )
00214              ENDIF
00215           END IF
00216   330  CONTINUE
00217 *
00218 *
00219       ELSE
00220 *
00221 *       Must add elements to keep condition of matrix in check
00222 *
00223         DO 380 I=1, NQ
00224 *
00225           IF( NPROW .EQ. 1 ) THEN
00226 *
00227             IF( MOD(I+MYCOL*NB,2) .EQ. 1 ) THEN
00228                 A( DIAG_INDEX+1, I ) =
00229      $                         CMPLX( REAL( A( DIAG_INDEX+1, I ) )
00230      $                         + REAL( 2*( BWL+BWU+1 ) ) )
00231 *
00232             ELSE
00233 *
00234                 A( DIAG_INDEX-1, I ) =
00235      $                          CMPLX( REAL( A( DIAG_INDEX-1, I ) )
00236      $                          + REAL( 2*( BWL+BWU+1 ) ) )
00237             ENDIF
00238 *
00239           ENDIF
00240 *
00241   380   CONTINUE
00242 *
00243       END IF
00244 *
00245       RETURN
00246 *
00247 *     End of PCBMATGEN
00248 *
00249       END