Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/mathlibs/src/blas/cher2k.f
5204 views
1
SUBROUTINE CHER2K( UPLO, TRANS, N, K, ALPHA, A, LDA, B, LDB,
2
$ BETA, C, LDC )
3
* .. Scalar Arguments ..
4
CHARACTER*1 UPLO, TRANS
5
INTEGER N, K, LDA, LDB, LDC
6
REAL BETA
7
COMPLEX ALPHA
8
* .. Array Arguments ..
9
COMPLEX A( LDA, * ), B( LDB, * ), C( LDC, * )
10
* ..
11
*
12
* Purpose
13
* =======
14
*
15
* CHER2K performs one of the hermitian rank 2k operations
16
*
17
* C := alpha*A*conjg( B' ) + conjg( alpha )*B*conjg( A' ) + beta*C,
18
*
19
* or
20
*
21
* C := alpha*conjg( A' )*B + conjg( alpha )*conjg( B' )*A + beta*C,
22
*
23
* where alpha and beta are scalars with beta real, C is an n by n
24
* hermitian matrix and A and B are n by k matrices in the first case
25
* and k by n matrices in the second case.
26
*
27
* Parameters
28
* ==========
29
*
30
* UPLO - CHARACTER*1.
31
* On entry, UPLO specifies whether the upper or lower
32
* triangular part of the array C is to be referenced as
33
* follows:
34
*
35
* UPLO = 'U' or 'u' Only the upper triangular part of C
36
* is to be referenced.
37
*
38
* UPLO = 'L' or 'l' Only the lower triangular part of C
39
* is to be referenced.
40
*
41
* Unchanged on exit.
42
*
43
* TRANS - CHARACTER*1.
44
* On entry, TRANS specifies the operation to be performed as
45
* follows:
46
*
47
* TRANS = 'N' or 'n' C := alpha*A*conjg( B' ) +
48
* conjg( alpha )*B*conjg( A' ) +
49
* beta*C.
50
*
51
* TRANS = 'C' or 'c' C := alpha*conjg( A' )*B +
52
* conjg( alpha )*conjg( B' )*A +
53
* beta*C.
54
*
55
* Unchanged on exit.
56
*
57
* N - INTEGER.
58
* On entry, N specifies the order of the matrix C. N must be
59
* at least zero.
60
* Unchanged on exit.
61
*
62
* K - INTEGER.
63
* On entry with TRANS = 'N' or 'n', K specifies the number
64
* of columns of the matrices A and B, and on entry with
65
* TRANS = 'C' or 'c', K specifies the number of rows of the
66
* matrices A and B. K must be at least zero.
67
* Unchanged on exit.
68
*
69
* ALPHA - COMPLEX .
70
* On entry, ALPHA specifies the scalar alpha.
71
* Unchanged on exit.
72
*
73
* A - COMPLEX array of DIMENSION ( LDA, ka ), where ka is
74
* k when TRANS = 'N' or 'n', and is n otherwise.
75
* Before entry with TRANS = 'N' or 'n', the leading n by k
76
* part of the array A must contain the matrix A, otherwise
77
* the leading k by n part of the array A must contain the
78
* matrix A.
79
* Unchanged on exit.
80
*
81
* LDA - INTEGER.
82
* On entry, LDA specifies the first dimension of A as declared
83
* in the calling (sub) program. When TRANS = 'N' or 'n'
84
* then LDA must be at least max( 1, n ), otherwise LDA must
85
* be at least max( 1, k ).
86
* Unchanged on exit.
87
*
88
* B - COMPLEX array of DIMENSION ( LDB, kb ), where kb is
89
* k when TRANS = 'N' or 'n', and is n otherwise.
90
* Before entry with TRANS = 'N' or 'n', the leading n by k
91
* part of the array B must contain the matrix B, otherwise
92
* the leading k by n part of the array B must contain the
93
* matrix B.
94
* Unchanged on exit.
95
*
96
* LDB - INTEGER.
97
* On entry, LDB specifies the first dimension of B as declared
98
* in the calling (sub) program. When TRANS = 'N' or 'n'
99
* then LDB must be at least max( 1, n ), otherwise LDB must
100
* be at least max( 1, k ).
101
* Unchanged on exit.
102
*
103
* BETA - REAL .
104
* On entry, BETA specifies the scalar beta.
105
* Unchanged on exit.
106
*
107
* C - COMPLEX array of DIMENSION ( LDC, n ).
108
* Before entry with UPLO = 'U' or 'u', the leading n by n
109
* upper triangular part of the array C must contain the upper
110
* triangular part of the hermitian matrix and the strictly
111
* lower triangular part of C is not referenced. On exit, the
112
* upper triangular part of the array C is overwritten by the
113
* upper triangular part of the updated matrix.
114
* Before entry with UPLO = 'L' or 'l', the leading n by n
115
* lower triangular part of the array C must contain the lower
116
* triangular part of the hermitian matrix and the strictly
117
* upper triangular part of C is not referenced. On exit, the
118
* lower triangular part of the array C is overwritten by the
119
* lower triangular part of the updated matrix.
120
* Note that the imaginary parts of the diagonal elements need
121
* not be set, they are assumed to be zero, and on exit they
122
* are set to zero.
123
*
124
* LDC - INTEGER.
125
* On entry, LDC specifies the first dimension of C as declared
126
* in the calling (sub) program. LDC must be at least
127
* max( 1, n ).
128
* Unchanged on exit.
129
*
130
*
131
* Level 3 Blas routine.
132
*
133
* -- Written on 8-February-1989.
134
* Jack Dongarra, Argonne National Laboratory.
135
* Iain Duff, AERE Harwell.
136
* Jeremy Du Croz, Numerical Algorithms Group Ltd.
137
* Sven Hammarling, Numerical Algorithms Group Ltd.
138
*
139
* -- Modified 8-Nov-93 to set C(J,J) to REAL( C(J,J) ) when BETA = 1.
140
* Ed Anderson, Cray Research Inc.
141
*
142
*
143
* .. External Functions ..
144
LOGICAL LSAME
145
EXTERNAL LSAME
146
* .. External Subroutines ..
147
EXTERNAL XERBLA
148
* .. Intrinsic Functions ..
149
INTRINSIC CONJG, MAX, REAL
150
* .. Local Scalars ..
151
LOGICAL UPPER
152
INTEGER I, INFO, J, L, NROWA
153
COMPLEX TEMP1, TEMP2
154
* .. Parameters ..
155
REAL ONE
156
PARAMETER ( ONE = 1.0E+0 )
157
COMPLEX ZERO
158
PARAMETER ( ZERO = ( 0.0E+0, 0.0E+0 ) )
159
* ..
160
* .. Executable Statements ..
161
*
162
* Test the input parameters.
163
*
164
IF( LSAME( TRANS, 'N' ) )THEN
165
NROWA = N
166
ELSE
167
NROWA = K
168
END IF
169
UPPER = LSAME( UPLO, 'U' )
170
*
171
INFO = 0
172
IF( ( .NOT.UPPER ).AND.
173
$ ( .NOT.LSAME( UPLO , 'L' ) ) )THEN
174
INFO = 1
175
ELSE IF( ( .NOT.LSAME( TRANS, 'N' ) ).AND.
176
$ ( .NOT.LSAME( TRANS, 'C' ) ) )THEN
177
INFO = 2
178
ELSE IF( N .LT.0 )THEN
179
INFO = 3
180
ELSE IF( K .LT.0 )THEN
181
INFO = 4
182
ELSE IF( LDA.LT.MAX( 1, NROWA ) )THEN
183
INFO = 7
184
ELSE IF( LDB.LT.MAX( 1, NROWA ) )THEN
185
INFO = 9
186
ELSE IF( LDC.LT.MAX( 1, N ) )THEN
187
INFO = 12
188
END IF
189
IF( INFO.NE.0 )THEN
190
CALL XERBLA( 'CHER2K', INFO )
191
RETURN
192
END IF
193
*
194
* Quick return if possible.
195
*
196
IF( ( N.EQ.0 ).OR.
197
$ ( ( ( ALPHA.EQ.ZERO ).OR.( K.EQ.0 ) ).AND.( BETA.EQ.ONE ) ) )
198
$ RETURN
199
*
200
* And when alpha.eq.zero.
201
*
202
IF( ALPHA.EQ.ZERO )THEN
203
IF( UPPER )THEN
204
IF( BETA.EQ.REAL( ZERO ) )THEN
205
DO 20, J = 1, N
206
DO 10, I = 1, J
207
C( I, J ) = ZERO
208
10 CONTINUE
209
20 CONTINUE
210
ELSE
211
DO 40, J = 1, N
212
DO 30, I = 1, J - 1
213
C( I, J ) = BETA*C( I, J )
214
30 CONTINUE
215
C( J, J ) = BETA*REAL( C( J, J ) )
216
40 CONTINUE
217
END IF
218
ELSE
219
IF( BETA.EQ.REAL( ZERO ) )THEN
220
DO 60, J = 1, N
221
DO 50, I = J, N
222
C( I, J ) = ZERO
223
50 CONTINUE
224
60 CONTINUE
225
ELSE
226
DO 80, J = 1, N
227
C( J, J ) = BETA*REAL( C( J, J ) )
228
DO 70, I = J + 1, N
229
C( I, J ) = BETA*C( I, J )
230
70 CONTINUE
231
80 CONTINUE
232
END IF
233
END IF
234
RETURN
235
END IF
236
*
237
* Start the operations.
238
*
239
IF( LSAME( TRANS, 'N' ) )THEN
240
*
241
* Form C := alpha*A*conjg( B' ) + conjg( alpha )*B*conjg( A' ) +
242
* C.
243
*
244
IF( UPPER )THEN
245
DO 130, J = 1, N
246
IF( BETA.EQ.REAL( ZERO ) )THEN
247
DO 90, I = 1, J
248
C( I, J ) = ZERO
249
90 CONTINUE
250
ELSE IF( BETA.NE.ONE )THEN
251
DO 100, I = 1, J - 1
252
C( I, J ) = BETA*C( I, J )
253
100 CONTINUE
254
C( J, J ) = BETA*REAL( C( J, J ) )
255
ELSE
256
C( J, J ) = REAL( C( J, J ) )
257
END IF
258
DO 120, L = 1, K
259
IF( ( A( J, L ).NE.ZERO ).OR.
260
$ ( B( J, L ).NE.ZERO ) )THEN
261
TEMP1 = ALPHA*CONJG( B( J, L ) )
262
TEMP2 = CONJG( ALPHA*A( J, L ) )
263
DO 110, I = 1, J - 1
264
C( I, J ) = C( I, J ) + A( I, L )*TEMP1 +
265
$ B( I, L )*TEMP2
266
110 CONTINUE
267
C( J, J ) = REAL( C( J, J ) ) +
268
$ REAL( A( J, L )*TEMP1 +
269
$ B( J, L )*TEMP2 )
270
END IF
271
120 CONTINUE
272
130 CONTINUE
273
ELSE
274
DO 180, J = 1, N
275
IF( BETA.EQ.REAL( ZERO ) )THEN
276
DO 140, I = J, N
277
C( I, J ) = ZERO
278
140 CONTINUE
279
ELSE IF( BETA.NE.ONE )THEN
280
DO 150, I = J + 1, N
281
C( I, J ) = BETA*C( I, J )
282
150 CONTINUE
283
C( J, J ) = BETA*REAL( C( J, J ) )
284
ELSE
285
C( J, J ) = REAL( C( J, J ) )
286
END IF
287
DO 170, L = 1, K
288
IF( ( A( J, L ).NE.ZERO ).OR.
289
$ ( B( J, L ).NE.ZERO ) )THEN
290
TEMP1 = ALPHA*CONJG( B( J, L ) )
291
TEMP2 = CONJG( ALPHA*A( J, L ) )
292
DO 160, I = J + 1, N
293
C( I, J ) = C( I, J ) + A( I, L )*TEMP1 +
294
$ B( I, L )*TEMP2
295
160 CONTINUE
296
C( J, J ) = REAL( C( J, J ) ) +
297
$ REAL( A( J, L )*TEMP1 +
298
$ B( J, L )*TEMP2 )
299
END IF
300
170 CONTINUE
301
180 CONTINUE
302
END IF
303
ELSE
304
*
305
* Form C := alpha*conjg( A' )*B + conjg( alpha )*conjg( B' )*A +
306
* C.
307
*
308
IF( UPPER )THEN
309
DO 210, J = 1, N
310
DO 200, I = 1, J
311
TEMP1 = ZERO
312
TEMP2 = ZERO
313
DO 190, L = 1, K
314
TEMP1 = TEMP1 + CONJG( A( L, I ) )*B( L, J )
315
TEMP2 = TEMP2 + CONJG( B( L, I ) )*A( L, J )
316
190 CONTINUE
317
IF( I.EQ.J )THEN
318
IF( BETA.EQ.REAL( ZERO ) )THEN
319
C( J, J ) = REAL( ALPHA *TEMP1 +
320
$ CONJG( ALPHA )*TEMP2 )
321
ELSE
322
C( J, J ) = BETA*REAL( C( J, J ) ) +
323
$ REAL( ALPHA *TEMP1 +
324
$ CONJG( ALPHA )*TEMP2 )
325
END IF
326
ELSE
327
IF( BETA.EQ.REAL( ZERO ) )THEN
328
C( I, J ) = ALPHA*TEMP1 + CONJG( ALPHA )*TEMP2
329
ELSE
330
C( I, J ) = BETA *C( I, J ) +
331
$ ALPHA*TEMP1 + CONJG( ALPHA )*TEMP2
332
END IF
333
END IF
334
200 CONTINUE
335
210 CONTINUE
336
ELSE
337
DO 240, J = 1, N
338
DO 230, I = J, N
339
TEMP1 = ZERO
340
TEMP2 = ZERO
341
DO 220, L = 1, K
342
TEMP1 = TEMP1 + CONJG( A( L, I ) )*B( L, J )
343
TEMP2 = TEMP2 + CONJG( B( L, I ) )*A( L, J )
344
220 CONTINUE
345
IF( I.EQ.J )THEN
346
IF( BETA.EQ.REAL( ZERO ) )THEN
347
C( J, J ) = REAL( ALPHA *TEMP1 +
348
$ CONJG( ALPHA )*TEMP2 )
349
ELSE
350
C( J, J ) = BETA*REAL( C( J, J ) ) +
351
$ REAL( ALPHA *TEMP1 +
352
$ CONJG( ALPHA )*TEMP2 )
353
END IF
354
ELSE
355
IF( BETA.EQ.REAL( ZERO ) )THEN
356
C( I, J ) = ALPHA*TEMP1 + CONJG( ALPHA )*TEMP2
357
ELSE
358
C( I, J ) = BETA *C( I, J ) +
359
$ ALPHA*TEMP1 + CONJG( ALPHA )*TEMP2
360
END IF
361
END IF
362
230 CONTINUE
363
240 CONTINUE
364
END IF
365
END IF
366
*
367
RETURN
368
*
369
* End of CHER2K.
370
*
371
END
372
373