~ubuntu-branches/ubuntu/karmic/scilab/karmic

« back to all changes in this revision

Viewing changes to routines/lapack/dormql.f

  • Committer: Bazaar Package Importer
  • Author(s): Torsten Werner
  • Date: 2002-03-21 16:57:43 UTC
  • Revision ID: james.westby@ubuntu.com-20020321165743-e9mv12c1tb1plztg
Tags: upstream-2.6
ImportĀ upstreamĀ versionĀ 2.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
      SUBROUTINE DORMQL( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,
 
3
     $                   WORK, LWORK, INFO )
 
4
*
 
5
*  -- LAPACK routine (version 2.0) --
 
6
*     Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
 
7
*     Courant Institute, Argonne National Lab, and Rice University
 
8
*     September 30, 1994
 
9
*
 
10
*     .. Scalar Arguments ..
 
11
      CHARACTER          SIDE, TRANS
 
12
      INTEGER            INFO, K, LDA, LDC, LWORK, M, N
 
13
*     ..
 
14
*     .. Array Arguments ..
 
15
      DOUBLE PRECISION   A( LDA, * ), C( LDC, * ), TAU( * ),
 
16
     $                   WORK( LWORK )
 
17
*     ..
 
18
*
 
19
*  Purpose
 
20
*  =======
 
21
*
 
22
*  DORMQL overwrites the general real M-by-N matrix C with
 
23
*
 
24
*                  SIDE = 'L'     SIDE = 'R'
 
25
*  TRANS = 'N':      Q * C          C * Q
 
26
*  TRANS = 'T':      Q**T * C       C * Q**T
 
27
*
 
28
*  where Q is a real orthogonal matrix defined as the product of k
 
29
*  elementary reflectors
 
30
*
 
31
*        Q = H(k) . . . H(2) H(1)
 
32
*
 
33
*  as returned by DGEQLF. Q is of order M if SIDE = 'L' and of order N
 
34
*  if SIDE = 'R'.
 
35
*
 
36
*  Arguments
 
37
*  =========
 
38
*
 
39
*  SIDE    (input) CHARACTER*1
 
40
*          = 'L': apply Q or Q**T from the Left;
 
41
*          = 'R': apply Q or Q**T from the Right.
 
42
*
 
43
*  TRANS   (input) CHARACTER*1
 
44
*          = 'N':  No transpose, apply Q;
 
45
*          = 'T':  Transpose, apply Q**T.
 
46
*
 
47
*  M       (input) INTEGER
 
48
*          The number of rows of the matrix C. M >= 0.
 
49
*
 
50
*  N       (input) INTEGER
 
51
*          The number of columns of the matrix C. N >= 0.
 
52
*
 
53
*  K       (input) INTEGER
 
54
*          The number of elementary reflectors whose product defines
 
55
*          the matrix Q.
 
56
*          If SIDE = 'L', M >= K >= 0;
 
57
*          if SIDE = 'R', N >= K >= 0.
 
58
*
 
59
*  A       (input) DOUBLE PRECISION array, dimension (LDA,K)
 
60
*          The i-th column must contain the vector which defines the
 
61
*          elementary reflector H(i), for i = 1,2,...,k, as returned by
 
62
*          DGEQLF in the last k columns of its array argument A.
 
63
*          A is modified by the routine but restored on exit.
 
64
*
 
65
*  LDA     (input) INTEGER
 
66
*          The leading dimension of the array A.
 
67
*          If SIDE = 'L', LDA >= max(1,M);
 
68
*          if SIDE = 'R', LDA >= max(1,N).
 
69
*
 
70
*  TAU     (input) DOUBLE PRECISION array, dimension (K)
 
71
*          TAU(i) must contain the scalar factor of the elementary
 
72
*          reflector H(i), as returned by DGEQLF.
 
73
*
 
74
*  C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
 
75
*          On entry, the M-by-N matrix C.
 
76
*          On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q.
 
77
*
 
78
*  LDC     (input) INTEGER
 
79
*          The leading dimension of the array C. LDC >= max(1,M).
 
80
*
 
81
*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (LWORK)
 
82
*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
 
83
*
 
84
*  LWORK   (input) INTEGER
 
85
*          The dimension of the array WORK.
 
86
*          If SIDE = 'L', LWORK >= max(1,N);
 
87
*          if SIDE = 'R', LWORK >= max(1,M).
 
88
*          For optimum performance LWORK >= N*NB if SIDE = 'L', and
 
89
*          LWORK >= M*NB if SIDE = 'R', where NB is the optimal
 
90
*          blocksize.
 
91
*
 
92
*  INFO    (output) INTEGER
 
93
*          = 0:  successful exit
 
94
*          < 0:  if INFO = -i, the i-th argument had an illegal value
 
95
*
 
96
*  =====================================================================
 
97
*
 
98
*     .. Parameters ..
 
99
      INTEGER            NBMAX, LDT
 
100
      PARAMETER          ( NBMAX = 64, LDT = NBMAX+1 )
 
101
*     ..
 
102
*     .. Local Scalars ..
 
103
      LOGICAL            LEFT, NOTRAN
 
104
      INTEGER            I, I1, I2, I3, IB, IINFO, IWS, LDWORK, MI, NB,
 
105
     $                   NBMIN, NI, NQ, NW
 
106
*     ..
 
107
*     .. Local Arrays ..
 
108
      DOUBLE PRECISION   T( LDT, NBMAX )
 
109
*     ..
 
110
*     .. External Functions ..
 
111
      LOGICAL            LSAME
 
112
      INTEGER            ILAENV
 
113
      EXTERNAL           LSAME, ILAENV
 
114
*     ..
 
115
*     .. External Subroutines ..
 
116
      EXTERNAL           DLARFB, DLARFT, DORM2L, XERBLA
 
117
*     ..
 
118
*     .. Intrinsic Functions ..
 
119
      INTRINSIC          MAX, MIN
 
120
*     ..
 
121
*     .. Executable Statements ..
 
122
*
 
123
*     Test the input arguments
 
124
*
 
125
      INFO = 0
 
126
      LEFT = LSAME( SIDE, 'L' )
 
127
      NOTRAN = LSAME( TRANS, 'N' )
 
128
*
 
129
*     NQ is the order of Q and NW is the minimum dimension of WORK
 
130
*
 
131
      IF( LEFT ) THEN
 
132
         NQ = M
 
133
         NW = N
 
134
      ELSE
 
135
         NQ = N
 
136
         NW = M
 
137
      END IF
 
138
      IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
 
139
         INFO = -1
 
140
      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THEN
 
141
         INFO = -2
 
142
      ELSE IF( M.LT.0 ) THEN
 
143
         INFO = -3
 
144
      ELSE IF( N.LT.0 ) THEN
 
145
         INFO = -4
 
146
      ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN
 
147
         INFO = -5
 
148
      ELSE IF( LDA.LT.MAX( 1, NQ ) ) THEN
 
149
         INFO = -7
 
150
      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
 
151
         INFO = -10
 
152
      ELSE IF( LWORK.LT.MAX( 1, NW ) ) THEN
 
153
         INFO = -12
 
154
      END IF
 
155
      IF( INFO.NE.0 ) THEN
 
156
         CALL XERBLA( 'DORMQL', -INFO )
 
157
         RETURN
 
158
      END IF
 
159
*
 
160
*     Quick return if possible
 
161
*
 
162
      IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 ) THEN
 
163
         WORK( 1 ) = 1
 
164
         RETURN
 
165
      END IF
 
166
*
 
167
*     Determine the block size.  NB may be at most NBMAX, where NBMAX
 
168
*     is used to define the local array T.
 
169
*
 
170
      NB = MIN( NBMAX, ILAENV( 1, 'DORMQL', SIDE // TRANS, M, N, K,
 
171
     $     -1 ) )
 
172
      NBMIN = 2
 
173
      LDWORK = NW
 
174
      IF( NB.GT.1 .AND. NB.LT.K ) THEN
 
175
         IWS = NW*NB
 
176
         IF( LWORK.LT.IWS ) THEN
 
177
            NB = LWORK / LDWORK
 
178
            NBMIN = MAX( 2, ILAENV( 2, 'DORMQL', SIDE // TRANS, M, N, K,
 
179
     $              -1 ) )
 
180
         END IF
 
181
      ELSE
 
182
         IWS = NW
 
183
      END IF
 
184
*
 
185
      IF( NB.LT.NBMIN .OR. NB.GE.K ) THEN
 
186
*
 
187
*        Use unblocked code
 
188
*
 
189
         CALL DORM2L( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK,
 
190
     $                IINFO )
 
191
      ELSE
 
192
*
 
193
*        Use blocked code
 
194
*
 
195
         IF( ( LEFT .AND. NOTRAN ) .OR.
 
196
     $       ( .NOT.LEFT .AND. .NOT.NOTRAN ) ) THEN
 
197
            I1 = 1
 
198
            I2 = K
 
199
            I3 = NB
 
200
         ELSE
 
201
            I1 = ( ( K-1 ) / NB )*NB + 1
 
202
            I2 = 1
 
203
            I3 = -NB
 
204
         END IF
 
205
*
 
206
         IF( LEFT ) THEN
 
207
            NI = N
 
208
         ELSE
 
209
            MI = M
 
210
         END IF
 
211
*
 
212
         DO 10 I = I1, I2, I3
 
213
            IB = MIN( NB, K-I+1 )
 
214
*
 
215
*           Form the triangular factor of the block reflector
 
216
*           H = H(i+ib-1) . . . H(i+1) H(i)
 
217
*
 
218
            CALL DLARFT( 'Backward', 'Columnwise', NQ-K+I+IB-1, IB,
 
219
     $                   A( 1, I ), LDA, TAU( I ), T, LDT )
 
220
            IF( LEFT ) THEN
 
221
*
 
222
*              H or H' is applied to C(1:m-k+i+ib-1,1:n)
 
223
*
 
224
               MI = M - K + I + IB - 1
 
225
            ELSE
 
226
*
 
227
*              H or H' is applied to C(1:m,1:n-k+i+ib-1)
 
228
*
 
229
               NI = N - K + I + IB - 1
 
230
            END IF
 
231
*
 
232
*           Apply H or H'
 
233
*
 
234
            CALL DLARFB( SIDE, TRANS, 'Backward', 'Columnwise', MI, NI,
 
235
     $                   IB, A( 1, I ), LDA, T, LDT, C, LDC, WORK,
 
236
     $                   LDWORK )
 
237
   10    CONTINUE
 
238
      END IF
 
239
      WORK( 1 ) = IWS
 
240
      RETURN
 
241
*
 
242
*     End of DORMQL
 
243
*
 
244
      END
 
245
 
 
246
      SUBROUTINE DORM2L( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,
 
247
     $                   WORK, INFO )
 
248
*
 
249
*  -- LAPACK routine (version 2.0) --
 
250
*     Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
 
251
*     Courant Institute, Argonne National Lab, and Rice University
 
252
*     February 29, 1992
 
253
*
 
254
*     .. Scalar Arguments ..
 
255
      CHARACTER          SIDE, TRANS
 
256
      INTEGER            INFO, K, LDA, LDC, M, N
 
257
*     ..
 
258
*     .. Array Arguments ..
 
259
      DOUBLE PRECISION   A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )
 
260
*     ..
 
261
*
 
262
*  Purpose
 
263
*  =======
 
264
*
 
265
*  DORM2L overwrites the general real m by n matrix C with
 
266
*
 
267
*        Q * C  if SIDE = 'L' and TRANS = 'N', or
 
268
*
 
269
*        Q'* C  if SIDE = 'L' and TRANS = 'T', or
 
270
*
 
271
*        C * Q  if SIDE = 'R' and TRANS = 'N', or
 
272
*
 
273
*        C * Q' if SIDE = 'R' and TRANS = 'T',
 
274
*
 
275
*  where Q is a real orthogonal matrix defined as the product of k
 
276
*  elementary reflectors
 
277
*
 
278
*        Q = H(k) . . . H(2) H(1)
 
279
*
 
280
*  as returned by DGEQLF. Q is of order m if SIDE = 'L' and of order n
 
281
*  if SIDE = 'R'.
 
282
*
 
283
*  Arguments
 
284
*  =========
 
285
*
 
286
*  SIDE    (input) CHARACTER*1
 
287
*          = 'L': apply Q or Q' from the Left
 
288
*          = 'R': apply Q or Q' from the Right
 
289
*
 
290
*  TRANS   (input) CHARACTER*1
 
291
*          = 'N': apply Q  (No transpose)
 
292
*          = 'T': apply Q' (Transpose)
 
293
*
 
294
*  M       (input) INTEGER
 
295
*          The number of rows of the matrix C. M >= 0.
 
296
*
 
297
*  N       (input) INTEGER
 
298
*          The number of columns of the matrix C. N >= 0.
 
299
*
 
300
*  K       (input) INTEGER
 
301
*          The number of elementary reflectors whose product defines
 
302
*          the matrix Q.
 
303
*          If SIDE = 'L', M >= K >= 0;
 
304
*          if SIDE = 'R', N >= K >= 0.
 
305
*
 
306
*  A       (input) DOUBLE PRECISION array, dimension (LDA,K)
 
307
*          The i-th column must contain the vector which defines the
 
308
*          elementary reflector H(i), for i = 1,2,...,k, as returned by
 
309
*          DGEQLF in the last k columns of its array argument A.
 
310
*          A is modified by the routine but restored on exit.
 
311
*
 
312
*  LDA     (input) INTEGER
 
313
*          The leading dimension of the array A.
 
314
*          If SIDE = 'L', LDA >= max(1,M);
 
315
*          if SIDE = 'R', LDA >= max(1,N).
 
316
*
 
317
*  TAU     (input) DOUBLE PRECISION array, dimension (K)
 
318
*          TAU(i) must contain the scalar factor of the elementary
 
319
*          reflector H(i), as returned by DGEQLF.
 
320
*
 
321
*  C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
 
322
*          On entry, the m by n matrix C.
 
323
*          On exit, C is overwritten by Q*C or Q'*C or C*Q' or C*Q.
 
324
*
 
325
*  LDC     (input) INTEGER
 
326
*          The leading dimension of the array C. LDC >= max(1,M).
 
327
*
 
328
*  WORK    (workspace) DOUBLE PRECISION array, dimension
 
329
*                                   (N) if SIDE = 'L',
 
330
*                                   (M) if SIDE = 'R'
 
331
*
 
332
*  INFO    (output) INTEGER
 
333
*          = 0: successful exit
 
334
*          < 0: if INFO = -i, the i-th argument had an illegal value
 
335
*
 
336
*  =====================================================================
 
337
*
 
338
*     .. Parameters ..
 
339
      DOUBLE PRECISION   ONE
 
340
      PARAMETER          ( ONE = 1.0D+0 )
 
341
*     ..
 
342
*     .. Local Scalars ..
 
343
      LOGICAL            LEFT, NOTRAN
 
344
      INTEGER            I, I1, I2, I3, MI, NI, NQ
 
345
      DOUBLE PRECISION   AII
 
346
*     ..
 
347
*     .. External Functions ..
 
348
      LOGICAL            LSAME
 
349
      EXTERNAL           LSAME
 
350
*     ..
 
351
*     .. External Subroutines ..
 
352
      EXTERNAL           DLARF, XERBLA
 
353
*     ..
 
354
*     .. Intrinsic Functions ..
 
355
      INTRINSIC          MAX
 
356
*     ..
 
357
*     .. Executable Statements ..
 
358
*
 
359
*     Test the input arguments
 
360
*
 
361
      INFO = 0
 
362
      LEFT = LSAME( SIDE, 'L' )
 
363
      NOTRAN = LSAME( TRANS, 'N' )
 
364
*
 
365
*     NQ is the order of Q
 
366
*
 
367
      IF( LEFT ) THEN
 
368
         NQ = M
 
369
      ELSE
 
370
         NQ = N
 
371
      END IF
 
372
      IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
 
373
         INFO = -1
 
374
      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THEN
 
375
         INFO = -2
 
376
      ELSE IF( M.LT.0 ) THEN
 
377
         INFO = -3
 
378
      ELSE IF( N.LT.0 ) THEN
 
379
         INFO = -4
 
380
      ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN
 
381
         INFO = -5
 
382
      ELSE IF( LDA.LT.MAX( 1, NQ ) ) THEN
 
383
         INFO = -7
 
384
      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
 
385
         INFO = -10
 
386
      END IF
 
387
      IF( INFO.NE.0 ) THEN
 
388
         CALL XERBLA( 'DORM2L', -INFO )
 
389
         RETURN
 
390
      END IF
 
391
*
 
392
*     Quick return if possible
 
393
*
 
394
      IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 )
 
395
     $   RETURN
 
396
*
 
397
      IF( ( LEFT .AND. NOTRAN ) .OR. ( .NOT.LEFT .AND. .NOT.NOTRAN ) )
 
398
     $     THEN
 
399
         I1 = 1
 
400
         I2 = K
 
401
         I3 = 1
 
402
      ELSE
 
403
         I1 = K
 
404
         I2 = 1
 
405
         I3 = -1
 
406
      END IF
 
407
*
 
408
      IF( LEFT ) THEN
 
409
         NI = N
 
410
      ELSE
 
411
         MI = M
 
412
      END IF
 
413
*
 
414
      DO 10 I = I1, I2, I3
 
415
         IF( LEFT ) THEN
 
416
*
 
417
*           H(i) is applied to C(1:m-k+i,1:n)
 
418
*
 
419
            MI = M - K + I
 
420
         ELSE
 
421
*
 
422
*           H(i) is applied to C(1:m,1:n-k+i)
 
423
*
 
424
            NI = N - K + I
 
425
         END IF
 
426
*
 
427
*        Apply H(i)
 
428
*
 
429
         AII = A( NQ-K+I, I )
 
430
         A( NQ-K+I, I ) = ONE
 
431
         CALL DLARF( SIDE, MI, NI, A( 1, I ), 1, TAU( I ), C, LDC,
 
432
     $               WORK )
 
433
         A( NQ-K+I, I ) = AII
 
434
   10 CONTINUE
 
435
      RETURN
 
436
*
 
437
*     End of DORM2L
 
438
*
 
439
      END