3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
9 *> Download SORBDB4 + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/sorbdb4.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/sorbdb4.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/sorbdb4.f">
21 * SUBROUTINE SORBDB4( M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI,
22 * TAUP1, TAUP2, TAUQ1, PHANTOM, WORK, LWORK,
25 * .. Scalar Arguments ..
26 * INTEGER INFO, LWORK, M, P, Q, LDX11, LDX21
28 * .. Array Arguments ..
29 * REAL PHI(*), THETA(*)
30 * REAL PHANTOM(*), TAUP1(*), TAUP2(*), TAUQ1(*),
31 * $ WORK(*), X11(LDX11,*), X21(LDX21,*)
40 *> SORBDB4 simultaneously bidiagonalizes the blocks of a tall and skinny
41 *> matrix X with orthonomal columns:
44 *> [ X11 ] [ P1 | ] [ 0 ]
45 *> [-----] = [---------] [-----] Q1**T .
46 *> [ X21 ] [ | P2 ] [ B21 ]
49 *> X11 is P-by-Q, and X21 is (M-P)-by-Q. M-Q must be no larger than P,
50 *> M-P, or Q. Routines SORBDB1, SORBDB2, and SORBDB3 handle cases in
51 *> which M-Q is not the minimum dimension.
53 *> The orthogonal matrices P1, P2, and Q1 are P-by-P, (M-P)-by-(M-P),
54 *> and (M-Q)-by-(M-Q), respectively. They are represented implicitly by
55 *> Householder vectors.
57 *> B11 and B12 are (M-Q)-by-(M-Q) bidiagonal matrices represented
58 *> implicitly by angles THETA, PHI.
68 *> The number of rows X11 plus the number of rows in X21.
74 *> The number of rows in X11. 0 <= P <= M.
80 *> The number of columns in X11 and X21. 0 <= Q <= M and
81 *> M-Q <= min(P,M-P,Q).
86 *> X11 is REAL array, dimension (LDX11,Q)
87 *> On entry, the top block of the matrix X to be reduced. On
88 *> exit, the columns of tril(X11) specify reflectors for P1 and
89 *> the rows of triu(X11,1) specify reflectors for Q1.
95 *> The leading dimension of X11. LDX11 >= P.
100 *> X21 is REAL array, dimension (LDX21,Q)
101 *> On entry, the bottom block of the matrix X to be reduced. On
102 *> exit, the columns of tril(X21) specify reflectors for P2.
108 *> The leading dimension of X21. LDX21 >= M-P.
113 *> THETA is REAL array, dimension (Q)
114 *> The entries of the bidiagonal blocks B11, B21 are defined by
115 *> THETA and PHI. See Further Details.
120 *> PHI is REAL array, dimension (Q-1)
121 *> The entries of the bidiagonal blocks B11, B21 are defined by
122 *> THETA and PHI. See Further Details.
127 *> TAUP1 is REAL array, dimension (P)
128 *> The scalar factors of the elementary reflectors that define
134 *> TAUP2 is REAL array, dimension (M-P)
135 *> The scalar factors of the elementary reflectors that define
141 *> TAUQ1 is REAL array, dimension (Q)
142 *> The scalar factors of the elementary reflectors that define
146 *> \param[out] PHANTOM
148 *> PHANTOM is REAL array, dimension (M)
149 *> The routine computes an M-by-1 column vector Y that is
150 *> orthogonal to the columns of [ X11; X21 ]. PHANTOM(1:P) and
151 *> PHANTOM(P+1:M) contain Householder vectors for Y(1:P) and
152 *> Y(P+1:M), respectively.
157 *> WORK is REAL array, dimension (LWORK)
163 *> The dimension of the array WORK. LWORK >= M-Q.
165 *> If LWORK = -1, then a workspace query is assumed; the routine
166 *> only calculates the optimal size of the WORK array, returns
167 *> this value as the first entry of the WORK array, and no error
168 *> message related to LWORK is issued by XERBLA.
174 *> = 0: successful exit.
175 *> < 0: if INFO = -i, the i-th argument had an illegal value.
182 *> \author Univ. of Tennessee
183 *> \author Univ. of California Berkeley
184 *> \author Univ. of Colorado Denver
189 *> \ingroup realOTHERcomputational
191 *> \par Further Details:
192 * =====================
196 *> The upper-bidiagonal blocks B11, B21 are represented implicitly by
197 *> angles THETA(1), ..., THETA(Q) and PHI(1), ..., PHI(Q-1). Every entry
198 *> in each bidiagonal band is a product of a sine or cosine of a THETA
199 *> with a sine or cosine of a PHI. See [1] or SORCSD for details.
201 *> P1, P2, and Q1 are represented as products of elementary reflectors.
202 *> See SORCSD2BY1 for details on generating P1, P2, and Q1 using SORGQR
209 *> [1] Brian D. Sutton. Computing the complete CS decomposition. Numer.
210 *> Algorithms, 50(1):33-65, 2009.
212 * =====================================================================
213 SUBROUTINE SORBDB4( M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI,
214 $ TAUP1, TAUP2, TAUQ1, PHANTOM, WORK, LWORK,
217 * -- LAPACK computational routine (version 3.6.1) --
218 * -- LAPACK is a software package provided by Univ. of Tennessee, --
219 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
222 * .. Scalar Arguments ..
223 INTEGER INFO, LWORK, M, P, Q, LDX11, LDX21
225 * .. Array Arguments ..
226 REAL PHI(*), THETA(*)
227 REAL PHANTOM(*), TAUP1(*), TAUP2(*), TAUQ1(*),
228 $ WORK(*), X11(LDX11,*), X21(LDX21,*)
231 * ====================================================================
234 REAL NEGONE, ONE, ZERO
235 PARAMETER ( NEGONE = -1.0E0, ONE = 1.0E0, ZERO = 0.0E0 )
237 * .. Local Scalars ..
239 INTEGER CHILDINFO, I, ILARF, IORBDB5, J, LLARF,
240 $ LORBDB5, LWORKMIN, LWORKOPT
243 * .. External Subroutines ..
244 EXTERNAL SLARF, SLARFGP, SORBDB5, SROT, SSCAL, XERBLA
246 * .. External Functions ..
250 * .. Intrinsic Function ..
251 INTRINSIC ATAN2, COS, MAX, SIN, SQRT
253 * .. Executable Statements ..
255 * Test input arguments
258 LQUERY = LWORK .EQ. -1
262 ELSE IF( P .LT. M-Q .OR. M-P .LT. M-Q ) THEN
264 ELSE IF( Q .LT. M-Q .OR. Q .GT. M ) THEN
266 ELSE IF( LDX11 .LT. MAX( 1, P ) ) THEN
268 ELSE IF( LDX21 .LT. MAX( 1, M-P ) ) THEN
274 IF( INFO .EQ. 0 ) THEN
276 LLARF = MAX( Q-1, P-1, M-P-1 )
279 LWORKOPT = ILARF + LLARF - 1
280 LWORKOPT = MAX( LWORKOPT, IORBDB5 + LORBDB5 - 1 )
283 IF( LWORK .LT. LWORKMIN .AND. .NOT.LQUERY ) THEN
287 IF( INFO .NE. 0 ) THEN
288 CALL XERBLA( 'SORBDB4', -INFO )
290 ELSE IF( LQUERY ) THEN
294 * Reduce columns 1, ..., M-Q of X11 and X21
302 CALL SORBDB5( P, M-P, Q, PHANTOM(1), 1, PHANTOM(P+1), 1,
303 $ X11, LDX11, X21, LDX21, WORK(IORBDB5),
304 $ LORBDB5, CHILDINFO )
305 CALL SSCAL( P, NEGONE, PHANTOM(1), 1 )
306 CALL SLARFGP( P, PHANTOM(1), PHANTOM(2), 1, TAUP1(1) )
307 CALL SLARFGP( M-P, PHANTOM(P+1), PHANTOM(P+2), 1, TAUP2(1) )
308 THETA(I) = ATAN2( PHANTOM(1), PHANTOM(P+1) )
313 CALL SLARF( 'L', P, Q, PHANTOM(1), 1, TAUP1(1), X11, LDX11,
315 CALL SLARF( 'L', M-P, Q, PHANTOM(P+1), 1, TAUP2(1), X21,
316 $ LDX21, WORK(ILARF) )
318 CALL SORBDB5( P-I+1, M-P-I+1, Q-I+1, X11(I,I-1), 1,
319 $ X21(I,I-1), 1, X11(I,I), LDX11, X21(I,I),
320 $ LDX21, WORK(IORBDB5), LORBDB5, CHILDINFO )
321 CALL SSCAL( P-I+1, NEGONE, X11(I,I-1), 1 )
322 CALL SLARFGP( P-I+1, X11(I,I-1), X11(I+1,I-1), 1, TAUP1(I) )
323 CALL SLARFGP( M-P-I+1, X21(I,I-1), X21(I+1,I-1), 1,
325 THETA(I) = ATAN2( X11(I,I-1), X21(I,I-1) )
330 CALL SLARF( 'L', P-I+1, Q-I+1, X11(I,I-1), 1, TAUP1(I),
331 $ X11(I,I), LDX11, WORK(ILARF) )
332 CALL SLARF( 'L', M-P-I+1, Q-I+1, X21(I,I-1), 1, TAUP2(I),
333 $ X21(I,I), LDX21, WORK(ILARF) )
336 CALL SROT( Q-I+1, X11(I,I), LDX11, X21(I,I), LDX21, S, -C )
337 CALL SLARFGP( Q-I+1, X21(I,I), X21(I,I+1), LDX21, TAUQ1(I) )
340 CALL SLARF( 'R', P-I, Q-I+1, X21(I,I), LDX21, TAUQ1(I),
341 $ X11(I+1,I), LDX11, WORK(ILARF) )
342 CALL SLARF( 'R', M-P-I, Q-I+1, X21(I,I), LDX21, TAUQ1(I),
343 $ X21(I+1,I), LDX21, WORK(ILARF) )
344 IF( I .LT. M-Q ) THEN
345 S = SQRT( SNRM2( P-I, X11(I+1,I), 1 )**2
346 $ + SNRM2( M-P-I, X21(I+1,I), 1 )**2 )
347 PHI(I) = ATAN2( S, C )
352 * Reduce the bottom-right portion of X11 to [ I 0 ]
355 CALL SLARFGP( Q-I+1, X11(I,I), X11(I,I+1), LDX11, TAUQ1(I) )
357 CALL SLARF( 'R', P-I, Q-I+1, X11(I,I), LDX11, TAUQ1(I),
358 $ X11(I+1,I), LDX11, WORK(ILARF) )
359 CALL SLARF( 'R', Q-P, Q-I+1, X11(I,I), LDX11, TAUQ1(I),
360 $ X21(M-Q+1,I), LDX21, WORK(ILARF) )
363 * Reduce the bottom-right portion of X21 to [ 0 I ]
366 CALL SLARFGP( Q-I+1, X21(M-Q+I-P,I), X21(M-Q+I-P,I+1), LDX21,
369 CALL SLARF( 'R', Q-I, Q-I+1, X21(M-Q+I-P,I), LDX21, TAUQ1(I),
370 $ X21(M-Q+I-P+1,I), LDX21, WORK(ILARF) )