1 SUBROUTINE pssvdcmp( M, N, JOBTYPE, S, SC, U, UC, IU, JU, DESCU,
2 $ VT, VTC, IVT, JVT, DESCVT, THRESH, RESULT,
11 INTEGER IU, IVT, JOBTYPE, JU, JVT, LWORK, M, N
15 INTEGER DESCU( * ), DESCVT( * ), RESULT( * )
16 REAL S( * ), SC( * ), U( * ), UC( * ), VT( * ),
176 INTEGER BLOCK_CYCLIC_2D, DLEN_, DTYPE_, CTXT_, M_, N_,
177 $ , NB_, RSRC_, CSRC_, LLD_
178 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
179 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
180 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
183 INTEGER COLPTR, I, INFO, J, LWMIN, MYCOL, MYROW, NPCOL
185 REAL ACCUR, CMP, NORMDIFS, NORMDIFU, NORMDIFV,
190 REAL SLANGE, PSLAMCH, PSLANGE
191 EXTERNAL numroc, slange, pslamch, pslange
201 IF( block_cyclic_2d*csrc_*dlen_*dtype_*mb_*m_*n_*rsrc_.LT.0 )
216 IF( nprow.EQ.-1 )
THEN
219 CALL chk1mat( m, 1,
SIZE, sizepos, 1, 1, descu, 8, info )
220 CALL chk1mat(
SIZE, sizepos, n, 2, 1, 1, descvt, 11, info )
227 sizeq = numroc(
SIZE, descu( nb_ ), mycol, 0, npcol )
228 nq = numroc( n, descvt( nb_ ), mycol, 0, npcol )
229 lwmin =
max( sizeq, nq ) + 4
233 IF( lwork.LT.lwmin )
THEN
235 ELSE IF( thresh.LE.0 )
THEN
241 CALL pxerbla( descu( ctxt_ ),
'PSSVDCMP', -info )
245 ulp = pslamch( descu( ctxt_ ),
'P' )
249 norms = slange(
'1',
SIZE, 1, s,
SIZE, work )
251 sc( i ) = s( i ) - sc( i )
254 normdifs = slange(
'1',
SIZE, 1, sc,
SIZE, work )
255 accur = ulp*size*norms*thresh
257 IF( normdifs.GT.accur )
259 IF( normdifs.EQ.0 .AND. accur.EQ.0 )
THEN
262 normdifs = normdifs / accur
265 IF( jobtype.EQ.2 )
THEN
267 result( 5 ) = results
270 colptr = descu( lld_ )*( j-1 )
271 DO 20 i = 1, descu( lld_ )
272 uc( i+colptr ) = u( i+colptr ) - uc( i+colptr )
276 normdifu = pslange(
'1', m,
SIZE, uc, iu, ju, descu, work )
278 IF( normdifu.GE.accur )
280 IF( normdifu.EQ.0 .AND. accur.EQ.0 )
THEN
283 normdifu = normdifu / accur
286 ELSE IF( jobtype.EQ.3 )
THEN
288 result( 7 ) = results
291 colptr = descvt( lld_ )*( j-1 )
292 DO 40 i = 1, descvt( lld_ )
293 vtc( i+colptr ) = vt( i+colptr ) - vtc( i+colptr )
297 normdifv = pslange(
'1',
SIZE, n, vtc, ivt, jvt, descvt, work )
299 IF( normdifv.GE.accur )
302 IF( normdifv.EQ.0 .AND. accur.EQ.0 )
THEN
305 normdifv = normdifv / accur
308 ELSE IF( jobtype.EQ.4 )
THEN
310 result( 9 ) = results
314 cmp =
max( normdifv, normdifu )
315 delta =
max( cmp, normdifs )
subroutine pssvdcmp(m, n, jobtype, s, sc, u, uc, iu, ju, descu, vt, vtc, ivt, jvt, descvt, thresh, result, delta, work, lwork)