226 SUBROUTINE scsdts( 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 REAL RESULT( 15 ), RWORK( * ), THETA( * )
240 REAL U1( LDU1, * ), U2( LDU2, * ), V1T( LDV1T, * ),
241 $ v2t( ldv2t, * ), work( lwork ), x( ldx, * ),
248 REAL REALONE, REALZERO
249 PARAMETER ( REALONE = 1.0e0, realzero = 0.0e0 )
251 parameter( zero = 0.0e0, one = 1.0e0 )
253 parameter( piover2 = 1.57079632679489661923132169163975144210e0 )
257 REAL EPS2, RESID, ULP, ULPINV
260 REAL SLAMCH, SLANGE, SLANSY
261 EXTERNAL SLAMCH, SLANGE, SLANSY
268 INTRINSIC cos, max, min, real, sin
272 ulp = slamch(
'Precision' )
273 ulpinv = realone / ulp
277 CALL slaset(
'Full', m, m, zero, one, work, ldx )
278 CALL ssyrk(
'Upper',
'Conjugate transpose', m, m, -one, x, ldx,
282 $ slange(
'1', m, m, work, ldx, rwork ) / real( m ) )
286 r = min( p, m-p, q, m-q )
290 CALL slacpy(
'Full', m, m, x, ldx, xf, ldx )
294 CALL sorcsd(
'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 slacpy(
'Full', m, m, x, ldx, xf, ldx )
303 CALL sgemm(
'No transpose',
'Conjugate transpose', p, q, q, one,
304 $ xf, ldx, v1t, ldv1t, zero, work, ldx )
306 CALL sgemm(
'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 sgemm(
'No transpose',
'Conjugate transpose', p, m-q, m-q,
318 $ one, xf(1,q+1), ldx, v2t, ldv2t, zero, work, ldx )
320 CALL sgemm(
'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 sgemm(
'No transpose',
'Conjugate transpose', m-p, q, q, one,
333 $ xf(p+1,1), ldx, v1t, ldv1t, zero, work, ldx )
335 CALL sgemm(
'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 sgemm(
'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 sgemm(
'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 = slange(
'1', p, q, xf, ldx, rwork )
365 result( 1 ) = ( resid / real(max(1,p,q)) ) / eps2
369 resid = slange(
'1', p, m-q, xf(1,q+1), ldx, rwork )
370 result( 2 ) = ( resid / real(max(1,p,m-q)) ) / eps2
374 resid = slange(
'1', m-p, q, xf(p+1,1), ldx, rwork )
375 result( 3 ) = ( resid / real(max(1,m-p,q)) ) / eps2
379 resid = slange(
'1', m-p, m-q, xf(p+1,q+1), ldx, rwork )
380 result( 4 ) = ( resid / real(max(1,m-p,m-q)) ) / eps2
384 CALL slaset(
'Full', p, p, zero, one, work, ldu1 )
385 CALL ssyrk(
'Upper',
'Conjugate transpose', p, p, -one, u1, ldu1,
390 resid = slansy(
'1',
'Upper', p, work, ldu1, rwork )
391 result( 5 ) = ( resid / real(max(1,p)) ) / ulp
395 CALL slaset(
'Full', m-p, m-p, zero, one, work, ldu2 )
396 CALL ssyrk(
'Upper',
'Conjugate transpose', m-p, m-p, -one, u2,
397 $ ldu2, one, work, ldu2 )
401 resid = slansy(
'1',
'Upper', m-p, work, ldu2, rwork )
402 result( 6 ) = ( resid / real(max(1,m-p)) ) / ulp
406 CALL slaset(
'Full', q, q, zero, one, work, ldv1t )
407 CALL ssyrk(
'Upper',
'No transpose', q, q, -one, v1t, ldv1t, one,
412 resid = slansy(
'1',
'Upper', q, work, ldv1t, rwork )
413 result( 7 ) = ( resid / real(max(1,q)) ) / ulp
417 CALL slaset(
'Full', m-q, m-q, zero, one, work, ldv2t )
418 CALL ssyrk(
'Upper',
'No transpose', m-q, m-q, -one, v2t, ldv2t,
423 resid = slansy(
'1',
'Upper', m-q, work, ldv2t, rwork )
424 result( 8 ) = ( resid / real(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 slaset(
'Full', q, q, zero, one, work, ldx )
443 CALL ssyrk(
'Upper',
'Conjugate transpose', q, m, -one, x, ldx,
447 $ slange(
'1', q, q, work, ldx, rwork ) / real( m ) )
451 r = min( p, m-p, q, m-q )
455 CALL slacpy(
'Full', m, q, x, ldx, xf, ldx )
459 CALL sorcsd2by1(
'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 sgemm(
'No transpose',
'Conjugate transpose', p, q, q, one,
466 $ x, ldx, v1t, ldv1t, zero, work, ldx )
468 CALL sgemm(
'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 sgemm(
'No transpose',
'Conjugate transpose', m-p, q, q, one,
480 $ x(p+1,1), ldx, v1t, ldv1t, zero, work, ldx )
482 CALL sgemm(
'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 = slange(
'1', p, q, x, ldx, rwork )
497 result( 10 ) = ( resid / real(max(1,p,q)) ) / eps2
501 resid = slange(
'1', m-p, q, x(p+1,1), ldx, rwork )
502 result( 11 ) = ( resid / real(max(1,m-p,q)) ) / eps2
506 CALL slaset(
'Full', p, p, zero, one, work, ldu1 )
507 CALL ssyrk(
'Upper',
'Conjugate transpose', p, p, -one, u1, ldu1,
512 resid = slansy(
'1',
'Upper', p, work, ldu1, rwork )
513 result( 12 ) = ( resid / real(max(1,p)) ) / ulp
517 CALL slaset(
'Full', m-p, m-p, zero, one, work, ldu2 )
518 CALL ssyrk(
'Upper',
'Conjugate transpose', m-p, m-p, -one, u2,
519 $ ldu2, one, work, ldu2 )
523 resid = slansy(
'1',
'Upper', m-p, work, ldu2, rwork )
524 result( 13 ) = ( resid / real(max(1,m-p)) ) / ulp
528 CALL slaset(
'Full', q, q, zero, one, work, ldv1t )
529 CALL ssyrk(
'Upper',
'No transpose', q, q, -one, v1t, ldv1t, one,
534 resid = slansy(
'1',
'Upper', q, work, ldv1t, rwork )
535 result( 14 ) = ( resid / real(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 sgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
SGEMM
subroutine ssyrk(uplo, trans, n, k, alpha, a, lda, beta, c, ldc)
SSYRK
subroutine slacpy(uplo, m, n, a, lda, b, ldb)
SLACPY copies all or part of one two-dimensional array to another.
subroutine slaset(uplo, m, n, alpha, beta, a, lda)
SLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine sorcsd2by1(jobu1, jobu2, jobv1t, m, p, q, x11, ldx11, x21, ldx21, theta, u1, ldu1, u2, ldu2, v1t, ldv1t, work, lwork, iwork, info)
SORCSD2BY1
recursive subroutine sorcsd(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)
SORCSD
subroutine scsdts(m, p, q, x, xf, ldx, u1, ldu1, u2, ldu2, v1t, ldv1t, v2t, ldv2t, theta, iwork, work, lwork, rwork, result)
SCSDTS