LAPACK  3.4.2
LAPACK: Linear Algebra PACKage
 All Files Functions Groups
dgbbrd.f
Go to the documentation of this file.
1 *> \brief \b DGBBRD
2 *
3 * =========== DOCUMENTATION ===========
4 *
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
7 *
8 *> \htmlonly
9 *> Download DGBBRD + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgbbrd.f">
11 *> [TGZ]</a>
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgbbrd.f">
13 *> [ZIP]</a>
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgbbrd.f">
15 *> [TXT]</a>
16 *> \endhtmlonly
17 *
18 * Definition:
19 * ===========
20 *
21 * SUBROUTINE DGBBRD( VECT, M, N, NCC, KL, KU, AB, LDAB, D, E, Q,
22 * LDQ, PT, LDPT, C, LDC, WORK, INFO )
23 *
24 * .. Scalar Arguments ..
25 * CHARACTER VECT
26 * INTEGER INFO, KL, KU, LDAB, LDC, LDPT, LDQ, M, N, NCC
27 * ..
28 * .. Array Arguments ..
29 * DOUBLE PRECISION AB( LDAB, * ), C( LDC, * ), D( * ), E( * ),
30 * $ PT( LDPT, * ), Q( LDQ, * ), WORK( * )
31 * ..
32 *
33 *
34 *> \par Purpose:
35 * =============
36 *>
37 *> \verbatim
38 *>
39 *> DGBBRD reduces a real general m-by-n band matrix A to upper
40 *> bidiagonal form B by an orthogonal transformation: Q**T * A * P = B.
41 *>
42 *> The routine computes B, and optionally forms Q or P**T, or computes
43 *> Q**T*C for a given matrix C.
44 *> \endverbatim
45 *
46 * Arguments:
47 * ==========
48 *
49 *> \param[in] VECT
50 *> \verbatim
51 *> VECT is CHARACTER*1
52 *> Specifies whether or not the matrices Q and P**T are to be
53 *> formed.
54 *> = 'N': do not form Q or P**T;
55 *> = 'Q': form Q only;
56 *> = 'P': form P**T only;
57 *> = 'B': form both.
58 *> \endverbatim
59 *>
60 *> \param[in] M
61 *> \verbatim
62 *> M is INTEGER
63 *> The number of rows of the matrix A. M >= 0.
64 *> \endverbatim
65 *>
66 *> \param[in] N
67 *> \verbatim
68 *> N is INTEGER
69 *> The number of columns of the matrix A. N >= 0.
70 *> \endverbatim
71 *>
72 *> \param[in] NCC
73 *> \verbatim
74 *> NCC is INTEGER
75 *> The number of columns of the matrix C. NCC >= 0.
76 *> \endverbatim
77 *>
78 *> \param[in] KL
79 *> \verbatim
80 *> KL is INTEGER
81 *> The number of subdiagonals of the matrix A. KL >= 0.
82 *> \endverbatim
83 *>
84 *> \param[in] KU
85 *> \verbatim
86 *> KU is INTEGER
87 *> The number of superdiagonals of the matrix A. KU >= 0.
88 *> \endverbatim
89 *>
90 *> \param[in,out] AB
91 *> \verbatim
92 *> AB is DOUBLE PRECISION array, dimension (LDAB,N)
93 *> On entry, the m-by-n band matrix A, stored in rows 1 to
94 *> KL+KU+1. The j-th column of A is stored in the j-th column of
95 *> the array AB as follows:
96 *> AB(ku+1+i-j,j) = A(i,j) for max(1,j-ku)<=i<=min(m,j+kl).
97 *> On exit, A is overwritten by values generated during the
98 *> reduction.
99 *> \endverbatim
100 *>
101 *> \param[in] LDAB
102 *> \verbatim
103 *> LDAB is INTEGER
104 *> The leading dimension of the array A. LDAB >= KL+KU+1.
105 *> \endverbatim
106 *>
107 *> \param[out] D
108 *> \verbatim
109 *> D is DOUBLE PRECISION array, dimension (min(M,N))
110 *> The diagonal elements of the bidiagonal matrix B.
111 *> \endverbatim
112 *>
113 *> \param[out] E
114 *> \verbatim
115 *> E is DOUBLE PRECISION array, dimension (min(M,N)-1)
116 *> The superdiagonal elements of the bidiagonal matrix B.
117 *> \endverbatim
118 *>
119 *> \param[out] Q
120 *> \verbatim
121 *> Q is DOUBLE PRECISION array, dimension (LDQ,M)
122 *> If VECT = 'Q' or 'B', the m-by-m orthogonal matrix Q.
123 *> If VECT = 'N' or 'P', the array Q is not referenced.
124 *> \endverbatim
125 *>
126 *> \param[in] LDQ
127 *> \verbatim
128 *> LDQ is INTEGER
129 *> The leading dimension of the array Q.
130 *> LDQ >= max(1,M) if VECT = 'Q' or 'B'; LDQ >= 1 otherwise.
131 *> \endverbatim
132 *>
133 *> \param[out] PT
134 *> \verbatim
135 *> PT is DOUBLE PRECISION array, dimension (LDPT,N)
136 *> If VECT = 'P' or 'B', the n-by-n orthogonal matrix P'.
137 *> If VECT = 'N' or 'Q', the array PT is not referenced.
138 *> \endverbatim
139 *>
140 *> \param[in] LDPT
141 *> \verbatim
142 *> LDPT is INTEGER
143 *> The leading dimension of the array PT.
144 *> LDPT >= max(1,N) if VECT = 'P' or 'B'; LDPT >= 1 otherwise.
145 *> \endverbatim
146 *>
147 *> \param[in,out] C
148 *> \verbatim
149 *> C is DOUBLE PRECISION array, dimension (LDC,NCC)
150 *> On entry, an m-by-ncc matrix C.
151 *> On exit, C is overwritten by Q**T*C.
152 *> C is not referenced if NCC = 0.
153 *> \endverbatim
154 *>
155 *> \param[in] LDC
156 *> \verbatim
157 *> LDC is INTEGER
158 *> The leading dimension of the array C.
159 *> LDC >= max(1,M) if NCC > 0; LDC >= 1 if NCC = 0.
160 *> \endverbatim
161 *>
162 *> \param[out] WORK
163 *> \verbatim
164 *> WORK is DOUBLE PRECISION array, dimension (2*max(M,N))
165 *> \endverbatim
166 *>
167 *> \param[out] INFO
168 *> \verbatim
169 *> INFO is INTEGER
170 *> = 0: successful exit.
171 *> < 0: if INFO = -i, the i-th argument had an illegal value.
172 *> \endverbatim
173 *
174 * Authors:
175 * ========
176 *
177 *> \author Univ. of Tennessee
178 *> \author Univ. of California Berkeley
179 *> \author Univ. of Colorado Denver
180 *> \author NAG Ltd.
181 *
182 *> \date November 2011
183 *
184 *> \ingroup doubleGBcomputational
185 *
186 * =====================================================================
187  SUBROUTINE dgbbrd( VECT, M, N, NCC, KL, KU, AB, LDAB, D, E, Q,
188  $ ldq, pt, ldpt, c, ldc, work, info )
189 *
190 * -- LAPACK computational routine (version 3.4.0) --
191 * -- LAPACK is a software package provided by Univ. of Tennessee, --
192 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
193 * November 2011
194 *
195 * .. Scalar Arguments ..
196  CHARACTER vect
197  INTEGER info, kl, ku, ldab, ldc, ldpt, ldq, m, n, ncc
198 * ..
199 * .. Array Arguments ..
200  DOUBLE PRECISION ab( ldab, * ), c( ldc, * ), d( * ), e( * ),
201  $ pt( ldpt, * ), q( ldq, * ), work( * )
202 * ..
203 *
204 * =====================================================================
205 *
206 * .. Parameters ..
207  DOUBLE PRECISION zero, one
208  parameter( zero = 0.0d+0, one = 1.0d+0 )
209 * ..
210 * .. Local Scalars ..
211  LOGICAL wantb, wantc, wantpt, wantq
212  INTEGER i, inca, j, j1, j2, kb, kb1, kk, klm, klu1,
213  $ kun, l, minmn, ml, ml0, mn, mu, mu0, nr, nrt
214  DOUBLE PRECISION ra, rb, rc, rs
215 * ..
216 * .. External Subroutines ..
217  EXTERNAL dlargv, dlartg, dlartv, dlaset, drot, xerbla
218 * ..
219 * .. Intrinsic Functions ..
220  INTRINSIC max, min
221 * ..
222 * .. External Functions ..
223  LOGICAL lsame
224  EXTERNAL lsame
225 * ..
226 * .. Executable Statements ..
227 *
228 * Test the input parameters
229 *
230  wantb = lsame( vect, 'B' )
231  wantq = lsame( vect, 'Q' ) .OR. wantb
232  wantpt = lsame( vect, 'P' ) .OR. wantb
233  wantc = ncc.GT.0
234  klu1 = kl + ku + 1
235  info = 0
236  IF( .NOT.wantq .AND. .NOT.wantpt .AND. .NOT.lsame( vect, 'N' ) )
237  $ THEN
238  info = -1
239  ELSE IF( m.LT.0 ) THEN
240  info = -2
241  ELSE IF( n.LT.0 ) THEN
242  info = -3
243  ELSE IF( ncc.LT.0 ) THEN
244  info = -4
245  ELSE IF( kl.LT.0 ) THEN
246  info = -5
247  ELSE IF( ku.LT.0 ) THEN
248  info = -6
249  ELSE IF( ldab.LT.klu1 ) THEN
250  info = -8
251  ELSE IF( ldq.LT.1 .OR. wantq .AND. ldq.LT.max( 1, m ) ) THEN
252  info = -12
253  ELSE IF( ldpt.LT.1 .OR. wantpt .AND. ldpt.LT.max( 1, n ) ) THEN
254  info = -14
255  ELSE IF( ldc.LT.1 .OR. wantc .AND. ldc.LT.max( 1, m ) ) THEN
256  info = -16
257  END IF
258  IF( info.NE.0 ) THEN
259  CALL xerbla( 'DGBBRD', -info )
260  return
261  END IF
262 *
263 * Initialize Q and P**T to the unit matrix, if needed
264 *
265  IF( wantq )
266  $ CALL dlaset( 'Full', m, m, zero, one, q, ldq )
267  IF( wantpt )
268  $ CALL dlaset( 'Full', n, n, zero, one, pt, ldpt )
269 *
270 * Quick return if possible.
271 *
272  IF( m.EQ.0 .OR. n.EQ.0 )
273  $ return
274 *
275  minmn = min( m, n )
276 *
277  IF( kl+ku.GT.1 ) THEN
278 *
279 * Reduce to upper bidiagonal form if KU > 0; if KU = 0, reduce
280 * first to lower bidiagonal form and then transform to upper
281 * bidiagonal
282 *
283  IF( ku.GT.0 ) THEN
284  ml0 = 1
285  mu0 = 2
286  ELSE
287  ml0 = 2
288  mu0 = 1
289  END IF
290 *
291 * Wherever possible, plane rotations are generated and applied in
292 * vector operations of length NR over the index set J1:J2:KLU1.
293 *
294 * The sines of the plane rotations are stored in WORK(1:max(m,n))
295 * and the cosines in WORK(max(m,n)+1:2*max(m,n)).
296 *
297  mn = max( m, n )
298  klm = min( m-1, kl )
299  kun = min( n-1, ku )
300  kb = klm + kun
301  kb1 = kb + 1
302  inca = kb1*ldab
303  nr = 0
304  j1 = klm + 2
305  j2 = 1 - kun
306 *
307  DO 90 i = 1, minmn
308 *
309 * Reduce i-th column and i-th row of matrix to bidiagonal form
310 *
311  ml = klm + 1
312  mu = kun + 1
313  DO 80 kk = 1, kb
314  j1 = j1 + kb
315  j2 = j2 + kb
316 *
317 * generate plane rotations to annihilate nonzero elements
318 * which have been created below the band
319 *
320  IF( nr.GT.0 )
321  $ CALL dlargv( nr, ab( klu1, j1-klm-1 ), inca,
322  $ work( j1 ), kb1, work( mn+j1 ), kb1 )
323 *
324 * apply plane rotations from the left
325 *
326  DO 10 l = 1, kb
327  IF( j2-klm+l-1.GT.n ) THEN
328  nrt = nr - 1
329  ELSE
330  nrt = nr
331  END IF
332  IF( nrt.GT.0 )
333  $ CALL dlartv( nrt, ab( klu1-l, j1-klm+l-1 ), inca,
334  $ ab( klu1-l+1, j1-klm+l-1 ), inca,
335  $ work( mn+j1 ), work( j1 ), kb1 )
336  10 continue
337 *
338  IF( ml.GT.ml0 ) THEN
339  IF( ml.LE.m-i+1 ) THEN
340 *
341 * generate plane rotation to annihilate a(i+ml-1,i)
342 * within the band, and apply rotation from the left
343 *
344  CALL dlartg( ab( ku+ml-1, i ), ab( ku+ml, i ),
345  $ work( mn+i+ml-1 ), work( i+ml-1 ),
346  $ ra )
347  ab( ku+ml-1, i ) = ra
348  IF( i.LT.n )
349  $ CALL drot( min( ku+ml-2, n-i ),
350  $ ab( ku+ml-2, i+1 ), ldab-1,
351  $ ab( ku+ml-1, i+1 ), ldab-1,
352  $ work( mn+i+ml-1 ), work( i+ml-1 ) )
353  END IF
354  nr = nr + 1
355  j1 = j1 - kb1
356  END IF
357 *
358  IF( wantq ) THEN
359 *
360 * accumulate product of plane rotations in Q
361 *
362  DO 20 j = j1, j2, kb1
363  CALL drot( m, q( 1, j-1 ), 1, q( 1, j ), 1,
364  $ work( mn+j ), work( j ) )
365  20 continue
366  END IF
367 *
368  IF( wantc ) THEN
369 *
370 * apply plane rotations to C
371 *
372  DO 30 j = j1, j2, kb1
373  CALL drot( ncc, c( j-1, 1 ), ldc, c( j, 1 ), ldc,
374  $ work( mn+j ), work( j ) )
375  30 continue
376  END IF
377 *
378  IF( j2+kun.GT.n ) THEN
379 *
380 * adjust J2 to keep within the bounds of the matrix
381 *
382  nr = nr - 1
383  j2 = j2 - kb1
384  END IF
385 *
386  DO 40 j = j1, j2, kb1
387 *
388 * create nonzero element a(j-1,j+ku) above the band
389 * and store it in WORK(n+1:2*n)
390 *
391  work( j+kun ) = work( j )*ab( 1, j+kun )
392  ab( 1, j+kun ) = work( mn+j )*ab( 1, j+kun )
393  40 continue
394 *
395 * generate plane rotations to annihilate nonzero elements
396 * which have been generated above the band
397 *
398  IF( nr.GT.0 )
399  $ CALL dlargv( nr, ab( 1, j1+kun-1 ), inca,
400  $ work( j1+kun ), kb1, work( mn+j1+kun ),
401  $ kb1 )
402 *
403 * apply plane rotations from the right
404 *
405  DO 50 l = 1, kb
406  IF( j2+l-1.GT.m ) THEN
407  nrt = nr - 1
408  ELSE
409  nrt = nr
410  END IF
411  IF( nrt.GT.0 )
412  $ CALL dlartv( nrt, ab( l+1, j1+kun-1 ), inca,
413  $ ab( l, j1+kun ), inca,
414  $ work( mn+j1+kun ), work( j1+kun ),
415  $ kb1 )
416  50 continue
417 *
418  IF( ml.EQ.ml0 .AND. mu.GT.mu0 ) THEN
419  IF( mu.LE.n-i+1 ) THEN
420 *
421 * generate plane rotation to annihilate a(i,i+mu-1)
422 * within the band, and apply rotation from the right
423 *
424  CALL dlartg( ab( ku-mu+3, i+mu-2 ),
425  $ ab( ku-mu+2, i+mu-1 ),
426  $ work( mn+i+mu-1 ), work( i+mu-1 ),
427  $ ra )
428  ab( ku-mu+3, i+mu-2 ) = ra
429  CALL drot( min( kl+mu-2, m-i ),
430  $ ab( ku-mu+4, i+mu-2 ), 1,
431  $ ab( ku-mu+3, i+mu-1 ), 1,
432  $ work( mn+i+mu-1 ), work( i+mu-1 ) )
433  END IF
434  nr = nr + 1
435  j1 = j1 - kb1
436  END IF
437 *
438  IF( wantpt ) THEN
439 *
440 * accumulate product of plane rotations in P**T
441 *
442  DO 60 j = j1, j2, kb1
443  CALL drot( n, pt( j+kun-1, 1 ), ldpt,
444  $ pt( j+kun, 1 ), ldpt, work( mn+j+kun ),
445  $ work( j+kun ) )
446  60 continue
447  END IF
448 *
449  IF( j2+kb.GT.m ) THEN
450 *
451 * adjust J2 to keep within the bounds of the matrix
452 *
453  nr = nr - 1
454  j2 = j2 - kb1
455  END IF
456 *
457  DO 70 j = j1, j2, kb1
458 *
459 * create nonzero element a(j+kl+ku,j+ku-1) below the
460 * band and store it in WORK(1:n)
461 *
462  work( j+kb ) = work( j+kun )*ab( klu1, j+kun )
463  ab( klu1, j+kun ) = work( mn+j+kun )*ab( klu1, j+kun )
464  70 continue
465 *
466  IF( ml.GT.ml0 ) THEN
467  ml = ml - 1
468  ELSE
469  mu = mu - 1
470  END IF
471  80 continue
472  90 continue
473  END IF
474 *
475  IF( ku.EQ.0 .AND. kl.GT.0 ) THEN
476 *
477 * A has been reduced to lower bidiagonal form
478 *
479 * Transform lower bidiagonal form to upper bidiagonal by applying
480 * plane rotations from the left, storing diagonal elements in D
481 * and off-diagonal elements in E
482 *
483  DO 100 i = 1, min( m-1, n )
484  CALL dlartg( ab( 1, i ), ab( 2, i ), rc, rs, ra )
485  d( i ) = ra
486  IF( i.LT.n ) THEN
487  e( i ) = rs*ab( 1, i+1 )
488  ab( 1, i+1 ) = rc*ab( 1, i+1 )
489  END IF
490  IF( wantq )
491  $ CALL drot( m, q( 1, i ), 1, q( 1, i+1 ), 1, rc, rs )
492  IF( wantc )
493  $ CALL drot( ncc, c( i, 1 ), ldc, c( i+1, 1 ), ldc, rc,
494  $ rs )
495  100 continue
496  IF( m.LE.n )
497  $ d( m ) = ab( 1, m )
498  ELSE IF( ku.GT.0 ) THEN
499 *
500 * A has been reduced to upper bidiagonal form
501 *
502  IF( m.LT.n ) THEN
503 *
504 * Annihilate a(m,m+1) by applying plane rotations from the
505 * right, storing diagonal elements in D and off-diagonal
506 * elements in E
507 *
508  rb = ab( ku, m+1 )
509  DO 110 i = m, 1, -1
510  CALL dlartg( ab( ku+1, i ), rb, rc, rs, ra )
511  d( i ) = ra
512  IF( i.GT.1 ) THEN
513  rb = -rs*ab( ku, i )
514  e( i-1 ) = rc*ab( ku, i )
515  END IF
516  IF( wantpt )
517  $ CALL drot( n, pt( i, 1 ), ldpt, pt( m+1, 1 ), ldpt,
518  $ rc, rs )
519  110 continue
520  ELSE
521 *
522 * Copy off-diagonal elements to E and diagonal elements to D
523 *
524  DO 120 i = 1, minmn - 1
525  e( i ) = ab( ku, i+1 )
526  120 continue
527  DO 130 i = 1, minmn
528  d( i ) = ab( ku+1, i )
529  130 continue
530  END IF
531  ELSE
532 *
533 * A is diagonal. Set elements of E to zero and copy diagonal
534 * elements to D.
535 *
536  DO 140 i = 1, minmn - 1
537  e( i ) = zero
538  140 continue
539  DO 150 i = 1, minmn
540  d( i ) = ab( 1, i )
541  150 continue
542  END IF
543  return
544 *
545 * End of DGBBRD
546 *
547  END