226 SUBROUTINE dcsdts( M, P, Q, X, XF, LDX, U1, LDU1, U2, LDU2, V1T,
227 $ LDV1T, V2T, LDV2T, THETA, IWORK, WORK, LWORK,
235 INTEGER LDX, LDU1, LDU2, LDV1T, LDV2T, LWORK, M, P, Q
239 DOUBLE PRECISION RESULT( 15 ), RWORK( * ), THETA( * )
240 DOUBLE PRECISION U1( LDU1, * ), U2( LDU2, * ), V1T( LDV1T, * ),
241 $ v2t( ldv2t, * ), work( lwork ), x( ldx, * ),
248 DOUBLE PRECISION REALONE, REALZERO
249 PARAMETER ( REALONE = 1.0d0, realzero = 0.0d0 )
250 DOUBLE PRECISION ZERO, ONE
251 parameter( zero = 0.0d0, one = 1.0d0 )
252 DOUBLE PRECISION PIOVER2
253 parameter( piover2 = 1.57079632679489661923132169163975144210d0 )
257 DOUBLE PRECISION EPS2, RESID, ULP, ULPINV
260 DOUBLE PRECISION DLAMCH, DLANGE, DLANSY
261 EXTERNAL DLAMCH, DLANGE, DLANSY
268 INTRINSIC cos, dble, max, min, sin
272 ulp = dlamch(
'Precision' )
273 ulpinv = realone / ulp
277 CALL dlaset(
'Full', m, m, zero, one, work, ldx )
278 CALL dsyrk(
'Upper',
'Conjugate transpose', m, m, -one, x, ldx,
282 $ dlange(
'1', m, m, work, ldx, rwork ) / dble( m ) )
286 r = min( p, m-p, q, m-q )
290 CALL dlacpy(
'Full', m, m, x, ldx, xf, ldx )
294 CALL dorcsd(
'Y',
'Y',
'Y',
'Y',
'N',
'D', m, p, q, xf(1,1), ldx,
295 $ xf(1,q+1), ldx, xf(p+1,1), ldx, xf(p+1,q+1), ldx,
296 $ theta, u1, ldu1, u2, ldu2, v1t, ldv1t, v2t, ldv2t,
297 $ work, lwork, iwork, info )
301 CALL dlacpy(
'Full', m, m, x, ldx, xf, ldx )
303 CALL dgemm(
'No transpose',
'Conjugate transpose', p, q, q, one,
304 $ xf, ldx, v1t, ldv1t, zero, work, ldx )
306 CALL dgemm(
'Conjugate transpose',
'No transpose', p, q, p, one,
307 $ u1, ldu1, work, ldx, zero, xf, ldx )
310 xf(i,i) = xf(i,i) - one
313 xf(min(p,q)-r+i,min(p,q)-r+i) =
314 $ xf(min(p,q)-r+i,min(p,q)-r+i) - cos(theta(i))
317 CALL dgemm(
'No transpose',
'Conjugate transpose', p, m-q, m-q,
318 $ one, xf(1,q+1), ldx, v2t, ldv2t, zero, work, ldx )
320 CALL dgemm(
'Conjugate transpose',
'No transpose', p, m-q, p,
321 $ one, u1, ldu1, work, ldx, zero, xf(1,q+1), ldx )
323 DO i = 1, min(p,m-q)-r
324 xf(p-i+1,m-i+1) = xf(p-i+1,m-i+1) + one
327 xf(p-(min(p,m-q)-r)+1-i,m-(min(p,m-q)-r)+1-i) =
328 $ xf(p-(min(p,m-q)-r)+1-i,m-(min(p,m-q)-r)+1-i) +
332 CALL dgemm(
'No transpose',
'Conjugate transpose', m-p, q, q, one,
333 $ xf(p+1,1), ldx, v1t, ldv1t, zero, work, ldx )
335 CALL dgemm(
'Conjugate transpose',
'No transpose', m-p, q, m-p,
336 $ one, u2, ldu2, work, ldx, zero, xf(p+1,1), ldx )
338 DO i = 1, min(m-p,q)-r
339 xf(m-i+1,q-i+1) = xf(m-i+1,q-i+1) - one
342 xf(m-(min(m-p,q)-r)+1-i,q-(min(m-p,q)-r)+1-i) =
343 $ xf(m-(min(m-p,q)-r)+1-i,q-(min(m-p,q)-r)+1-i) -
347 CALL dgemm(
'No transpose',
'Conjugate transpose', m-p, m-q, m-q,
348 $ one, xf(p+1,q+1), ldx, v2t, ldv2t, zero, work, ldx )
350 CALL dgemm(
'Conjugate transpose',
'No transpose', m-p, m-q, m-p,
351 $ one, u2, ldu2, work, ldx, zero, xf(p+1,q+1), ldx )
353 DO i = 1, min(m-p,m-q)-r
354 xf(p+i,q+i) = xf(p+i,q+i) - one
357 xf(p+(min(m-p,m-q)-r)+i,q+(min(m-p,m-q)-r)+i) =
358 $ xf(p+(min(m-p,m-q)-r)+i,q+(min(m-p,m-q)-r)+i) -
364 resid = dlange(
'1', p, q, xf, ldx, rwork )
365 result( 1 ) = ( resid / dble(max(1,p,q)) ) / eps2
369 resid = dlange(
'1', p, m-q, xf(1,q+1), ldx, rwork )
370 result( 2 ) = ( resid / dble(max(1,p,m-q)) ) / eps2
374 resid = dlange(
'1', m-p, q, xf(p+1,1), ldx, rwork )
375 result( 3 ) = ( resid / dble(max(1,m-p,q)) ) / eps2
379 resid = dlange(
'1', m-p, m-q, xf(p+1,q+1), ldx, rwork )
380 result( 4 ) = ( resid / dble(max(1,m-p,m-q)) ) / eps2
384 CALL dlaset(
'Full', p, p, zero, one, work, ldu1 )
385 CALL dsyrk(
'Upper',
'Conjugate transpose', p, p, -one, u1, ldu1,
390 resid = dlansy(
'1',
'Upper', p, work, ldu1, rwork )
391 result( 5 ) = ( resid / dble(max(1,p)) ) / ulp
395 CALL dlaset(
'Full', m-p, m-p, zero, one, work, ldu2 )
396 CALL dsyrk(
'Upper',
'Conjugate transpose', m-p, m-p, -one, u2,
397 $ ldu2, one, work, ldu2 )
401 resid = dlansy(
'1',
'Upper', m-p, work, ldu2, rwork )
402 result( 6 ) = ( resid / dble(max(1,m-p)) ) / ulp
406 CALL dlaset(
'Full', q, q, zero, one, work, ldv1t )
407 CALL dsyrk(
'Upper',
'No transpose', q, q, -one, v1t, ldv1t, one,
412 resid = dlansy(
'1',
'Upper', q, work, ldv1t, rwork )
413 result( 7 ) = ( resid / dble(max(1,q)) ) / ulp
417 CALL dlaset(
'Full', m-q, m-q, zero, one, work, ldv2t )
418 CALL dsyrk(
'Upper',
'No transpose', m-q, m-q, -one, v2t, ldv2t,
423 resid = dlansy(
'1',
'Upper', m-q, work, ldv2t, rwork )
424 result( 8 ) = ( resid / dble(max(1,m-q)) ) / ulp
428 result( 9 ) = realzero
430 IF( theta(i).LT.realzero .OR. theta(i).GT.piover2 )
THEN
434 IF ( theta(i).LT.theta(i-1) )
THEN
442 CALL dlaset(
'Full', q, q, zero, one, work, ldx )
443 CALL dsyrk(
'Upper',
'Conjugate transpose', q, m, -one, x, ldx,
447 $ dlange(
'1', q, q, work, ldx, rwork ) / dble( m ) )
451 r = min( p, m-p, q, m-q )
455 CALL dlacpy(
'Full', m, q, x, ldx, xf, ldx )
459 CALL dorcsd2by1(
'Y',
'Y',
'Y', m, p, q, xf(1,1), ldx, xf(p+1,1),
460 $ ldx, theta, u1, ldu1, u2, ldu2, v1t, ldv1t, work,
461 $ lwork, iwork, info )
465 CALL dgemm(
'No transpose',
'Conjugate transpose', p, q, q, one,
466 $ x, ldx, v1t, ldv1t, zero, work, ldx )
468 CALL dgemm(
'Conjugate transpose',
'No transpose', p, q, p, one,
469 $ u1, ldu1, work, ldx, zero, x, ldx )
472 x(i,i) = x(i,i) - one
475 x(min(p,q)-r+i,min(p,q)-r+i) =
476 $ x(min(p,q)-r+i,min(p,q)-r+i) - cos(theta(i))
479 CALL dgemm(
'No transpose',
'Conjugate transpose', m-p, q, q, one,
480 $ x(p+1,1), ldx, v1t, ldv1t, zero, work, ldx )
482 CALL dgemm(
'Conjugate transpose',
'No transpose', m-p, q, m-p,
483 $ one, u2, ldu2, work, ldx, zero, x(p+1,1), ldx )
485 DO i = 1, min(m-p,q)-r
486 x(m-i+1,q-i+1) = x(m-i+1,q-i+1) - one
489 x(m-(min(m-p,q)-r)+1-i,q-(min(m-p,q)-r)+1-i) =
490 $ x(m-(min(m-p,q)-r)+1-i,q-(min(m-p,q)-r)+1-i) -
496 resid = dlange(
'1', p, q, x, ldx, rwork )
497 result( 10 ) = ( resid / dble(max(1,p,q)) ) / eps2
501 resid = dlange(
'1', m-p, q, x(p+1,1), ldx, rwork )
502 result( 11 ) = ( resid / dble(max(1,m-p,q)) ) / eps2
506 CALL dlaset(
'Full', p, p, zero, one, work, ldu1 )
507 CALL dsyrk(
'Upper',
'Conjugate transpose', p, p, -one, u1, ldu1,
512 resid = dlansy(
'1',
'Upper', p, work, ldu1, rwork )
513 result( 12 ) = ( resid / dble(max(1,p)) ) / ulp
517 CALL dlaset(
'Full', m-p, m-p, zero, one, work, ldu2 )
518 CALL dsyrk(
'Upper',
'Conjugate transpose', m-p, m-p, -one, u2,
519 $ ldu2, one, work, ldu2 )
523 resid = dlansy(
'1',
'Upper', m-p, work, ldu2, rwork )
524 result( 13 ) = ( resid / dble(max(1,m-p)) ) / ulp
528 CALL dlaset(
'Full', q, q, zero, one, work, ldv1t )
529 CALL dsyrk(
'Upper',
'No transpose', q, q, -one, v1t, ldv1t, one,
534 resid = dlansy(
'1',
'Upper', q, work, ldv1t, rwork )
535 result( 14 ) = ( resid / dble(max(1,q)) ) / ulp
539 result( 15 ) = realzero
541 IF( theta(i).LT.realzero .OR. theta(i).GT.piover2 )
THEN
542 result( 15 ) = ulpinv
545 IF ( theta(i).LT.theta(i-1) )
THEN
546 result( 15 ) = ulpinv
subroutine dcsdts(m, p, q, x, xf, ldx, u1, ldu1, u2, ldu2, v1t, ldv1t, v2t, ldv2t, theta, iwork, work, lwork, rwork, result)
DCSDTS
subroutine dgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
DGEMM
subroutine dsyrk(uplo, trans, n, k, alpha, a, lda, beta, c, ldc)
DSYRK
subroutine dlacpy(uplo, m, n, a, lda, b, ldb)
DLACPY copies all or part of one two-dimensional array to another.
subroutine dlaset(uplo, m, n, alpha, beta, a, lda)
DLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine dorcsd2by1(jobu1, jobu2, jobv1t, m, p, q, x11, ldx11, x21, ldx21, theta, u1, ldu1, u2, ldu2, v1t, ldv1t, work, lwork, iwork, info)
DORCSD2BY1
recursive subroutine dorcsd(jobu1, jobu2, jobv1t, jobv2t, trans, signs, m, p, q, x11, ldx11, x12, ldx12, x21, ldx21, x22, ldx22, theta, u1, ldu1, u2, ldu2, v1t, ldv1t, v2t, ldv2t, work, lwork, iwork, info)
DORCSD