OpenRadioss 2025.1.11
OpenRadioss project
Loading...
Searching...
No Matches
csytrs.f
Go to the documentation of this file.
1*> \brief \b CSYTRS
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> \htmlonly
9*> Download CSYTRS + dependencies
10*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/csytrs.f">
11*> [TGZ]</a>
12*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/csytrs.f">
13*> [ZIP]</a>
14*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/csytrs.f">
15*> [TXT]</a>
16*> \endhtmlonly
17*
18* Definition:
19* ===========
20*
21* SUBROUTINE CSYTRS( UPLO, N, NRHS, A, LDA, IPIV, B, LDB, INFO )
22*
23* .. Scalar Arguments ..
24* CHARACTER UPLO
25* INTEGER INFO, LDA, LDB, N, NRHS
26* ..
27* .. Array Arguments ..
28* INTEGER IPIV( * )
29* COMPLEX A( LDA, * ), B( LDB, * )
30* ..
31*
32*
33*> \par Purpose:
34* =============
35*>
36*> \verbatim
37*>
38*> CSYTRS solves a system of linear equations A*X = B with a complex
39*> symmetric matrix A using the factorization A = U*D*U**T or
40*> A = L*D*L**T computed by CSYTRF.
41*> \endverbatim
42*
43* Arguments:
44* ==========
45*
46*> \param[in] UPLO
47*> \verbatim
48*> UPLO is CHARACTER*1
49*> Specifies whether the details of the factorization are stored
50*> as an upper or lower triangular matrix.
51*> = 'U': Upper triangular, form is A = U*D*U**T;
52*> = 'L': Lower triangular, form is A = L*D*L**T.
53*> \endverbatim
54*>
55*> \param[in] N
56*> \verbatim
57*> N is INTEGER
58*> The order of the matrix A. N >= 0.
59*> \endverbatim
60*>
61*> \param[in] NRHS
62*> \verbatim
63*> NRHS is INTEGER
64*> The number of right hand sides, i.e., the number of columns
65*> of the matrix B. NRHS >= 0.
66*> \endverbatim
67*>
68*> \param[in] A
69*> \verbatim
70*> A is COMPLEX array, dimension (LDA,N)
71*> The block diagonal matrix D and the multipliers used to
72*> obtain the factor U or L as computed by CSYTRF.
73*> \endverbatim
74*>
75*> \param[in] LDA
76*> \verbatim
77*> LDA is INTEGER
78*> The leading dimension of the array A. LDA >= max(1,N).
79*> \endverbatim
80*>
81*> \param[in] IPIV
82*> \verbatim
83*> IPIV is INTEGER array, dimension (N)
84*> Details of the interchanges and the block structure of D
85*> as determined by CSYTRF.
86*> \endverbatim
87*>
88*> \param[in,out] B
89*> \verbatim
90*> B is COMPLEX array, dimension (LDB,NRHS)
91*> On entry, the right hand side matrix B.
92*> On exit, the solution matrix X.
93*> \endverbatim
94*>
95*> \param[in] LDB
96*> \verbatim
97*> LDB is INTEGER
98*> The leading dimension of the array B. LDB >= max(1,N).
99*> \endverbatim
100*>
101*> \param[out] INFO
102*> \verbatim
103*> INFO is INTEGER
104*> = 0: successful exit
105*> < 0: if INFO = -i, the i-th argument had an illegal value
106*> \endverbatim
107*
108* Authors:
109* ========
110*
111*> \author Univ. of Tennessee
112*> \author Univ. of California Berkeley
113*> \author Univ. of Colorado Denver
114*> \author NAG Ltd.
115*
116*> \ingroup complexSYcomputational
117*
118* =====================================================================
119 SUBROUTINE csytrs( UPLO, N, NRHS, A, LDA, IPIV, B, LDB, INFO )
120*
121* -- LAPACK computational routine --
122* -- LAPACK is a software package provided by Univ. of Tennessee, --
123* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
124*
125* .. Scalar Arguments ..
126 CHARACTER UPLO
127 INTEGER INFO, LDA, LDB, N, NRHS
128* ..
129* .. Array Arguments ..
130 INTEGER IPIV( * )
131 COMPLEX A( LDA, * ), B( LDB, * )
132* ..
133*
134* =====================================================================
135*
136* .. Parameters ..
137 COMPLEX ONE
138 parameter( one = ( 1.0e+0, 0.0e+0 ) )
139* ..
140* .. Local Scalars ..
141 LOGICAL UPPER
142 INTEGER J, K, KP
143 COMPLEX AK, AKM1, AKM1K, BK, BKM1, DENOM
144* ..
145* .. External Functions ..
146 LOGICAL LSAME
147 EXTERNAL lsame
148* ..
149* .. External Subroutines ..
150 EXTERNAL cgemv, cgeru, cscal, cswap, xerbla
151* ..
152* .. Intrinsic Functions ..
153 INTRINSIC max
154* ..
155* .. Executable Statements ..
156*
157 info = 0
158 upper = lsame( uplo, 'U' )
159 IF( .NOT.upper .AND. .NOT.lsame( uplo, 'l' ) ) THEN
160 INFO = -1
161.LT. ELSE IF( N0 ) THEN
162 INFO = -2
163.LT. ELSE IF( NRHS0 ) THEN
164 INFO = -3
165.LT. ELSE IF( LDAMAX( 1, N ) ) THEN
166 INFO = -5
167.LT. ELSE IF( LDBMAX( 1, N ) ) THEN
168 INFO = -8
169 END IF
170.NE. IF( INFO0 ) THEN
171 CALL XERBLA( 'csytrs', -INFO )
172 RETURN
173 END IF
174*
175* Quick return if possible
176*
177.EQ..OR..EQ. IF( N0 NRHS0 )
178 $ RETURN
179*
180 IF( UPPER ) THEN
181*
182* Solve A*X = B, where A = U*D*U**T.
183*
184* First solve U*D*X = B, overwriting B with X.
185*
186* K is the main loop index, decreasing from N to 1 in steps of
187* 1 or 2, depending on the size of the diagonal blocks.
188*
189 K = N
190 10 CONTINUE
191*
192* If K < 1, exit from loop.
193*
194.LT. IF( K1 )
195 $ GO TO 30
196*
197.GT. IF( IPIV( K )0 ) THEN
198*
199* 1 x 1 diagonal block
200*
201* Interchange rows K and IPIV(K).
202*
203 KP = IPIV( K )
204.NE. IF( KPK )
205 $ CALL CSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
206*
207* Multiply by inv(U(K)), where U(K) is the transformation
208* stored in column K of A.
209*
210 CALL CGERU( K-1, NRHS, -ONE, A( 1, K ), 1, B( K, 1 ), LDB,
211 $ B( 1, 1 ), LDB )
212*
213* Multiply by the inverse of the diagonal block.
214*
215 CALL CSCAL( NRHS, ONE / A( K, K ), B( K, 1 ), LDB )
216 K = K - 1
217 ELSE
218*
219* 2 x 2 diagonal block
220*
221* Interchange rows K-1 and -IPIV(K).
222*
223 KP = -IPIV( K )
224.NE. IF( KPK-1 )
225 $ CALL CSWAP( NRHS, B( K-1, 1 ), LDB, B( KP, 1 ), LDB )
226*
227* Multiply by inv(U(K)), where U(K) is the transformation
228* stored in columns K-1 and K of A.
229*
230 CALL CGERU( K-2, NRHS, -ONE, A( 1, K ), 1, B( K, 1 ), LDB,
231 $ B( 1, 1 ), LDB )
232 CALL CGERU( K-2, NRHS, -ONE, A( 1, K-1 ), 1, B( K-1, 1 ),
233 $ LDB, B( 1, 1 ), LDB )
234*
235* Multiply by the inverse of the diagonal block.
236*
237 AKM1K = A( K-1, K )
238 AKM1 = A( K-1, K-1 ) / AKM1K
239 AK = A( K, K ) / AKM1K
240 DENOM = AKM1*AK - ONE
241 DO 20 J = 1, NRHS
242 BKM1 = B( K-1, J ) / AKM1K
243 BK = B( K, J ) / AKM1K
244 B( K-1, J ) = ( AK*BKM1-BK ) / DENOM
245 B( K, J ) = ( AKM1*BK-BKM1 ) / DENOM
246 20 CONTINUE
247 K = K - 2
248 END IF
249*
250 GO TO 10
251 30 CONTINUE
252*
253* Next solve U**T *X = B, overwriting B with X.
254*
255* K is the main loop index, increasing from 1 to N in steps of
256* 1 or 2, depending on the size of the diagonal blocks.
257*
258 K = 1
259 40 CONTINUE
260*
261* If K > N, exit from loop.
262*
263.GT. IF( KN )
264 $ GO TO 50
265*
266.GT. IF( IPIV( K )0 ) THEN
267*
268* 1 x 1 diagonal block
269*
270* Multiply by inv(U**T(K)), where U(K) is the transformation
271* stored in column K of A.
272*
273 CALL CGEMV( 'transpose', K-1, NRHS, -ONE, B, LDB, A( 1, K ),
274 $ 1, ONE, B( K, 1 ), LDB )
275*
276* Interchange rows K and IPIV(K).
277*
278 KP = IPIV( K )
279.NE. IF( KPK )
280 $ CALL CSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
281 K = K + 1
282 ELSE
283*
284* 2 x 2 diagonal block
285*
286* Multiply by inv(U**T(K+1)), where U(K+1) is the transformation
287* stored in columns K and K+1 of A.
288*
289 CALL CGEMV( 'transpose', K-1, NRHS, -ONE, B, LDB, A( 1, K ),
290 $ 1, ONE, B( K, 1 ), LDB )
291 CALL CGEMV( 'transpose', K-1, NRHS, -ONE, B, LDB,
292 $ A( 1, K+1 ), 1, ONE, B( K+1, 1 ), LDB )
293*
294* Interchange rows K and -IPIV(K).
295*
296 KP = -IPIV( K )
297.NE. IF( KPK )
298 $ CALL CSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
299 K = K + 2
300 END IF
301*
302 GO TO 40
303 50 CONTINUE
304*
305 ELSE
306*
307* Solve A*X = B, where A = L*D*L**T.
308*
309* First solve L*D*X = B, overwriting B with X.
310*
311* K is the main loop index, increasing from 1 to N in steps of
312* 1 or 2, depending on the size of the diagonal blocks.
313*
314 K = 1
315 60 CONTINUE
316*
317* If K > N, exit from loop.
318*
319.GT. IF( KN )
320 $ GO TO 80
321*
322.GT. IF( IPIV( K )0 ) THEN
323*
324* 1 x 1 diagonal block
325*
326* Interchange rows K and IPIV(K).
327*
328 KP = IPIV( K )
329.NE. IF( KPK )
330 $ CALL CSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
331*
332* Multiply by inv(L(K)), where L(K) is the transformation
333* stored in column K of A.
334*
335.LT. IF( KN )
336 $ CALL CGERU( N-K, NRHS, -ONE, A( K+1, K ), 1, B( K, 1 ),
337 $ LDB, B( K+1, 1 ), LDB )
338*
339* Multiply by the inverse of the diagonal block.
340*
341 CALL CSCAL( NRHS, ONE / A( K, K ), B( K, 1 ), LDB )
342 K = K + 1
343 ELSE
344*
345* 2 x 2 diagonal block
346*
347* Interchange rows K+1 and -IPIV(K).
348*
349 KP = -IPIV( K )
350.NE. IF( KPK+1 )
351 $ CALL CSWAP( NRHS, B( K+1, 1 ), LDB, B( KP, 1 ), LDB )
352*
353* Multiply by inv(L(K)), where L(K) is the transformation
354* stored in columns K and K+1 of A.
355*
356.LT. IF( KN-1 ) THEN
357 CALL CGERU( N-K-1, NRHS, -ONE, A( K+2, K ), 1, B( K, 1 ),
358 $ LDB, B( K+2, 1 ), LDB )
359 CALL CGERU( N-K-1, NRHS, -ONE, A( K+2, K+1 ), 1,
360 $ B( K+1, 1 ), LDB, B( K+2, 1 ), LDB )
361 END IF
362*
363* Multiply by the inverse of the diagonal block.
364*
365 AKM1K = A( K+1, K )
366 AKM1 = A( K, K ) / AKM1K
367 AK = A( K+1, K+1 ) / AKM1K
368 DENOM = AKM1*AK - ONE
369 DO 70 J = 1, NRHS
370 BKM1 = B( K, J ) / AKM1K
371 BK = B( K+1, J ) / AKM1K
372 B( K, J ) = ( AK*BKM1-BK ) / DENOM
373 B( K+1, J ) = ( AKM1*BK-BKM1 ) / DENOM
374 70 CONTINUE
375 K = K + 2
376 END IF
377*
378 GO TO 60
379 80 CONTINUE
380*
381* Next solve L**T *X = B, overwriting B with X.
382*
383* K is the main loop index, decreasing from N to 1 in steps of
384* 1 or 2, depending on the size of the diagonal blocks.
385*
386 K = N
387 90 CONTINUE
388*
389* If K < 1, exit from loop.
390*
391.LT. IF( K1 )
392 $ GO TO 100
393*
394.GT. IF( IPIV( K )0 ) THEN
395*
396* 1 x 1 diagonal block
397*
398* Multiply by inv(L**T(K)), where L(K) is the transformation
399* stored in column K of A.
400*
401.LT. IF( KN )
402 $ CALL CGEMV( 'transpose', N-K, NRHS, -ONE, B( K+1, 1 ),
403 $ LDB, A( K+1, K ), 1, ONE, B( K, 1 ), LDB )
404*
405* Interchange rows K and IPIV(K).
406*
407 KP = IPIV( K )
408.NE. IF( KPK )
409 $ CALL CSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
410 K = K - 1
411 ELSE
412*
413* 2 x 2 diagonal block
414*
415* Multiply by inv(L**T(K-1)), where L(K-1) is the transformation
416* stored in columns K-1 and K of A.
417*
418.LT. IF( KN ) THEN
419 CALL CGEMV( 'transpose', N-K, NRHS, -ONE, B( K+1, 1 ),
420 $ LDB, A( K+1, K ), 1, ONE, B( K, 1 ), LDB )
421 CALL CGEMV( 'transpose', N-K, NRHS, -ONE, B( K+1, 1 ),
422 $ LDB, A( K+1, K-1 ), 1, ONE, B( K-1, 1 ),
423 $ LDB )
424 END IF
425*
426* Interchange rows K and -IPIV(K).
427*
428 KP = -IPIV( K )
429.NE. IF( KPK )
430 $ CALL CSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
431 K = K - 2
432 END IF
433*
434 GO TO 90
435 100 CONTINUE
436 END IF
437*
438 RETURN
439*
440* End of CSYTRS
441*
442 END
subroutine xerbla(srname, info)
XERBLA
Definition xerbla.f:60
subroutine csytrs(uplo, n, nrhs, a, lda, ipiv, b, ldb, info)
CSYTRS
Definition csytrs.f:120
subroutine cswap(n, cx, incx, cy, incy)
CSWAP
Definition cswap.f:81
subroutine cscal(n, ca, cx, incx)
CSCAL
Definition cscal.f:78
subroutine cgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
CGEMV
Definition cgemv.f:158
subroutine cgeru(m, n, alpha, x, incx, y, incy, a, lda)
CGERU
Definition cgeru.f:130
#define max(a, b)
Definition macros.h:21