LAPACK  3.4.2 LAPACK: Linear Algebra PACKage
sdrvls.f
Go to the documentation of this file.
1 *> \brief \b SDRVLS
2 *
3 * =========== DOCUMENTATION ===========
4 *
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
7 *
8 * Definition:
9 * ===========
10 *
11 * SUBROUTINE SDRVLS( DOTYPE, NM, MVAL, NN, NVAL, NNS, NSVAL, NNB,
12 * NBVAL, NXVAL, THRESH, TSTERR, A, COPYA, B,
13 * COPYB, C, S, COPYS, WORK, IWORK, NOUT )
14 *
15 * .. Scalar Arguments ..
16 * LOGICAL TSTERR
17 * INTEGER NM, NN, NNB, NNS, NOUT
18 * REAL THRESH
19 * ..
20 * .. Array Arguments ..
21 * LOGICAL DOTYPE( * )
22 * INTEGER IWORK( * ), MVAL( * ), NBVAL( * ), NSVAL( * ),
23 * \$ NVAL( * ), NXVAL( * )
24 * REAL A( * ), B( * ), C( * ), COPYA( * ), COPYB( * ),
25 * \$ COPYS( * ), S( * ), WORK( * )
26 * ..
27 *
28 *
29 *> \par Purpose:
30 * =============
31 *>
32 *> \verbatim
33 *>
34 *> SDRVLS tests the least squares driver routines SGELS, SGELSS, SGELSX,
35 *> SGELSY and SGELSD.
36 *> \endverbatim
37 *
38 * Arguments:
39 * ==========
40 *
41 *> \param[in] DOTYPE
42 *> \verbatim
43 *> DOTYPE is LOGICAL array, dimension (NTYPES)
44 *> The matrix types to be used for testing. Matrices of type j
45 *> (for 1 <= j <= NTYPES) are used for testing if DOTYPE(j) =
46 *> .TRUE.; if DOTYPE(j) = .FALSE., then type j is not used.
47 *> The matrix of type j is generated as follows:
48 *> j=1: A = U*D*V where U and V are random orthogonal matrices
49 *> and D has random entries (> 0.1) taken from a uniform
50 *> distribution (0,1). A is full rank.
51 *> j=2: The same of 1, but A is scaled up.
52 *> j=3: The same of 1, but A is scaled down.
53 *> j=4: A = U*D*V where U and V are random orthogonal matrices
54 *> and D has 3*min(M,N)/4 random entries (> 0.1) taken
55 *> from a uniform distribution (0,1) and the remaining
56 *> entries set to 0. A is rank-deficient.
57 *> j=5: The same of 4, but A is scaled up.
58 *> j=6: The same of 5, but A is scaled down.
59 *> \endverbatim
60 *>
61 *> \param[in] NM
62 *> \verbatim
63 *> NM is INTEGER
64 *> The number of values of M contained in the vector MVAL.
65 *> \endverbatim
66 *>
67 *> \param[in] MVAL
68 *> \verbatim
69 *> MVAL is INTEGER array, dimension (NM)
70 *> The values of the matrix row dimension M.
71 *> \endverbatim
72 *>
73 *> \param[in] NN
74 *> \verbatim
75 *> NN is INTEGER
76 *> The number of values of N contained in the vector NVAL.
77 *> \endverbatim
78 *>
79 *> \param[in] NVAL
80 *> \verbatim
81 *> NVAL is INTEGER array, dimension (NN)
82 *> The values of the matrix column dimension N.
83 *> \endverbatim
84 *>
85 *> \param[in] NNS
86 *> \verbatim
87 *> NNS is INTEGER
88 *> The number of values of NRHS contained in the vector NSVAL.
89 *> \endverbatim
90 *>
91 *> \param[in] NSVAL
92 *> \verbatim
93 *> NSVAL is INTEGER array, dimension (NNS)
94 *> The values of the number of right hand sides NRHS.
95 *> \endverbatim
96 *>
97 *> \param[in] NNB
98 *> \verbatim
99 *> NNB is INTEGER
100 *> The number of values of NB and NX contained in the
101 *> vectors NBVAL and NXVAL. The blocking parameters are used
102 *> in pairs (NB,NX).
103 *> \endverbatim
104 *>
105 *> \param[in] NBVAL
106 *> \verbatim
107 *> NBVAL is INTEGER array, dimension (NNB)
108 *> The values of the blocksize NB.
109 *> \endverbatim
110 *>
111 *> \param[in] NXVAL
112 *> \verbatim
113 *> NXVAL is INTEGER array, dimension (NNB)
114 *> The values of the crossover point NX.
115 *> \endverbatim
116 *>
117 *> \param[in] THRESH
118 *> \verbatim
119 *> THRESH is REAL
120 *> The threshold value for the test ratios. A result is
121 *> included in the output file if RESULT >= THRESH. To have
122 *> every test ratio printed, use THRESH = 0.
123 *> \endverbatim
124 *>
125 *> \param[in] TSTERR
126 *> \verbatim
127 *> TSTERR is LOGICAL
128 *> Flag that indicates whether error exits are to be tested.
129 *> \endverbatim
130 *>
131 *> \param[out] A
132 *> \verbatim
133 *> A is REAL array, dimension (MMAX*NMAX)
134 *> where MMAX is the maximum value of M in MVAL and NMAX is the
135 *> maximum value of N in NVAL.
136 *> \endverbatim
137 *>
138 *> \param[out] COPYA
139 *> \verbatim
140 *> COPYA is REAL array, dimension (MMAX*NMAX)
141 *> \endverbatim
142 *>
143 *> \param[out] B
144 *> \verbatim
145 *> B is REAL array, dimension (MMAX*NSMAX)
146 *> where MMAX is the maximum value of M in MVAL and NSMAX is the
147 *> maximum value of NRHS in NSVAL.
148 *> \endverbatim
149 *>
150 *> \param[out] COPYB
151 *> \verbatim
152 *> COPYB is REAL array, dimension (MMAX*NSMAX)
153 *> \endverbatim
154 *>
155 *> \param[out] C
156 *> \verbatim
157 *> C is REAL array, dimension (MMAX*NSMAX)
158 *> \endverbatim
159 *>
160 *> \param[out] S
161 *> \verbatim
162 *> S is REAL array, dimension
163 *> (min(MMAX,NMAX))
164 *> \endverbatim
165 *>
166 *> \param[out] COPYS
167 *> \verbatim
168 *> COPYS is REAL array, dimension
169 *> (min(MMAX,NMAX))
170 *> \endverbatim
171 *>
172 *> \param[out] WORK
173 *> \verbatim
174 *> WORK is REAL array,
175 *> dimension (MMAX*NMAX + 4*NMAX + MMAX).
176 *> \endverbatim
177 *>
178 *> \param[out] IWORK
179 *> \verbatim
180 *> IWORK is INTEGER array, dimension (15*NMAX)
181 *> \endverbatim
182 *>
183 *> \param[in] NOUT
184 *> \verbatim
185 *> NOUT is INTEGER
186 *> The unit number for output.
187 *> \endverbatim
188 *
189 * Authors:
190 * ========
191 *
192 *> \author Univ. of Tennessee
193 *> \author Univ. of California Berkeley
194 *> \author Univ. of Colorado Denver
195 *> \author NAG Ltd.
196 *
197 *> \date November 2011
198 *
199 *> \ingroup single_lin
200 *
201 * =====================================================================
202  SUBROUTINE sdrvls( DOTYPE, NM, MVAL, NN, NVAL, NNS, NSVAL, NNB,
203  \$ nbval, nxval, thresh, tsterr, a, copya, b,
204  \$ copyb, c, s, copys, work, iwork, nout )
205 *
206 * -- LAPACK test routine (version 3.4.0) --
207 * -- LAPACK is a software package provided by Univ. of Tennessee, --
208 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
209 * November 2011
210 *
211 * .. Scalar Arguments ..
212  LOGICAL tsterr
213  INTEGER nm, nn, nnb, nns, nout
214  REAL thresh
215 * ..
216 * .. Array Arguments ..
217  LOGICAL dotype( * )
218  INTEGER iwork( * ), mval( * ), nbval( * ), nsval( * ),
219  \$ nval( * ), nxval( * )
220  REAL a( * ), b( * ), c( * ), copya( * ), copyb( * ),
221  \$ copys( * ), s( * ), work( * )
222 * ..
223 *
224 * =====================================================================
225 *
226 * .. Parameters ..
227  INTEGER ntests
228  parameter( ntests = 18 )
229  INTEGER smlsiz
230  parameter( smlsiz = 25 )
231  REAL one, two, zero
232  parameter( one = 1.0e0, two = 2.0e0, zero = 0.0e0 )
233 * ..
234 * .. Local Scalars ..
235  CHARACTER trans
236  CHARACTER*3 path
237  INTEGER crank, i, im, in, inb, info, ins, irank,
238  \$ iscale, itran, itype, j, k, lda, ldb, ldwork,
239  \$ lwlsy, lwork, m, mnmin, n, nb, ncols, nerrs,
240  \$ nfail, nlvl, nrhs, nrows, nrun, rank
241  REAL eps, norma, normb, rcond
242 * ..
243 * .. Local Arrays ..
244  INTEGER iseed( 4 ), iseedy( 4 )
245  REAL result( ntests )
246 * ..
247 * .. External Functions ..
248  REAL sasum, slamch, sqrt12, sqrt14, sqrt17
249  EXTERNAL sasum, slamch, sqrt12, sqrt14, sqrt17
250 * ..
251 * .. External Subroutines ..
252  EXTERNAL alaerh, alahd, alasvm, saxpy, serrls, sgels,
255  \$ xlaenv
256 * ..
257 * .. Intrinsic Functions ..
258  INTRINSIC int, log, max, min, REAL, sqrt
259 * ..
260 * .. Scalars in Common ..
261  LOGICAL lerr, ok
262  CHARACTER*32 srnamt
263  INTEGER infot, iounit
264 * ..
265 * .. Common blocks ..
266  common / infoc / infot, iounit, ok, lerr
267  common / srnamc / srnamt
268 * ..
269 * .. Data statements ..
270  DATA iseedy / 1988, 1989, 1990, 1991 /
271 * ..
272 * .. Executable Statements ..
273 *
274 * Initialize constants and the random number seed.
275 *
276  path( 1: 1 ) = 'Single precision'
277  path( 2: 3 ) = 'LS'
278  nrun = 0
279  nfail = 0
280  nerrs = 0
281  DO 10 i = 1, 4
282  iseed( i ) = iseedy( i )
283  10 continue
284  eps = slamch( 'Epsilon' )
285 *
286 * Threshold for rank estimation
287 *
288  rcond = sqrt( eps ) - ( sqrt( eps )-eps ) / 2
289 *
290 * Test the error exits
291 *
292  CALL xlaenv( 2, 2 )
293  CALL xlaenv( 9, smlsiz )
294  IF( tsterr )
295  \$ CALL serrls( path, nout )
296 *
297 * Print the header if NM = 0 or NN = 0 and THRESH = 0.
298 *
299  IF( ( nm.EQ.0 .OR. nn.EQ.0 ) .AND. thresh.EQ.zero )
300  \$ CALL alahd( nout, path )
301  infot = 0
302 *
303  DO 150 im = 1, nm
304  m = mval( im )
305  lda = max( 1, m )
306 *
307  DO 140 in = 1, nn
308  n = nval( in )
309  mnmin = min( m, n )
310  ldb = max( 1, m, n )
311 *
312  DO 130 ins = 1, nns
313  nrhs = nsval( ins )
314  nlvl = max( int( log( max( one, REAL( MNMIN ) ) /
315  \$ REAL( SMLSIZ+1 ) ) / log( two ) ) + 1, 0 )
316  lwork = max( 1, ( m+nrhs )*( n+2 ), ( n+nrhs )*( m+2 ),
317  \$ m*n+4*mnmin+max( m, n ), 12*mnmin+2*mnmin*smlsiz+
318  \$ 8*mnmin*nlvl+mnmin*nrhs+(smlsiz+1)**2 )
319 *
320  DO 120 irank = 1, 2
321  DO 110 iscale = 1, 3
322  itype = ( irank-1 )*3 + iscale
323  IF( .NOT.dotype( itype ) )
324  \$ go to 110
325 *
326  IF( irank.EQ.1 ) THEN
327 *
328 * Test SGELS
329 *
330 * Generate a matrix of scaling type ISCALE
331 *
332  CALL sqrt13( iscale, m, n, copya, lda, norma,
333  \$ iseed )
334  DO 40 inb = 1, nnb
335  nb = nbval( inb )
336  CALL xlaenv( 1, nb )
337  CALL xlaenv( 3, nxval( inb ) )
338 *
339  DO 30 itran = 1, 2
340  IF( itran.EQ.1 ) THEN
341  trans = 'N'
342  nrows = m
343  ncols = n
344  ELSE
345  trans = 'T'
346  nrows = n
347  ncols = m
348  END IF
349  ldwork = max( 1, ncols )
350 *
351 * Set up a consistent rhs
352 *
353  IF( ncols.GT.0 ) THEN
354  CALL slarnv( 2, iseed, ncols*nrhs,
355  \$ work )
356  CALL sscal( ncols*nrhs,
357  \$ one / REAL( NCOLS ), work,
358  \$ 1 )
359  END IF
360  CALL sgemm( trans, 'No transpose', nrows,
361  \$ nrhs, ncols, one, copya, lda,
362  \$ work, ldwork, zero, b, ldb )
363  CALL slacpy( 'Full', nrows, nrhs, b, ldb,
364  \$ copyb, ldb )
365 *
366 * Solve LS or overdetermined system
367 *
368  IF( m.GT.0 .AND. n.GT.0 ) THEN
369  CALL slacpy( 'Full', m, n, copya, lda,
370  \$ a, lda )
371  CALL slacpy( 'Full', nrows, nrhs,
372  \$ copyb, ldb, b, ldb )
373  END IF
374  srnamt = 'SGELS '
375  CALL sgels( trans, m, n, nrhs, a, lda, b,
376  \$ ldb, work, lwork, info )
377  IF( info.NE.0 )
378  \$ CALL alaerh( path, 'SGELS ', info, 0,
379  \$ trans, m, n, nrhs, -1, nb,
380  \$ itype, nfail, nerrs,
381  \$ nout )
382 *
383 * Check correctness of results
384 *
385  ldwork = max( 1, nrows )
386  IF( nrows.GT.0 .AND. nrhs.GT.0 )
387  \$ CALL slacpy( 'Full', nrows, nrhs,
388  \$ copyb, ldb, c, ldb )
389  CALL sqrt16( trans, m, n, nrhs, copya,
390  \$ lda, b, ldb, c, ldb, work,
391  \$ result( 1 ) )
392 *
393  IF( ( itran.EQ.1 .AND. m.GE.n ) .OR.
394  \$ ( itran.EQ.2 .AND. m.LT.n ) ) THEN
395 *
396 * Solving LS system
397 *
398  result( 2 ) = sqrt17( trans, 1, m, n,
399  \$ nrhs, copya, lda, b, ldb,
400  \$ copyb, ldb, c, work,
401  \$ lwork )
402  ELSE
403 *
404 * Solving overdetermined system
405 *
406  result( 2 ) = sqrt14( trans, m, n,
407  \$ nrhs, copya, lda, b, ldb,
408  \$ work, lwork )
409  END IF
410 *
411 * Print information about the tests that
412 * did not pass the threshold.
413 *
414  DO 20 k = 1, 2
415  IF( result( k ).GE.thresh ) THEN
416  IF( nfail.EQ.0 .AND. nerrs.EQ.0 )
417  \$ CALL alahd( nout, path )
418  WRITE( nout, fmt = 9999 )trans, m,
419  \$ n, nrhs, nb, itype, k,
420  \$ result( k )
421  nfail = nfail + 1
422  END IF
423  20 continue
424  nrun = nrun + 2
425  30 continue
426  40 continue
427  END IF
428 *
429 * Generate a matrix of scaling type ISCALE and rank
430 * type IRANK.
431 *
432  CALL sqrt15( iscale, irank, m, n, nrhs, copya, lda,
433  \$ copyb, ldb, copys, rank, norma, normb,
434  \$ iseed, work, lwork )
435 *
436 * workspace used: MAX(M+MIN(M,N),NRHS*MIN(M,N),2*N+M)
437 *
438 * Initialize vector IWORK.
439 *
440  DO 50 j = 1, n
441  iwork( j ) = 0
442  50 continue
443  ldwork = max( 1, m )
444 *
445 * Test SGELSX
446 *
447 * SGELSX: Compute the minimum-norm solution X
448 * to min( norm( A * X - B ) ) using a complete
449 * orthogonal factorization.
450 *
451  CALL slacpy( 'Full', m, n, copya, lda, a, lda )
452  CALL slacpy( 'Full', m, nrhs, copyb, ldb, b, ldb )
453 *
454  srnamt = 'SGELSX'
455  CALL sgelsx( m, n, nrhs, a, lda, b, ldb, iwork,
456  \$ rcond, crank, work, info )
457  IF( info.NE.0 )
458  \$ CALL alaerh( path, 'SGELSX', info, 0, ' ', m, n,
459  \$ nrhs, -1, nb, itype, nfail, nerrs,
460  \$ nout )
461 *
462 * workspace used: MAX( MNMIN+3*N, 2*MNMIN+NRHS )
463 *
464 * Test 3: Compute relative error in svd
465 * workspace: M*N + 4*MIN(M,N) + MAX(M,N)
466 *
467  result( 3 ) = sqrt12( crank, crank, a, lda, copys,
468  \$ work, lwork )
469 *
470 * Test 4: Compute error in solution
471 * workspace: M*NRHS + M
472 *
473  CALL slacpy( 'Full', m, nrhs, copyb, ldb, work,
474  \$ ldwork )
475  CALL sqrt16( 'No transpose', m, n, nrhs, copya,
476  \$ lda, b, ldb, work, ldwork,
477  \$ work( m*nrhs+1 ), result( 4 ) )
478 *
479 * Test 5: Check norm of r'*A
480 * workspace: NRHS*(M+N)
481 *
482  result( 5 ) = zero
483  IF( m.GT.crank )
484  \$ result( 5 ) = sqrt17( 'No transpose', 1, m, n,
485  \$ nrhs, copya, lda, b, ldb, copyb,
486  \$ ldb, c, work, lwork )
487 *
488 * Test 6: Check if x is in the rowspace of A
489 * workspace: (M+NRHS)*(N+2)
490 *
491  result( 6 ) = zero
492 *
493  IF( n.GT.crank )
494  \$ result( 6 ) = sqrt14( 'No transpose', m, n,
495  \$ nrhs, copya, lda, b, ldb, work,
496  \$ lwork )
497 *
498 * Print information about the tests that did not
499 * pass the threshold.
500 *
501  DO 60 k = 3, 6
502  IF( result( k ).GE.thresh ) THEN
503  IF( nfail.EQ.0 .AND. nerrs.EQ.0 )
504  \$ CALL alahd( nout, path )
505  WRITE( nout, fmt = 9998 )m, n, nrhs, nb,
506  \$ itype, k, result( k )
507  nfail = nfail + 1
508  END IF
509  60 continue
510  nrun = nrun + 4
511 *
512 * Loop for testing different block sizes.
513 *
514  DO 100 inb = 1, nnb
515  nb = nbval( inb )
516  CALL xlaenv( 1, nb )
517  CALL xlaenv( 3, nxval( inb ) )
518 *
519 * Test SGELSY
520 *
521 * SGELSY: Compute the minimum-norm solution X
522 * to min( norm( A * X - B ) )
523 * using the rank-revealing orthogonal
524 * factorization.
525 *
526 * Initialize vector IWORK.
527 *
528  DO 70 j = 1, n
529  iwork( j ) = 0
530  70 continue
531 *
532 * Set LWLSY to the adequate value.
533 *
534  lwlsy = max( 1, mnmin+2*n+nb*( n+1 ),
535  \$ 2*mnmin+nb*nrhs )
536 *
537  CALL slacpy( 'Full', m, n, copya, lda, a, lda )
538  CALL slacpy( 'Full', m, nrhs, copyb, ldb, b,
539  \$ ldb )
540 *
541  srnamt = 'SGELSY'
542  CALL sgelsy( m, n, nrhs, a, lda, b, ldb, iwork,
543  \$ rcond, crank, work, lwlsy, info )
544  IF( info.NE.0 )
545  \$ CALL alaerh( path, 'SGELSY', info, 0, ' ', m,
546  \$ n, nrhs, -1, nb, itype, nfail,
547  \$ nerrs, nout )
548 *
549 * Test 7: Compute relative error in svd
550 * workspace: M*N + 4*MIN(M,N) + MAX(M,N)
551 *
552  result( 7 ) = sqrt12( crank, crank, a, lda,
553  \$ copys, work, lwork )
554 *
555 * Test 8: Compute error in solution
556 * workspace: M*NRHS + M
557 *
558  CALL slacpy( 'Full', m, nrhs, copyb, ldb, work,
559  \$ ldwork )
560  CALL sqrt16( 'No transpose', m, n, nrhs, copya,
561  \$ lda, b, ldb, work, ldwork,
562  \$ work( m*nrhs+1 ), result( 8 ) )
563 *
564 * Test 9: Check norm of r'*A
565 * workspace: NRHS*(M+N)
566 *
567  result( 9 ) = zero
568  IF( m.GT.crank )
569  \$ result( 9 ) = sqrt17( 'No transpose', 1, m,
570  \$ n, nrhs, copya, lda, b, ldb,
571  \$ copyb, ldb, c, work, lwork )
572 *
573 * Test 10: Check if x is in the rowspace of A
574 * workspace: (M+NRHS)*(N+2)
575 *
576  result( 10 ) = zero
577 *
578  IF( n.GT.crank )
579  \$ result( 10 ) = sqrt14( 'No transpose', m, n,
580  \$ nrhs, copya, lda, b, ldb,
581  \$ work, lwork )
582 *
583 * Test SGELSS
584 *
585 * SGELSS: Compute the minimum-norm solution X
586 * to min( norm( A * X - B ) )
587 * using the SVD.
588 *
589  CALL slacpy( 'Full', m, n, copya, lda, a, lda )
590  CALL slacpy( 'Full', m, nrhs, copyb, ldb, b,
591  \$ ldb )
592  srnamt = 'SGELSS'
593  CALL sgelss( m, n, nrhs, a, lda, b, ldb, s,
594  \$ rcond, crank, work, lwork, info )
595  IF( info.NE.0 )
596  \$ CALL alaerh( path, 'SGELSS', info, 0, ' ', m,
597  \$ n, nrhs, -1, nb, itype, nfail,
598  \$ nerrs, nout )
599 *
600 * workspace used: 3*min(m,n) +
601 * max(2*min(m,n),nrhs,max(m,n))
602 *
603 * Test 11: Compute relative error in svd
604 *
605  IF( rank.GT.0 ) THEN
606  CALL saxpy( mnmin, -one, copys, 1, s, 1 )
607  result( 11 ) = sasum( mnmin, s, 1 ) /
608  \$ sasum( mnmin, copys, 1 ) /
609  \$ ( eps*REAL( MNMIN ) )
610  ELSE
611  result( 11 ) = zero
612  END IF
613 *
614 * Test 12: Compute error in solution
615 *
616  CALL slacpy( 'Full', m, nrhs, copyb, ldb, work,
617  \$ ldwork )
618  CALL sqrt16( 'No transpose', m, n, nrhs, copya,
619  \$ lda, b, ldb, work, ldwork,
620  \$ work( m*nrhs+1 ), result( 12 ) )
621 *
622 * Test 13: Check norm of r'*A
623 *
624  result( 13 ) = zero
625  IF( m.GT.crank )
626  \$ result( 13 ) = sqrt17( 'No transpose', 1, m,
627  \$ n, nrhs, copya, lda, b, ldb,
628  \$ copyb, ldb, c, work, lwork )
629 *
630 * Test 14: Check if x is in the rowspace of A
631 *
632  result( 14 ) = zero
633  IF( n.GT.crank )
634  \$ result( 14 ) = sqrt14( 'No transpose', m, n,
635  \$ nrhs, copya, lda, b, ldb,
636  \$ work, lwork )
637 *
638 * Test SGELSD
639 *
640 * SGELSD: Compute the minimum-norm solution X
641 * to min( norm( A * X - B ) ) using a
642 * divide and conquer SVD.
643 *
644 * Initialize vector IWORK.
645 *
646  DO 80 j = 1, n
647  iwork( j ) = 0
648  80 continue
649 *
650  CALL slacpy( 'Full', m, n, copya, lda, a, lda )
651  CALL slacpy( 'Full', m, nrhs, copyb, ldb, b,
652  \$ ldb )
653 *
654  srnamt = 'SGELSD'
655  CALL sgelsd( m, n, nrhs, a, lda, b, ldb, s,
656  \$ rcond, crank, work, lwork, iwork,
657  \$ info )
658  IF( info.NE.0 )
659  \$ CALL alaerh( path, 'SGELSD', info, 0, ' ', m,
660  \$ n, nrhs, -1, nb, itype, nfail,
661  \$ nerrs, nout )
662 *
663 * Test 15: Compute relative error in svd
664 *
665  IF( rank.GT.0 ) THEN
666  CALL saxpy( mnmin, -one, copys, 1, s, 1 )
667  result( 15 ) = sasum( mnmin, s, 1 ) /
668  \$ sasum( mnmin, copys, 1 ) /
669  \$ ( eps*REAL( MNMIN ) )
670  ELSE
671  result( 15 ) = zero
672  END IF
673 *
674 * Test 16: Compute error in solution
675 *
676  CALL slacpy( 'Full', m, nrhs, copyb, ldb, work,
677  \$ ldwork )
678  CALL sqrt16( 'No transpose', m, n, nrhs, copya,
679  \$ lda, b, ldb, work, ldwork,
680  \$ work( m*nrhs+1 ), result( 16 ) )
681 *
682 * Test 17: Check norm of r'*A
683 *
684  result( 17 ) = zero
685  IF( m.GT.crank )
686  \$ result( 17 ) = sqrt17( 'No transpose', 1, m,
687  \$ n, nrhs, copya, lda, b, ldb,
688  \$ copyb, ldb, c, work, lwork )
689 *
690 * Test 18: Check if x is in the rowspace of A
691 *
692  result( 18 ) = zero
693  IF( n.GT.crank )
694  \$ result( 18 ) = sqrt14( 'No transpose', m, n,
695  \$ nrhs, copya, lda, b, ldb,
696  \$ work, lwork )
697 *
698 * Print information about the tests that did not
699 * pass the threshold.
700 *
701  DO 90 k = 7, ntests
702  IF( result( k ).GE.thresh ) THEN
703  IF( nfail.EQ.0 .AND. nerrs.EQ.0 )
704  \$ CALL alahd( nout, path )
705  WRITE( nout, fmt = 9998 )m, n, nrhs, nb,
706  \$ itype, k, result( k )
707  nfail = nfail + 1
708  END IF
709  90 continue
710  nrun = nrun + 12
711 *
712  100 continue
713  110 continue
714  120 continue
715  130 continue
716  140 continue
717  150 continue
718 *
719 * Print a summary of the results.
720 *
721  CALL alasvm( path, nout, nfail, nrun, nerrs )
722 *
723  9999 format( ' TRANS=''', a1, ''', M=', i5, ', N=', i5, ', NRHS=', i4,
724  \$ ', NB=', i4, ', type', i2, ', test(', i2, ')=', g12.5 )
725  9998 format( ' M=', i5, ', N=', i5, ', NRHS=', i4, ', NB=', i4,
726  \$ ', type', i2, ', test(', i2, ')=', g12.5 )
727  return
728 *
729 * End of SDRVLS
730 *
731  END