3
4
5
6
7
8
9
10 CHARACTER JOBZ, UPLO
11 INTEGER IA, INFO, IZ, JA, JZ, LIWORK, LWORK, N
12
13
14 INTEGER DESCA( * ), DESCZ( * ), IWORK( * )
15 DOUBLE PRECISION A( * ), W( * ), WORK( * ), Z( * )
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155 INTEGER BLOCK_CYCLIC_2D, DLEN_, DTYPE_, CTXT_, M_, N_,
156 $ MB_, NB_, RSRC_, CSRC_, LLD_
157 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
158 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
159 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
160 DOUBLE PRECISION ZERO, ONE
161 parameter( zero = 0.0d+0, one = 1.0d+0 )
162
163
164 LOGICAL LQUERY, UPPER
165 INTEGER IACOL, IAROW, ICOFFA, ICOFFZ, ICTXT, IINFO,
166 $ INDD, INDE, INDE2, INDTAU, INDWORK, INDWORK2,
167 $ IROFFA, IROFFZ, ISCALE, LIWMIN, LLWORK,
168 $ LLWORK2, LWMIN, MYCOL, MYROW, NB, NP, NPCOL,
169 $ NPROW, NQ, OFFSET, TRILWMIN
170 DOUBLE PRECISION ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,
171 $ SMLNUM
172
173
174
175 INTEGER IDUM1( 2 ), IDUM2( 2 )
176
177
178 LOGICAL LSAME
179 INTEGER INDXG2P, NUMROC
180 DOUBLE PRECISION PDLAMCH, PDLANSY
182
183
187
188
189 INTRINSIC dble, ichar,
max,
min, mod, sqrt
190
191
192
193 IF( block_cyclic_2d*csrc_*ctxt_*dlen_*dtype_*lld_*mb_*m_*nb_*n_*
194 $ rsrc_.LT.0 )RETURN
195
196
197
198 IF( n.EQ.0 )
199 $ RETURN
200
201
202
203 ictxt = descz( ctxt_ )
204 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
205
206 info = 0
207 IF( nprow.EQ.-1 ) THEN
208 info = -( 600+ctxt_ )
209 ELSE
210 CALL chk1mat( n, 3, n, 3, ia, ja, desca, 7, info )
211 CALL chk1mat( n, 3, n, 3, iz, jz, descz, 12, info )
212 IF( info.EQ.0 ) THEN
213 upper =
lsame( uplo,
'U' )
214 nb = desca( nb_ )
215 iroffa = mod( ia-1, desca( mb_ ) )
216 icoffa = mod( ja-1, desca( nb_ ) )
217 iroffz = mod( iz-1, descz( mb_ ) )
218 icoffz = mod( jz-1, descz( nb_ ) )
219 iarow =
indxg2p( ia, nb, myrow, desca( rsrc_ ), nprow )
220 iacol =
indxg2p( ja, nb, mycol, desca( csrc_ ), npcol )
221 np =
numroc( n, nb, myrow, iarow, nprow )
222 nq =
numroc( n, nb, mycol, iacol, npcol )
223
224 lquery = ( lwork.EQ.-1 )
225 trilwmin = 3*n +
max( nb*( np+1 ), 3*nb )
226 lwmin =
max( 1+6*n+2*np*nq, trilwmin ) + 2*n
227 liwmin = 7*n + 8*npcol + 2
228 work( 1 ) = dble( lwmin )
229 iwork( 1 ) = liwmin
230 IF( .NOT.
lsame( jobz,
'V' ) )
THEN
231 info = -1
232 ELSE IF( .NOT.upper .AND. .NOT.
lsame( uplo,
'L' ) )
THEN
233 info = -2
234 ELSE IF( iroffa.NE.icoffa .OR. icoffa.NE.0 ) THEN
235 info = -6
236 ELSE IF( iroffa.NE.iroffz .OR. icoffa.NE.icoffz ) THEN
237 info = -10
238 ELSE IF( desca( m_ ).NE.descz( m_ ) ) THEN
239 info = -( 1200+m_ )
240 ELSE IF( desca( mb_ ).NE.desca( nb_ ) ) THEN
241 info = -( 700+nb_ )
242 ELSE IF( descz( mb_ ).NE.descz( nb_ ) ) THEN
243 info = -( 1200+nb_ )
244 ELSE IF( desca( mb_ ).NE.descz( mb_ ) ) THEN
245 info = -( 1200+mb_ )
246 ELSE IF( desca( ctxt_ ).NE.descz( ctxt_ ) ) THEN
247 info = -( 1200+ctxt_ )
248 ELSE IF( desca( rsrc_ ).NE.descz( rsrc_ ) ) THEN
249 info = -( 1200+rsrc_ )
250 ELSE IF( desca( csrc_ ).NE.descz( csrc_ ) ) THEN
251 info = -( 1200+csrc_ )
252 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
253 info = -14
254 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery ) THEN
255 info = -16
256 END IF
257 END IF
258 IF( upper ) THEN
259 idum1( 1 ) = ichar( 'U' )
260 ELSE
261 idum1( 1 ) = ichar( 'L' )
262 END IF
263 idum2( 1 ) = 2
264 IF( lwork.EQ.-1 ) THEN
265 idum1( 2 ) = -1
266 ELSE
267 idum1( 2 ) = 1
268 END IF
269 idum2( 2 ) = 14
270 CALL pchk1mat( n, 3, n, 3, ia, ja, desca, 7, 2, idum1, idum2,
271 $ info )
272 END IF
273 IF( info.NE.0 ) THEN
274 CALL pxerbla( ictxt,
'PDSYEVD', -info )
275 RETURN
276 ELSE IF( lquery ) THEN
277 RETURN
278 END IF
279
280
281
282 indtau = 1
283 inde = indtau + n
284 indd = inde + n
285 inde2 = indd + n
286 indwork = inde2 + n
287 llwork = lwork - indwork + 1
288 indwork2 = indd
289 llwork2 = lwork - indwork2 + 1
290
291
292
293 iscale = 0
294 safmin =
pdlamch( desca( ctxt_ ),
'Safe minimum' )
295 eps =
pdlamch( desca( ctxt_ ),
'Precision' )
296 smlnum = safmin / eps
297 bignum = one / smlnum
298 rmin = sqrt( smlnum )
299 rmax =
min( sqrt( bignum ), one / sqrt( sqrt( safmin ) ) )
300 anrm =
pdlansy(
'M', uplo, n, a, ia, ja, desca, work( indwork ) )
301
302 IF( anrm.GT.zero .AND. anrm.LT.rmin ) THEN
303 iscale = 1
304 sigma = rmin / anrm
305 ELSE IF( anrm.GT.rmax ) THEN
306 iscale = 1
307 sigma = rmax / anrm
308 END IF
309
310 IF( iscale.EQ.1 ) THEN
311 CALL pdlascl( uplo, one, sigma, n, n, a, ia, ja, desca, iinfo )
312 END IF
313
314
315
316
317 CALL pdsytrd( uplo, n, a, ia, ja, desca, work( indd ),
318 $ work( inde2 ), work( indtau ), work( indwork ),
319 $ llwork, iinfo )
320
321
322
323 CALL pdlared1d( n, ia, ja, desca, work( indd ), w,
324 $ work( indwork ), llwork )
325
326 CALL pdlared1d( n, ia, ja, desca, work( inde2 ), work( inde ),
327 $ work( indwork ), llwork )
328
329 CALL pdlaset(
'Full', n, n, zero, one, z, 1, 1, descz )
330
331 IF( upper ) THEN
332 offset = 1
333 ELSE
334 offset = 0
335 END IF
336 CALL pdstedc(
'I', n, w, work( inde+offset ), z, iz, jz, descz,
337 $ work( indwork2 ), llwork2, iwork, liwork, info )
338
339 CALL pdormtr(
'L', uplo,
'N', n, n, a, ia, ja, desca,
340 $ work( indtau ), z, iz, jz, descz, work( indwork2 ),
341 $ llwork2, iinfo )
342
343
344
345 IF( iscale.EQ.1 ) THEN
346 CALL dscal( n, one / sigma, w, 1 )
347 END IF
348
349 RETURN
350
351
352
subroutine chk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, info)
integer function indxg2p(indxglob, nb, iproc, isrcproc, nprocs)
integer function numroc(n, nb, iproc, isrcproc, nprocs)
subroutine pchk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, nextra, ex, expos, info)
subroutine pdlaset(uplo, m, n, alpha, beta, a, ia, ja, desca)
double precision function pdlamch(ictxt, cmach)
double precision function pdlansy(norm, uplo, n, a, ia, ja, desca, work)
subroutine pdlared1d(n, ia, ja, desc, bycol, byall, work, lwork)
subroutine pdlascl(type, cfrom, cto, m, n, a, ia, ja, desca, info)
subroutine pdormtr(side, uplo, trans, m, n, a, ia, ja, desca, tau, c, ic, jc, descc, work, lwork, info)
subroutine pdstedc(compz, n, d, e, q, iq, jq, descq, work, lwork, iwork, liwork, info)
subroutine pdsytrd(uplo, n, a, ia, ja, desca, d, e, tau, work, lwork, info)
subroutine pxerbla(ictxt, srname, info)