226 SUBROUTINE zcsdts( 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( * ), ( * )
240 COMPLEX*16 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 )
251 parameter( zero = (0.0d0,0.0d0), one = (1.0d0,0.0d0) )
252 DOUBLE PRECISION PIOVER2
253 parameter( piover2 = 1.57079632679489661923132169163975144210d0 )
257 DOUBLE PRECISION EPS2, RESID, ULP, ULPINV
260 DOUBLE PRECISION DLAMCH, ZLANGE, ZLANHE
261 EXTERNAL DLAMCH, ZLANGE, ZLANHE
268 INTRINSIC cos, dble, dcmplx,
max,
min, real, sin
272 ulp = dlamch(
'Precision' )
273 ulpinv = realone / ulp
277 CALL zlaset(
'Full', m, m, zero, one, work, ldx )
278 CALL zherk(
'Upper',
'Conjugate transpose', m, m, -realone,
279 $ x, ldx, realone, work, ldx )
282 $ zlange(
'1', m, m, work, ldx, rwork ) / dble( m ) )
286 r =
min( p, m-p, q, m-q )
290 CALL zlacpy(
'Full', m, m, x, ldx, xf, ldx )
294 CALL zuncsd(
'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, rwork, 17*(r+2), iwork, info )
301 CALL zlacpy(
'Full', m, m, x, ldx, xf, ldx )
303 CALL zgemm(
'No transpose',
'Conjugate transpose', p, q, q, one,
304 $ xf, ldx, v1t, ldv1t, zero, work, ldx )
306 CALL zgemm(
'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) - dcmplx( cos(theta(i)),
318 CALL zgemm(
'No transpose',
'Conjugate transpose', p, m-q, m-q,
319 $ one, xf(1,q+1), ldx, v2t, ldv2t, zero, work, ldx )
321 CALL zgemm(
'Conjugate transpose',
'No transpose', p, m-q, p,
322 $ one, u1, ldu1, work, ldx, zero, xf(1,q+1), ldx )
324 DO i = 1,
min(p,m-q)-r
325 xf(p-i+1,m-i+1) = xf(p-i+1,m-i+1) + one
328 xf(p-(
min(p,m-q)-r)+1-i,m-(
min(p,m-q)-r)+1-i) =
329 $ xf(p-(
min(p,m-q)-r)+1-i,m-(
min(p,m-q)-r)+1-i) +
330 $ dcmplx( sin(theta(r-i+1)), 0.0d0 )
333 CALL zgemm(
'No transpose',
'Conjugate transpose', m-p, q, q, one,
334 $ xf(p+1,1), ldx, v1t, ldv1t, zero, work, ldx )
336 CALL zgemm(
'Conjugate transpose',
'No transpose', m-p, q, m-p,
337 $ one, u2, ldu2, work, ldx, zero, xf(p+1,1), ldx )
339 DO i = 1,
min(m-p,q)-r
340 xf(m-i+1,q-i+1) = xf(m-i+1,q-i+1) - one
343 xf(m-(
min(m-p,q)-r)+1-i,q-(
min(m-p,q)-r)+1-i) =
344 $ xf(m-(
min(m-p,q)-r)+1-i,q-(
min(m-p,q)-r)+1-i) -
345 $ dcmplx( sin(theta(r-i+1)), 0.0d0 )
348 CALL zgemm(
'No transpose',
'Conjugate transpose', m-p, m-q, m-q,
349 $ one, xf(p+1,q+1), ldx, v2t, ldv2t, zero, work, ldx )
351 CALL zgemm(
'Conjugate transpose',
'No transpose', m-p, m-q, m-p,
352 $ one, u2, ldu2, work, ldx, zero, xf(p+1,q+1), ldx )
354 DO i = 1,
min(m-p,m-q)-r
355 xf(p+i,q+i) = xf(p+i,q+i) - one
359 $ xf(p+(
min(m-p,m-q)-r)+i,q+(
min(m-p,m-q)-r)+i) -
360 $ dcmplx( cos(theta(i)), 0.0d0 )
365 resid = zlange(
'1', p, q, xf, ldx, rwork )
366 result( 1 ) = ( resid / real(
max(1,p,q)) ) / eps2
370 resid = zlange(
'1', p, m-q, xf(1,q+1), ldx, rwork )
371 result( 2 ) = ( resid / real(
max(1,p,m-q)) ) / eps2
375 resid = zlange(
'1', m-p, q, xf(p+1,1), ldx, rwork )
376 result( 3 ) = ( resid / real(
max(1,m-p,q)) ) / eps2
380 resid = zlange(
'1', m-p, m-q, xf(p+1,q+1), ldx, rwork
381 result( 4 ) = ( resid / real(
max(1,m-p,m-q)) ) / eps2
385 CALL zlaset(
'Full', p, p, zero, one, work, ldu1 )
386 CALL zherk(
'Upper',
'Conjugate transpose', p, p, -realone,
387 $ u1, ldu1, realone, work, ldu1 )
391 resid = zlanhe(
'1',
'Upper', p, work, ldu1, rwork )
392 result( 5 ) = ( resid / real(
max(1,p)) ) / ulp
396 CALL zlaset(
'Full', m-p, m-p, zero, one, work, ldu2 )
397 CALL zherk(
'Upper',
'Conjugate transpose', m-p, m-p, -realone,
398 $ u2, ldu2, realone, work, ldu2 )
402 resid = zlanhe(
'1',
'Upper', m-p, work, ldu2, rwork )
403 result( 6 ) = ( resid / real(
max(1,m-p)) ) / ulp
407 CALL zlaset(
'Full', q, q, zero, one, work, ldv1t )
408 CALL zherk(
'Upper',
'No transpose', q, q, -realone,
409 $ v1t, ldv1t, realone, work, ldv1t )
413 resid = zlanhe(
'1',
'Upper', q, work, ldv1t, rwork )
414 result( 7 ) = ( resid / real(
max(1,q)) ) / ulp
418 CALL zlaset(
'Full', m-q, m-q, zero, one, work, ldv2t )
419 CALL zherk(
'Upper',
'No transpose', m-q, m-q, -realone,
420 $ v2t, ldv2t, realone, work, ldv2t )
424 resid = zlanhe(
'1',
'Upper', m-q, work, ldv2t, rwork )
425 result( 8 ) = ( resid / real(
max(1,m-q)) ) / ulp
429 result( 9 ) = realzero
431 IF( theta(i).LT.realzero .OR. theta(i).GT.piover2 )
THEN
435 IF ( theta(i).LT.theta(i-1) )
THEN
443 CALL zlaset(
'Full', q, q, zero, one, work, ldx )
444 CALL zherk(
'Upper',
'Conjugate transpose', q, m, -realone,
445 $ x, ldx, realone, work, ldx )
448 $ zlange( '1
', Q, Q, WORK, LDX, RWORK ) / DBLE( M ) )
452 R = MIN( P, M-P, Q, M-Q )
456 CALL ZLACPY( 'full
', M, M, X, LDX, XF, LDX )
460 CALL ZUNCSD2BY1( 'y
', 'y
', 'y
', M, P, Q, XF(1,1), LDX, XF(P+1,1),
461 $ LDX, THETA, U1, LDU1, U2, LDU2, V1T, LDV1T, WORK,
462 $ LWORK, RWORK, 17*(R+2), IWORK, INFO )
466 CALL ZGEMM( 'no transpose
', 'conjugate transpose
', P, Q, Q, ONE,
467 $ X, LDX, V1T, LDV1T, ZERO, WORK, LDX )
469 CALL ZGEMM( 'conjugate transpose
', 'no transpose
', P, Q, P, ONE,
470 $ U1, LDU1, WORK, LDX, ZERO, X, LDX )
473 X(I,I) = X(I,I) - ONE
476 X(MIN(P,Q)-R+I,MIN(P,Q)-R+I) =
477 $ X(MIN(P,Q)-R+I,MIN(P,Q)-R+I) - DCMPLX( COS(THETA(I)),
481 CALL ZGEMM( 'no transpose
', 'conjugate transpose
', M-P, Q, Q, ONE,
482 $ X(P+1,1), LDX, V1T, LDV1T, ZERO, WORK, LDX )
484 CALL ZGEMM( 'conjugate transpose
', 'no transpose
', M-P, Q, M-P,
485 $ ONE, U2, LDU2, WORK, LDX, ZERO, X(P+1,1), LDX )
487 DO I = 1, MIN(M-P,Q)-R
488 X(M-I+1,Q-I+1) = X(M-I+1,Q-I+1) - ONE
491 X(M-(MIN(M-P,Q)-R)+1-I,Q-(MIN(M-P,Q)-R)+1-I) =
492 $ X(M-(MIN(M-P,Q)-R)+1-I,Q-(MIN(M-P,Q)-R)+1-I) -
493 $ DCMPLX( SIN(THETA(R-I+1)), 0.0D0 )
498 RESID = ZLANGE( '1
', P, Q, X, LDX, RWORK )
499 RESULT( 10 ) = ( RESID / REAL(MAX(1,P,Q)) ) / EPS2
503 RESID = ZLANGE( '1
', M-P, Q, X(P+1,1), LDX, RWORK )
504 RESULT( 11 ) = ( RESID / REAL(MAX(1,M-P,Q)) ) / EPS2
508 CALL ZLASET( 'full
', P, P, ZERO, ONE, WORK, LDU1 )
509 CALL ZHERK( 'upper
', 'conjugate transpose
', P, P, -REALONE,
510 $ U1, LDU1, REALONE, WORK, LDU1 )
514 RESID = ZLANHE( '1
', 'upper
', P, WORK, LDU1, RWORK )
515 RESULT( 12 ) = ( RESID / REAL(MAX(1,P)) ) / ULP
519 CALL ZLASET( 'full
', M-P, M-P, ZERO, ONE, WORK, LDU2 )
520 CALL ZHERK( 'upper
', 'conjugate transpose
', M-P, M-P, -REALONE,
521 $ U2, LDU2, REALONE, WORK, LDU2 )
525 RESID = ZLANHE( '1
', 'upper
', M-P, WORK, LDU2, RWORK )
526 RESULT( 13 ) = ( RESID / REAL(MAX(1,M-P)) ) / ULP
530 CALL ZLASET( 'full
', Q, Q, ZERO, ONE, WORK, LDV1T )
531 CALL ZHERK( 'upper
', 'no transpose
', Q, Q, -REALONE,
532 $ V1T, LDV1T, REALONE, WORK, LDV1T )
536 RESID = ZLANHE( '1
', 'upper
', Q, WORK, LDV1T, RWORK )
537 RESULT( 14 ) = ( RESID / REAL(MAX(1,Q)) ) / ULP
541 RESULT( 15 ) = REALZERO
543.LT..OR..GT.
IF( THETA(I)REALZERO THETA(I)PIOVER2 ) THEN
544 RESULT( 15 ) = ULPINV
547.LT.
IF ( THETA(I)THETA(I-1) ) THEN
548 RESULT( 15 ) = ULPINV