203 SUBROUTINE ccsdts( M, P, Q, X, XF, LDX, U1, LDU1, U2, LDU2, V1T,
204 $ ldv1t, v2t, ldv2t, theta, iwork, work, lwork,
213 INTEGER ldx, ldu1, ldu2, ldv1t, ldv2t, lwork, m, p, q
217 REAL result( 9 ), rwork( * ), theta( * )
218 COMPLEX u1( ldu1, * ), u2( ldu2, * ), v1t( ldv1t, * ),
219 $ v2t( ldv2t, * ), work( lwork ), x( ldx, * ),
226 REAL piover2, realone, realzero
227 parameter( piover2 = 1.57079632679489662e0,
228 $ realone = 1.0e0, realzero = 0.0e0 )
230 parameter( zero = (0.0e0,0.0e0), one = (1.0e0,0.0e0) )
234 REAL eps2, resid, ulp, ulpinv
244 INTRINSIC REAL, max, min
248 ulp =
slamch(
'Precision' )
249 ulpinv = realone / ulp
250 CALL
claset(
'Full', m, m, zero, one, work, ldx )
251 CALL
cherk(
'Upper',
'Conjugate transpose', m, m, -realone,
252 $ x, ldx, realone, work, ldx )
255 $
clange(
'1', m, m, work, ldx, rwork ) /
REAL( M ) )
259 r = min( p, m-p, q, m-q )
263 CALL
clacpy(
'Full', m, m, x, ldx, xf, ldx )
267 CALL
cuncsd(
'Y',
'Y',
'Y',
'Y',
'N',
'D', m, p, q, xf(1,1), ldx,
268 $ xf(1,q+1), ldx, xf(p+1,1), ldx, xf(p+1,q+1), ldx,
269 $ theta, u1, ldu1, u2, ldu2, v1t, ldv1t, v2t, ldv2t,
270 $ work, lwork, rwork, 17*(r+2), iwork, info )
274 CALL
cgemm(
'No transpose',
'Conjugate transpose', p, q, q, one,
275 $ x, ldx, v1t, ldv1t, zero, work, ldx )
277 CALL
cgemm(
'Conjugate transpose',
'No transpose', p, q, p, one,
278 $ u1, ldu1, work, ldx, zero, x, ldx )
281 x(i,i) = x(i,i) - one
284 x(min(p,q)-r+i,min(p,q)-r+i) =
285 $ x(min(p,q)-r+i,min(p,q)-r+i) - cmplx( cos(theta(i)),
289 CALL
cgemm(
'No transpose',
'Conjugate transpose', p, m-q, m-q,
290 $ one, x(1,q+1), ldx, v2t, ldv2t, zero, work, ldx )
292 CALL
cgemm(
'Conjugate transpose',
'No transpose', p, m-q, p,
293 $ one, u1, ldu1, work, ldx, zero, x(1,q+1), ldx )
295 DO i = 1, min(p,m-q)-r
296 x(p-i+1,m-i+1) = x(p-i+1,m-i+1) + one
299 x(p-(min(p,m-q)-r)+1-i,m-(min(p,m-q)-r)+1-i) =
300 $ x(p-(min(p,m-q)-r)+1-i,m-(min(p,m-q)-r)+1-i) +
301 $ cmplx( sin(theta(r-i+1)), 0.0e0 )
304 CALL
cgemm(
'No transpose',
'Conjugate transpose', m-p, q, q, one,
305 $ x(p+1,1), ldx, v1t, ldv1t, zero, work, ldx )
307 CALL
cgemm(
'Conjugate transpose',
'No transpose', m-p, q, m-p,
308 $ one, u2, ldu2, work, ldx, zero, x(p+1,1), ldx )
310 DO i = 1, min(m-p,q)-r
311 x(m-i+1,q-i+1) = x(m-i+1,q-i+1) - one
314 x(m-(min(m-p,q)-r)+1-i,q-(min(m-p,q)-r)+1-i) =
315 $ x(m-(min(m-p,q)-r)+1-i,q-(min(m-p,q)-r)+1-i) -
316 $ cmplx( sin(theta(r-i+1)), 0.0e0 )
319 CALL
cgemm(
'No transpose',
'Conjugate transpose', m-p, m-q, m-q,
320 $ one, x(p+1,q+1), ldx, v2t, ldv2t, zero, work, ldx )
322 CALL
cgemm(
'Conjugate transpose',
'No transpose', m-p, m-q, m-p,
323 $ one, u2, ldu2, work, ldx, zero, x(p+1,q+1), ldx )
325 DO i = 1, min(m-p,m-q)-r
326 x(p+i,q+i) = x(p+i,q+i) - one
329 x(p+(min(m-p,m-q)-r)+i,q+(min(m-p,m-q)-r)+i) =
330 $ x(p+(min(m-p,m-q)-r)+i,q+(min(m-p,m-q)-r)+i) -
331 $ cmplx( cos(theta(i)), 0.0e0 )
336 resid =
clange(
'1', p, q, x, ldx, rwork )
337 result( 1 ) = ( resid /
REAL(MAX(1,P,Q)) ) / eps2
341 resid =
clange(
'1', p, m-q, x(1,q+1), ldx, rwork )
342 result( 2 ) = ( resid /
REAL(MAX(1,P,M-Q)) ) / eps2
346 resid =
clange(
'1', m-p, q, x(p+1,1), ldx, rwork )
347 result( 3 ) = ( resid /
REAL(MAX(1,M-P,Q)) ) / eps2
351 resid =
clange(
'1', m-p, m-q, x(p+1,q+1), ldx, rwork )
352 result( 4 ) = ( resid /
REAL(MAX(1,M-P,M-Q)) ) / eps2
356 CALL
claset(
'Full', p, p, zero, one, work, ldu1 )
357 CALL
cherk(
'Upper',
'Conjugate transpose', p, p, -realone,
358 $ u1, ldu1, realone, work, ldu1 )
362 resid =
clanhe(
'1',
'Upper', p, work, ldu1, rwork )
363 result( 5 ) = ( resid /
REAL(MAX(1,P)) ) / ulp
367 CALL
claset(
'Full', m-p, m-p, zero, one, work, ldu2 )
368 CALL
cherk(
'Upper',
'Conjugate transpose', m-p, m-p, -realone,
369 $ u2, ldu2, realone, work, ldu2 )
373 resid =
clanhe(
'1',
'Upper', m-p, work, ldu2, rwork )
374 result( 6 ) = ( resid /
REAL(MAX(1,M-P)) ) / ulp
378 CALL
claset(
'Full', q, q, zero, one, work, ldv1t )
379 CALL
cherk(
'Upper',
'No transpose', q, q, -realone,
380 $ v1t, ldv1t, realone, work, ldv1t )
384 resid =
clanhe(
'1',
'Upper', q, work, ldv1t, rwork )
385 result( 7 ) = ( resid /
REAL(MAX(1,Q)) ) / ulp
389 CALL
claset(
'Full', m-q, m-q, zero, one, work, ldv2t )
390 CALL
cherk(
'Upper',
'No transpose', m-q, m-q, -realone,
391 $ v2t, ldv2t, realone, work, ldv2t )
395 resid =
clanhe(
'1',
'Upper', m-q, work, ldv2t, rwork )
396 result( 8 ) = ( resid /
REAL(MAX(1,M-Q)) ) / ulp
402 IF( theta(i).LT.realzero .OR. theta(i).GT.piover2 )
THEN
406 IF ( theta(i).LT.theta(i-1) )
THEN