1      SUBROUTINE PZLAWIL( II, JJ, M, A, DESCA, H44, H33, H43H34, V )
2*
3*  -- ScaLAPACK routine (version 1.7) --
4*     University of Tennessee, Knoxville, Oak Ridge National Laboratory,
5*     and University of California, Berkeley.
6*     July 31, 2001
7*
8*     .. Scalar Arguments ..
9      INTEGER            II, JJ, M
10      COMPLEX*16         H33, H43H34, H44
11*     ..
12*     .. Array Arguments ..
13      INTEGER            DESCA( * )
14      COMPLEX*16         A( * ), V( * )
15*     ..
16*
17*  Purpose
18*  =======
19*
20*  PZLAWIL gets the transform given by H44,H33, & H43H34 into V
21*     starting at row M.
22*
23*  Notes
24*  =====
25*
26*  Each global data object is described by an associated description
27*  vector.  This vector stores the information required to establish
28*  the mapping between an object element and its corresponding process
29*  and memory location.
30*
31*  Let A be a generic term for any 2D block cyclicly distributed array.
32*  Such a global array has an associated description vector DESCA.
33*  In the following comments, the character _ should be read as
34*  "of the global array".
35*
36*  NOTATION        STORED IN      EXPLANATION
37*  --------------- -------------- --------------------------------------
38*  DTYPE_A(global) DESCA( DTYPE_ )The descriptor type.  In this case,
39*                                 DTYPE_A = 1.
40*  CTXT_A (global) DESCA( CTXT_ ) The BLACS context handle, indicating
41*                                 the BLACS process grid A is distribu-
42*                                 ted over. The context itself is glo-
43*                                 bal, but the handle (the integer
44*                                 value) may vary.
45*  M_A    (global) DESCA( M_ )    The number of rows in the global
46*                                 array A.
47*  N_A    (global) DESCA( N_ )    The number of columns in the global
48*                                 array A.
49*  MB_A   (global) DESCA( MB_ )   The blocking factor used to distribute
50*                                 the rows of the array.
51*  NB_A   (global) DESCA( NB_ )   The blocking factor used to distribute
52*                                 the columns of the array.
53*  RSRC_A (global) DESCA( RSRC_ ) The process row over which the first
54*                                 row of the array A is distributed.
55*  CSRC_A (global) DESCA( CSRC_ ) The process column over which the
56*                                 first column of the array A is
57*                                 distributed.
58*  LLD_A  (local)  DESCA( LLD_ )  The leading dimension of the local
59*                                 array.  LLD_A >= MAX(1,LOCr(M_A)).
60*
61*  Let K be the number of rows or columns of a distributed matrix,
62*  and assume that its process grid has dimension p x q.
63*  LOCr( K ) denotes the number of elements of K that a process
64*  would receive if K were distributed over the p processes of its
65*  process column.
66*  Similarly, LOCc( K ) denotes the number of elements of K that a
67*  process would receive if K were distributed over the q processes of
68*  its process row.
69*  The values of LOCr() and LOCc() may be determined via a call to the
70*  ScaLAPACK tool function, NUMROC:
71*          LOCr( M ) = NUMROC( M, MB_A, MYROW, RSRC_A, NPROW ),
72*          LOCc( N ) = NUMROC( N, NB_A, MYCOL, CSRC_A, NPCOL ).
73*  An upper bound for these quantities may be computed by:
74*          LOCr( M ) <= ceil( ceil(M/MB_A)/NPROW )*MB_A
75*          LOCc( N ) <= ceil( ceil(N/NB_A)/NPCOL )*NB_A
76*
77*  Arguments
78*  =========
79*
80*  II      (global input) INTEGER
81*          Row owner of H(M+2,M+2)
82*
83*  JJ      (global input) INTEGER
84*          Column owner of H(M+2,M+2)
85*
86*  M       (global input) INTEGER
87*          On entry, this is where the transform starts (row M.)
88*          Unchanged on exit.
89*
90*  A       (global input) COMPLEX*16 array, dimension
91*          (DESCA(LLD_),*)
92*          On entry, the Hessenberg matrix.
93*          Unchanged on exit.
94*
95*  DESCA   (global and local input) INTEGER array of dimension DLEN_.
96*          The array descriptor for the distributed matrix A.
97*          Unchanged on exit.
98*
99*  H44
100*  H33
101*  H43H34  (global input) COMPLEX*16
102*          These three values are for the double shift QR iteration.
103*          Unchanged on exit.
104*
105*  V       (global output) COMPLEX*16 array of size 3.
106*          Contains the transform on ouput.
107*
108*  Further Details
109*  ===============
110*
111*  Implemented by:  M. Fahey, May 28, 1999
112*
113*  =====================================================================
114*
115*     .. Parameters ..
116      INTEGER            BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
117     $                   LLD_, MB_, M_, NB_, N_, RSRC_
118      PARAMETER          ( BLOCK_CYCLIC_2D = 1, DLEN_ = 9, DTYPE_ = 1,
119     $                     CTXT_ = 2, M_ = 3, N_ = 4, MB_ = 5, NB_ = 6,
120     $                     RSRC_ = 7, CSRC_ = 8, LLD_ = 9 )
121*     ..
122*     .. Local Scalars ..
123      INTEGER            CONTXT, DOWN, HBL, ICOL, IROW, JSRC, LDA, LEFT,
124     $                   MODKM1, MYCOL, MYROW, NPCOL, NPROW, NUM, RIGHT,
125     $                   RSRC, UP
126      DOUBLE PRECISION   S
127      COMPLEX*16         CDUM, H11, H12, H21, H22, H33S, H44S, V1, V2,
128     $                   V3
129*     ..
130*     .. Local Arrays ..
131      COMPLEX*16         BUF( 4 )
132*     ..
133*     .. External Subroutines ..
134      EXTERNAL           BLACS_GRIDINFO, INFOG2L, ZGERV2D, ZGESD2D
135*     ..
136*     .. Intrinsic Functions ..
137      INTRINSIC          ABS, DBLE, DIMAG, MOD
138*     ..
139*     .. Statement Functions ..
140      DOUBLE PRECISION   CABS1
141*     ..
142*     .. Statement Function definitions ..
143      CABS1( CDUM ) = ABS( DBLE( CDUM ) ) + ABS( DIMAG( CDUM ) )
144*     ..
145*     .. Executable Statements ..
146*
147      HBL = DESCA( MB_ )
148      CONTXT = DESCA( CTXT_ )
149      LDA = DESCA( LLD_ )
150      CALL BLACS_GRIDINFO( CONTXT, NPROW, NPCOL, MYROW, MYCOL )
151      LEFT = MOD( MYCOL+NPCOL-1, NPCOL )
152      RIGHT = MOD( MYCOL+1, NPCOL )
153      UP = MOD( MYROW+NPROW-1, NPROW )
154      DOWN = MOD( MYROW+1, NPROW )
155      NUM = NPROW*NPCOL
156*
157*     On node (II,JJ) collect all DIA,SUP,SUB info from M, M+1
158*
159      MODKM1 = MOD( M+1, HBL )
160      IF( MODKM1.EQ.0 ) THEN
161         IF( ( MYROW.EQ.II ) .AND. ( RIGHT.EQ.JJ ) .AND.
162     $       ( NPCOL.GT.1 ) ) THEN
163            CALL INFOG2L( M+2, M+1, DESCA, NPROW, NPCOL, MYROW, MYCOL,
164     $                    IROW, ICOL, RSRC, JSRC )
165            BUF( 1 ) = A( ( ICOL-1 )*LDA+IROW )
166            CALL ZGESD2D( CONTXT, 1, 1, BUF, 1, II, JJ )
167         END IF
168         IF( ( DOWN.EQ.II ) .AND. ( RIGHT.EQ.JJ ) .AND. ( NUM.GT.1 ) )
169     $        THEN
170            CALL INFOG2L( M, M, DESCA, NPROW, NPCOL, MYROW, MYCOL, IROW,
171     $                    ICOL, RSRC, JSRC )
172            BUF( 1 ) = A( ( ICOL-1 )*LDA+IROW )
173            BUF( 2 ) = A( ( ICOL-1 )*LDA+IROW+1 )
174            BUF( 3 ) = A( ICOL*LDA+IROW )
175            BUF( 4 ) = A( ICOL*LDA+IROW+1 )
176            CALL ZGESD2D( CONTXT, 4, 1, BUF, 4, II, JJ )
177         END IF
178         IF( ( MYROW.EQ.II ) .AND. ( MYCOL.EQ.JJ ) ) THEN
179            CALL INFOG2L( M+2, M+2, DESCA, NPROW, NPCOL, MYROW, MYCOL,
180     $                    IROW, ICOL, RSRC, JSRC )
181            IF( NPCOL.GT.1 ) THEN
182               CALL ZGERV2D( CONTXT, 1, 1, V3, 1, MYROW, LEFT )
183            ELSE
184               V3 = A( ( ICOL-2 )*LDA+IROW )
185            END IF
186            IF( NUM.GT.1 ) THEN
187               CALL ZGERV2D( CONTXT, 4, 1, BUF, 4, UP, LEFT )
188               H11 = BUF( 1 )
189               H21 = BUF( 2 )
190               H12 = BUF( 3 )
191               H22 = BUF( 4 )
192            ELSE
193               H11 = A( ( ICOL-3 )*LDA+IROW-2 )
194               H21 = A( ( ICOL-3 )*LDA+IROW-1 )
195               H12 = A( ( ICOL-2 )*LDA+IROW-2 )
196               H22 = A( ( ICOL-2 )*LDA+IROW-1 )
197            END IF
198         END IF
199      END IF
200      IF( MODKM1.EQ.1 ) THEN
201         IF( ( DOWN.EQ.II ) .AND. ( RIGHT.EQ.JJ ) .AND. ( NUM.GT.1 ) )
202     $        THEN
203            CALL INFOG2L( M, M, DESCA, NPROW, NPCOL, MYROW, MYCOL, IROW,
204     $                    ICOL, RSRC, JSRC )
205            CALL ZGESD2D( CONTXT, 1, 1, A( ( ICOL-1 )*LDA+IROW ), 1, II,
206     $                    JJ )
207         END IF
208         IF( ( DOWN.EQ.II ) .AND. ( MYCOL.EQ.JJ ) .AND. ( NPROW.GT.1 ) )
209     $        THEN
210            CALL INFOG2L( M, M+1, DESCA, NPROW, NPCOL, MYROW, MYCOL,
211     $                    IROW, ICOL, RSRC, JSRC )
212            CALL ZGESD2D( CONTXT, 1, 1, A( ( ICOL-1 )*LDA+IROW ), 1, II,
213     $                    JJ )
214         END IF
215         IF( ( MYROW.EQ.II ) .AND. ( RIGHT.EQ.JJ ) .AND.
216     $       ( NPCOL.GT.1 ) ) THEN
217            CALL INFOG2L( M+1, M, DESCA, NPROW, NPCOL, MYROW, MYCOL,
218     $                    IROW, ICOL, RSRC, JSRC )
219            CALL ZGESD2D( CONTXT, 1, 1, A( ( ICOL-1 )*LDA+IROW ), 1, II,
220     $                    JJ )
221         END IF
222         IF( ( MYROW.EQ.II ) .AND. ( MYCOL.EQ.JJ ) ) THEN
223            CALL INFOG2L( M+2, M+2, DESCA, NPROW, NPCOL, MYROW, MYCOL,
224     $                    IROW, ICOL, RSRC, JSRC )
225            IF( NUM.GT.1 ) THEN
226               CALL ZGERV2D( CONTXT, 1, 1, H11, 1, UP, LEFT )
227            ELSE
228               H11 = A( ( ICOL-3 )*LDA+IROW-2 )
229            END IF
230            IF( NPROW.GT.1 ) THEN
231               CALL ZGERV2D( CONTXT, 1, 1, H12, 1, UP, MYCOL )
232            ELSE
233               H12 = A( ( ICOL-2 )*LDA+IROW-2 )
234            END IF
235            IF( NPCOL.GT.1 ) THEN
236               CALL ZGERV2D( CONTXT, 1, 1, H21, 1, MYROW, LEFT )
237            ELSE
238               H21 = A( ( ICOL-3 )*LDA+IROW-1 )
239            END IF
240            H22 = A( ( ICOL-2 )*LDA+IROW-1 )
241            V3 = A( ( ICOL-2 )*LDA+IROW )
242         END IF
243      END IF
244      IF( ( MYROW.NE.II ) .OR. ( MYCOL.NE.JJ ) )
245     $   RETURN
246*
247      IF( MODKM1.GT.1 ) THEN
248         CALL INFOG2L( M+2, M+2, DESCA, NPROW, NPCOL, MYROW, MYCOL,
249     $                 IROW, ICOL, RSRC, JSRC )
250         H11 = A( ( ICOL-3 )*LDA+IROW-2 )
251         H21 = A( ( ICOL-3 )*LDA+IROW-1 )
252         H12 = A( ( ICOL-2 )*LDA+IROW-2 )
253         H22 = A( ( ICOL-2 )*LDA+IROW-1 )
254         V3 = A( ( ICOL-2 )*LDA+IROW )
255      END IF
256*
257      H44S = H44 - H11
258      H33S = H33 - H11
259      V1 = ( H33S*H44S-H43H34 ) / H21 + H12
260      V2 = H22 - H11 - H33S - H44S
261      S = CABS1( V1 ) + CABS1( V2 ) + CABS1( V3 )
262      V1 = V1 / S
263      V2 = V2 / S
264      V3 = V3 / S
265      V( 1 ) = V1
266      V( 2 ) = V2
267      V( 3 ) = V3
268*
269      RETURN
270*
271*     End of PZLAWIL
272*
273      END
274