LAPACK  3.4.2
LAPACK: Linear Algebra PACKage
 All Files Functions Groups
dspgst.f
Go to the documentation of this file.
1 *> \brief \b DSPGST
2 *
3 * =========== DOCUMENTATION ===========
4 *
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
7 *
8 *> \htmlonly
9 *> Download DSPGST + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dspgst.f">
11 *> [TGZ]</a>
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dspgst.f">
13 *> [ZIP]</a>
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dspgst.f">
15 *> [TXT]</a>
16 *> \endhtmlonly
17 *
18 * Definition:
19 * ===========
20 *
21 * SUBROUTINE DSPGST( ITYPE, UPLO, N, AP, BP, INFO )
22 *
23 * .. Scalar Arguments ..
24 * CHARACTER UPLO
25 * INTEGER INFO, ITYPE, N
26 * ..
27 * .. Array Arguments ..
28 * DOUBLE PRECISION AP( * ), BP( * )
29 * ..
30 *
31 *
32 *> \par Purpose:
33 * =============
34 *>
35 *> \verbatim
36 *>
37 *> DSPGST reduces a real symmetric-definite generalized eigenproblem
38 *> to standard form, using packed storage.
39 *>
40 *> If ITYPE = 1, the problem is A*x = lambda*B*x,
41 *> and A is overwritten by inv(U**T)*A*inv(U) or inv(L)*A*inv(L**T)
42 *>
43 *> If ITYPE = 2 or 3, the problem is A*B*x = lambda*x or
44 *> B*A*x = lambda*x, and A is overwritten by U*A*U**T or L**T*A*L.
45 *>
46 *> B must have been previously factorized as U**T*U or L*L**T by DPPTRF.
47 *> \endverbatim
48 *
49 * Arguments:
50 * ==========
51 *
52 *> \param[in] ITYPE
53 *> \verbatim
54 *> ITYPE is INTEGER
55 *> = 1: compute inv(U**T)*A*inv(U) or inv(L)*A*inv(L**T);
56 *> = 2 or 3: compute U*A*U**T or L**T*A*L.
57 *> \endverbatim
58 *>
59 *> \param[in] UPLO
60 *> \verbatim
61 *> UPLO is CHARACTER*1
62 *> = 'U': Upper triangle of A is stored and B is factored as
63 *> U**T*U;
64 *> = 'L': Lower triangle of A is stored and B is factored as
65 *> L*L**T.
66 *> \endverbatim
67 *>
68 *> \param[in] N
69 *> \verbatim
70 *> N is INTEGER
71 *> The order of the matrices A and B. N >= 0.
72 *> \endverbatim
73 *>
74 *> \param[in,out] AP
75 *> \verbatim
76 *> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)
77 *> On entry, the upper or lower triangle of the symmetric matrix
78 *> A, packed columnwise in a linear array. The j-th column of A
79 *> is stored in the array AP as follows:
80 *> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;
81 *> if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.
82 *>
83 *> On exit, if INFO = 0, the transformed matrix, stored in the
84 *> same format as A.
85 *> \endverbatim
86 *>
87 *> \param[in] BP
88 *> \verbatim
89 *> BP is DOUBLE PRECISION array, dimension (N*(N+1)/2)
90 *> The triangular factor from the Cholesky factorization of B,
91 *> stored in the same format as A, as returned by DPPTRF.
92 *> \endverbatim
93 *>
94 *> \param[out] INFO
95 *> \verbatim
96 *> INFO is INTEGER
97 *> = 0: successful exit
98 *> < 0: if INFO = -i, the i-th argument had an illegal value
99 *> \endverbatim
100 *
101 * Authors:
102 * ========
103 *
104 *> \author Univ. of Tennessee
105 *> \author Univ. of California Berkeley
106 *> \author Univ. of Colorado Denver
107 *> \author NAG Ltd.
108 *
109 *> \date November 2011
110 *
111 *> \ingroup doubleOTHERcomputational
112 *
113 * =====================================================================
114  SUBROUTINE dspgst( ITYPE, UPLO, N, AP, BP, INFO )
115 *
116 * -- LAPACK computational routine (version 3.4.0) --
117 * -- LAPACK is a software package provided by Univ. of Tennessee, --
118 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
119 * November 2011
120 *
121 * .. Scalar Arguments ..
122  CHARACTER uplo
123  INTEGER info, itype, n
124 * ..
125 * .. Array Arguments ..
126  DOUBLE PRECISION ap( * ), bp( * )
127 * ..
128 *
129 * =====================================================================
130 *
131 * .. Parameters ..
132  DOUBLE PRECISION one, half
133  parameter( one = 1.0d0, half = 0.5d0 )
134 * ..
135 * .. Local Scalars ..
136  LOGICAL upper
137  INTEGER j, j1, j1j1, jj, k, k1, k1k1, kk
138  DOUBLE PRECISION ajj, akk, bjj, bkk, ct
139 * ..
140 * .. External Subroutines ..
141  EXTERNAL daxpy, dscal, dspmv, dspr2, dtpmv, dtpsv,
142  $ xerbla
143 * ..
144 * .. External Functions ..
145  LOGICAL lsame
146  DOUBLE PRECISION ddot
147  EXTERNAL lsame, ddot
148 * ..
149 * .. Executable Statements ..
150 *
151 * Test the input parameters.
152 *
153  info = 0
154  upper = lsame( uplo, 'U' )
155  IF( itype.LT.1 .OR. itype.GT.3 ) THEN
156  info = -1
157  ELSE IF( .NOT.upper .AND. .NOT.lsame( uplo, 'L' ) ) THEN
158  info = -2
159  ELSE IF( n.LT.0 ) THEN
160  info = -3
161  END IF
162  IF( info.NE.0 ) THEN
163  CALL xerbla( 'DSPGST', -info )
164  return
165  END IF
166 *
167  IF( itype.EQ.1 ) THEN
168  IF( upper ) THEN
169 *
170 * Compute inv(U**T)*A*inv(U)
171 *
172 * J1 and JJ are the indices of A(1,j) and A(j,j)
173 *
174  jj = 0
175  DO 10 j = 1, n
176  j1 = jj + 1
177  jj = jj + j
178 *
179 * Compute the j-th column of the upper triangle of A
180 *
181  bjj = bp( jj )
182  CALL dtpsv( uplo, 'Transpose', 'Nonunit', j, bp,
183  $ ap( j1 ), 1 )
184  CALL dspmv( uplo, j-1, -one, ap, bp( j1 ), 1, one,
185  $ ap( j1 ), 1 )
186  CALL dscal( j-1, one / bjj, ap( j1 ), 1 )
187  ap( jj ) = ( ap( jj )-ddot( j-1, ap( j1 ), 1, bp( j1 ),
188  $ 1 ) ) / bjj
189  10 continue
190  ELSE
191 *
192 * Compute inv(L)*A*inv(L**T)
193 *
194 * KK and K1K1 are the indices of A(k,k) and A(k+1,k+1)
195 *
196  kk = 1
197  DO 20 k = 1, n
198  k1k1 = kk + n - k + 1
199 *
200 * Update the lower triangle of A(k:n,k:n)
201 *
202  akk = ap( kk )
203  bkk = bp( kk )
204  akk = akk / bkk**2
205  ap( kk ) = akk
206  IF( k.LT.n ) THEN
207  CALL dscal( n-k, one / bkk, ap( kk+1 ), 1 )
208  ct = -half*akk
209  CALL daxpy( n-k, ct, bp( kk+1 ), 1, ap( kk+1 ), 1 )
210  CALL dspr2( uplo, n-k, -one, ap( kk+1 ), 1,
211  $ bp( kk+1 ), 1, ap( k1k1 ) )
212  CALL daxpy( n-k, ct, bp( kk+1 ), 1, ap( kk+1 ), 1 )
213  CALL dtpsv( uplo, 'No transpose', 'Non-unit', n-k,
214  $ bp( k1k1 ), ap( kk+1 ), 1 )
215  END IF
216  kk = k1k1
217  20 continue
218  END IF
219  ELSE
220  IF( upper ) THEN
221 *
222 * Compute U*A*U**T
223 *
224 * K1 and KK are the indices of A(1,k) and A(k,k)
225 *
226  kk = 0
227  DO 30 k = 1, n
228  k1 = kk + 1
229  kk = kk + k
230 *
231 * Update the upper triangle of A(1:k,1:k)
232 *
233  akk = ap( kk )
234  bkk = bp( kk )
235  CALL dtpmv( uplo, 'No transpose', 'Non-unit', k-1, bp,
236  $ ap( k1 ), 1 )
237  ct = half*akk
238  CALL daxpy( k-1, ct, bp( k1 ), 1, ap( k1 ), 1 )
239  CALL dspr2( uplo, k-1, one, ap( k1 ), 1, bp( k1 ), 1,
240  $ ap )
241  CALL daxpy( k-1, ct, bp( k1 ), 1, ap( k1 ), 1 )
242  CALL dscal( k-1, bkk, ap( k1 ), 1 )
243  ap( kk ) = akk*bkk**2
244  30 continue
245  ELSE
246 *
247 * Compute L**T *A*L
248 *
249 * JJ and J1J1 are the indices of A(j,j) and A(j+1,j+1)
250 *
251  jj = 1
252  DO 40 j = 1, n
253  j1j1 = jj + n - j + 1
254 *
255 * Compute the j-th column of the lower triangle of A
256 *
257  ajj = ap( jj )
258  bjj = bp( jj )
259  ap( jj ) = ajj*bjj + ddot( n-j, ap( jj+1 ), 1,
260  $ bp( jj+1 ), 1 )
261  CALL dscal( n-j, bjj, ap( jj+1 ), 1 )
262  CALL dspmv( uplo, n-j, one, ap( j1j1 ), bp( jj+1 ), 1,
263  $ one, ap( jj+1 ), 1 )
264  CALL dtpmv( uplo, 'Transpose', 'Non-unit', n-j+1,
265  $ bp( jj ), ap( jj ), 1 )
266  jj = j1j1
267  40 continue
268  END IF
269  END IF
270  return
271 *
272 * End of DSPGST
273 *
274  END