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
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
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.LT..OR..GT.
IF( THETA(I)REALZERO THETA(I)PIOVER2 ) THEN
542 RESULT( 15 ) = ULPINV
545.LT.
IF ( THETA(I)THETA(I-1) ) THEN
546 RESULT( 15 ) = ULPINV