Aasen sv and trs in LAPACKE
[platform/upstream/lapack.git] / SRC / ssytrs_aa.f
1 *> \brief \b SSYTRS_AA
2 *
3 *  =========== DOCUMENTATION ===========
4 *
5 * Online html documentation available at
6 *            http://www.netlib.org/lapack/explore-html/
7 *
8 *> \htmlonly
9 *> Download SSYTRS_AA + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ssytrs_aa.f">
11 *> [TGZ]</a>
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ssytrs_aa.f">
13 *> [ZIP]</a>
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ssytrs_aa.f">
15 *> [TXT]</a>
16 *> \endhtmlonly
17 *
18 *  Definition:
19 *  ===========
20 *
21 *       SUBROUTINE SSYTRS_AA( UPLO, N, NRHS, A, LDA, IPIV, B, LDB,
22 *                                WORK, LWORK, INFO )
23 *
24 *       .. Scalar Arguments ..
25 *       CHARACTER          UPLO
26 *       INTEGER            N, NRHS, LDA, LDB, LWORK, INFO
27 *       ..
28 *       .. Array Arguments ..
29 *       INTEGER            IPIV( * )
30 *       REAL   A( LDA, * ), B( LDB, * ), WORK( * )
31 *       ..
32
33 *
34 *> \par Purpose:
35 *  =============
36 *>
37 *> \verbatim
38 *>
39 *> SSYTRS_AA solves a system of linear equations A*X = B with a real
40 *> symmetric matrix A using the factorization A = U*T*U**T or
41 *> A = L*T*L**T computed by SSYTRF_AA.
42 *> \endverbatim
43 *
44 *  Arguments:
45 *  ==========
46 *
47 *> \param[in] UPLO
48 *> \verbatim
49 *>          UPLO is CHARACTER*1
50 *>          Specifies whether the details of the factorization are stored
51 *>          as an upper or lower triangular matrix.
52 *>          = 'U':  Upper triangular, form is A = U*T*U**T;
53 *>          = 'L':  Lower triangular, form is A = L*T*L**T.
54 *> \endverbatim
55 *>
56 *> \param[in] N
57 *> \verbatim
58 *>          N is INTEGER
59 *>          The order of the matrix A.  N >= 0.
60 *> \endverbatim
61 *>
62 *> \param[in] NRHS
63 *> \verbatim
64 *>          NRHS is INTEGER
65 *>          The number of right hand sides, i.e., the number of columns
66 *>          of the matrix B.  NRHS >= 0.
67 *> \endverbatim
68 *>
69 *> \param[in,out] A
70 *> \verbatim
71 *>          A is REAL array, dimension (LDA,N)
72 *>          Details of factors computed by SSYTRF_AA.
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 as computed by SSYTRF_AA.
85 *> \endverbatim
86 *>
87 *> \param[in,out] B
88 *> \verbatim
89 *>          B is REAL array, dimension (LDB,NRHS)
90 *>          On entry, the right hand side matrix B.
91 *>          On exit, the solution matrix X.
92 *> \endverbatim
93 *>
94 *> \param[in] LDB
95 *> \verbatim
96 *>          LDB is INTEGER
97 *>          The leading dimension of the array B.  LDB >= max(1,N).
98 *> \endverbatim
99 *>
100 *> \param[in] WORK
101 *> \verbatim
102 *>          WORK is DOUBLE array, dimension (MAX(1,LWORK))
103 *> \endverbatim
104 *>
105 *> \param[in] LWORK
106 *> \verbatim
107 *>          LWORK is INTEGER, LWORK >= 3*N-2.
108 *>
109 *> \param[out] INFO
110 *> \verbatim
111 *>          INFO is INTEGER
112 *>          = 0:  successful exit
113 *>          < 0:  if INFO = -i, the i-th argument had an illegal value
114 *> \endverbatim
115 *
116 *  Authors:
117 *  ========
118 *
119 *> \author Univ. of Tennessee
120 *> \author Univ. of California Berkeley
121 *> \author Univ. of Colorado Denver
122 *> \author NAG Ltd.
123 *
124 *> \date November 2016
125 *
126 *> \ingroup realSYcomputational
127 *
128 *  =====================================================================
129       SUBROUTINE SSYTRS_AA( UPLO, N, NRHS, A, LDA, IPIV, B, LDB,
130      $                         WORK, LWORK, INFO )
131 *
132 *  -- LAPACK computational routine (version 3.7.0) --
133 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
134 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
135 *     November 2016
136 *
137       IMPLICIT NONE
138 *
139 *     .. Scalar Arguments ..
140       CHARACTER          UPLO
141       INTEGER            N, NRHS, LDA, LDB, LWORK, INFO
142 *     ..
143 *     .. Array Arguments ..
144       INTEGER            IPIV( * )
145       REAL   A( LDA, * ), B( LDB, * ), WORK( * )
146 *     ..
147 *
148 *  =====================================================================
149 *
150       REAL               ONE
151       PARAMETER          ( ONE = 1.0E+0 )
152 *     ..
153 *     .. Local Scalars ..
154       LOGICAL            LQUERY, UPPER
155       INTEGER            K, KP, LWKOPT
156 *     ..
157 *     .. External Functions ..
158       LOGICAL            LSAME
159       EXTERNAL           LSAME
160 *     ..
161 *     .. External Subroutines ..
162       EXTERNAL           SGTSV, SSWAP, STRSM, XERBLA
163 *     ..
164 *     .. Intrinsic Functions ..
165       INTRINSIC          MAX
166 *     ..
167 *     .. Executable Statements ..
168 *
169       INFO = 0
170       UPPER = LSAME( UPLO, 'U' )
171       LQUERY = ( LWORK.EQ.-1 )
172       IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
173          INFO = -1
174       ELSE IF( N.LT.0 ) THEN
175          INFO = -2
176       ELSE IF( NRHS.LT.0 ) THEN
177          INFO = -3
178       ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
179          INFO = -5
180       ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
181          INFO = -8
182       ELSE IF( LWORK.LT.(3*N-2) .AND. .NOT.LQUERY ) THEN
183          INFO = -10
184       END IF
185       IF( INFO.NE.0 ) THEN
186          CALL XERBLA( 'SSYTRS_AA', -INFO )
187          RETURN
188       ELSE IF( LQUERY ) THEN
189          LWKOPT = (3*N-2)
190          WORK( 1 ) = LWKOPT
191          RETURN
192       END IF
193 *
194 *     Quick return if possible
195 *
196       IF( N.EQ.0 .OR. NRHS.EQ.0 )
197      $   RETURN
198 *
199       IF( UPPER ) THEN
200 *
201 *        Solve A*X = B, where A = U*T*U**T.
202 *
203 *        Pivot, P**T * B
204 *
205          K = 1
206          DO WHILE ( K.LE.N )
207             KP = IPIV( K )
208             IF( KP.NE.K )
209      $          CALL SSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
210             K = K + 1
211          END DO
212 *
213 *        Compute (U \P**T * B) -> B    [ (U \P**T * B) ]
214 *
215          CALL STRSM('L', 'U', 'T', 'U', N-1, NRHS, ONE, A( 1, 2 ), LDA,
216      $               B( 2, 1 ), LDB)
217 *
218 *        Compute T \ B -> B   [ T \ (U \P**T * B) ]
219 *
220          CALL SLACPY( 'F', 1, N, A(1, 1), LDA+1, WORK(N), 1)
221          IF( N.GT.1 ) THEN
222              CALL SLACPY( 'F', 1, N-1, A(1, 2), LDA+1, WORK(1), 1)
223              CALL SLACPY( 'F', 1, N-1, A(1, 2), LDA+1, WORK(2*N), 1)
224          END IF
225          CALL SGTSV(N, NRHS, WORK(1), WORK(N), WORK(2*N), B, LDB,
226      $              INFO)
227 *      
228 *
229 *        Compute (U**T \ B) -> B   [ U**T \ (T \ (U \P**T * B) ) ]
230 *
231          CALL STRSM( 'L', 'U', 'N', 'U', N-1, NRHS, ONE, A( 1, 2 ), LDA,
232      $               B(2, 1), LDB)
233 *
234 *        Pivot, P * B  [ P * (U**T \ (T \ (U \P**T * B) )) ]
235 *
236          K = N
237          DO WHILE ( K.GE.1 )
238             KP = IPIV( K )
239             IF( KP.NE.K )
240      $         CALL SSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
241             K = K - 1
242          END DO
243 *
244       ELSE
245 *
246 *        Solve A*X = B, where A = L*T*L**T.
247 *
248 *        Pivot, P**T * B
249 *
250          K = 1
251          DO WHILE ( K.LE.N )
252             KP = IPIV( K )
253             IF( KP.NE.K )
254      $         CALL SSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
255             K = K + 1
256          END DO
257 *
258 *        Compute (L \P**T * B) -> B    [ (L \P**T * B) ]
259 *
260          CALL STRSM( 'L', 'L', 'N', 'U', N-1, NRHS, ONE, A( 2, 1), LDA,
261      $               B(2, 1), LDB)
262 *
263 *        Compute T \ B -> B   [ T \ (L \P**T * B) ]
264 *
265          CALL SLACPY( 'F', 1, N, A(1, 1), LDA+1, WORK(N), 1)
266          IF( N.GT.1 ) THEN
267              CALL SLACPY( 'F', 1, N-1, A(2, 1), LDA+1, WORK(1), 1)
268              CALL SLACPY( 'F', 1, N-1, A(2, 1), LDA+1, WORK(2*N), 1)
269          END IF
270          CALL SGTSV(N, NRHS, WORK(1), WORK(N), WORK(2*N), B, LDB,
271      $              INFO)
272 *
273 *        Compute (L**T \ B) -> B   [ L**T \ (T \ (L \P**T * B) ) ]
274 *
275          CALL STRSM( 'L', 'L', 'T', 'U', N-1, NRHS, ONE, A( 2, 1 ), LDA,
276      $              B( 2, 1 ), LDB)
277 *
278 *        Pivot, P * B  [ P * (L**T \ (T \ (L \P**T * B) )) ]
279 *
280          K = N
281          DO WHILE ( K.GE.1 )
282             KP = IPIV( K )
283             IF( KP.NE.K )
284      $         CALL SSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )
285             K = K - 1
286          END DO
287 *
288       END IF
289 *
290       RETURN
291 *
292 *     End of SSYTRS_AA
293 *
294       END