LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
dsgesv.f
Go to the documentation of this file.
1*> \brief <b> DSGESV computes the solution to system of linear equations A * X = B for GE matrices</b> (mixed precision with iterative refinement)
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> Download DSGESV + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsgesv.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsgesv.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsgesv.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* SUBROUTINE DSGESV( N, NRHS, A, LDA, IPIV, B, LDB, X, LDX, WORK,
20* SWORK, ITER, INFO )
21*
22* .. Scalar Arguments ..
23* INTEGER INFO, ITER, LDA, LDB, LDX, N, NRHS
24* ..
25* .. Array Arguments ..
26* INTEGER IPIV( * )
27* REAL SWORK( * )
28* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), WORK( N, * ),
29* $ X( LDX, * )
30* ..
31*
32*
33*> \par Purpose:
34* =============
35*>
36*> \verbatim
37*>
38*> DSGESV computes the solution to a real system of linear equations
39*> A * X = B,
40*> where A is an N-by-N matrix and X and B are N-by-NRHS matrices.
41*>
42*> DSGESV first attempts to factorize the matrix in SINGLE PRECISION
43*> and use this factorization within an iterative refinement procedure
44*> to produce a solution with DOUBLE PRECISION normwise backward error
45*> quality (see below). If the approach fails the method switches to a
46*> DOUBLE PRECISION factorization and solve.
47*>
48*> The iterative refinement is not going to be a winning strategy if
49*> the ratio SINGLE PRECISION performance over DOUBLE PRECISION
50*> performance is too small. A reasonable strategy should take the
51*> number of right-hand sides and the size of the matrix into account.
52*> This might be done with a call to ILAENV in the future. Up to now, we
53*> always try iterative refinement.
54*>
55*> The iterative refinement process is stopped if
56*> ITER > ITERMAX
57*> or for all the RHS we have:
58*> RNRM < SQRT(N)*XNRM*ANRM*EPS*BWDMAX
59*> where
60*> o ITER is the number of the current iteration in the iterative
61*> refinement process
62*> o RNRM is the infinity-norm of the residual
63*> o XNRM is the infinity-norm of the solution
64*> o ANRM is the infinity-operator-norm of the matrix A
65*> o EPS is the machine epsilon returned by DLAMCH('Epsilon')
66*> The value ITERMAX and BWDMAX are fixed to 30 and 1.0D+00
67*> respectively.
68*> \endverbatim
69*
70* Arguments:
71* ==========
72*
73*> \param[in] N
74*> \verbatim
75*> N is INTEGER
76*> The number of linear equations, i.e., the order of the
77*> matrix A. N >= 0.
78*> \endverbatim
79*>
80*> \param[in] NRHS
81*> \verbatim
82*> NRHS is INTEGER
83*> The number of right hand sides, i.e., the number of columns
84*> of the matrix B. NRHS >= 0.
85*> \endverbatim
86*>
87*> \param[in,out] A
88*> \verbatim
89*> A is DOUBLE PRECISION array,
90*> dimension (LDA,N)
91*> On entry, the N-by-N coefficient matrix A.
92*> On exit, if iterative refinement has been successfully used
93*> (INFO = 0 and ITER >= 0, see description below), then A is
94*> unchanged, if double precision factorization has been used
95*> (INFO = 0 and ITER < 0, see description below), then the
96*> array A contains the factors L and U from the factorization
97*> A = P*L*U; the unit diagonal elements of L are not stored.
98*> \endverbatim
99*>
100*> \param[in] LDA
101*> \verbatim
102*> LDA is INTEGER
103*> The leading dimension of the array A. LDA >= max(1,N).
104*> \endverbatim
105*>
106*> \param[out] IPIV
107*> \verbatim
108*> IPIV is INTEGER array, dimension (N)
109*> The pivot indices that define the permutation matrix P;
110*> row i of the matrix was interchanged with row IPIV(i).
111*> Corresponds either to the single precision factorization
112*> (if INFO = 0 and ITER >= 0) or the double precision
113*> factorization (if INFO = 0 and ITER < 0).
114*> \endverbatim
115*>
116*> \param[in] B
117*> \verbatim
118*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)
119*> The N-by-NRHS right hand side matrix B.
120*> \endverbatim
121*>
122*> \param[in] LDB
123*> \verbatim
124*> LDB is INTEGER
125*> The leading dimension of the array B. LDB >= max(1,N).
126*> \endverbatim
127*>
128*> \param[out] X
129*> \verbatim
130*> X is DOUBLE PRECISION array, dimension (LDX,NRHS)
131*> If INFO = 0, the N-by-NRHS solution matrix X.
132*> \endverbatim
133*>
134*> \param[in] LDX
135*> \verbatim
136*> LDX is INTEGER
137*> The leading dimension of the array X. LDX >= max(1,N).
138*> \endverbatim
139*>
140*> \param[out] WORK
141*> \verbatim
142*> WORK is DOUBLE PRECISION array, dimension (N,NRHS)
143*> This array is used to hold the residual vectors.
144*> \endverbatim
145*>
146*> \param[out] SWORK
147*> \verbatim
148*> SWORK is REAL array, dimension (N*(N+NRHS))
149*> This array is used to use the single precision matrix and the
150*> right-hand sides or solutions in single precision.
151*> \endverbatim
152*>
153*> \param[out] ITER
154*> \verbatim
155*> ITER is INTEGER
156*> < 0: iterative refinement has failed, double precision
157*> factorization has been performed
158*> -1 : the routine fell back to full precision for
159*> implementation- or machine-specific reasons
160*> -2 : narrowing the precision induced an overflow,
161*> the routine fell back to full precision
162*> -3 : failure of SGETRF
163*> -31: stop the iterative refinement after the 30th
164*> iterations
165*> > 0: iterative refinement has been successfully used.
166*> Returns the number of iterations
167*> \endverbatim
168*>
169*> \param[out] INFO
170*> \verbatim
171*> INFO is INTEGER
172*> = 0: successful exit
173*> < 0: if INFO = -i, the i-th argument had an illegal value
174*> > 0: if INFO = i, U(i,i) computed in DOUBLE PRECISION is
175*> exactly zero. The factorization has been completed,
176*> but the factor U is exactly singular, so the solution
177*> could not be computed.
178*> \endverbatim
179*
180* Authors:
181* ========
182*
183*> \author Univ. of Tennessee
184*> \author Univ. of California Berkeley
185*> \author Univ. of Colorado Denver
186*> \author NAG Ltd.
187*
188*> \ingroup gesv_mixed
189*
190* =====================================================================
191 SUBROUTINE dsgesv( N, NRHS, A, LDA, IPIV, B, LDB, X, LDX, WORK,
192 $ SWORK, ITER, INFO )
193*
194* -- LAPACK driver routine --
195* -- LAPACK is a software package provided by Univ. of Tennessee, --
196* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
197*
198* .. Scalar Arguments ..
199 INTEGER INFO, ITER, LDA, LDB, LDX, N, NRHS
200* ..
201* .. Array Arguments ..
202 INTEGER IPIV( * )
203 REAL SWORK( * )
204 DOUBLE PRECISION A( LDA, * ), B( LDB, * ), WORK( N, * ),
205 $ x( ldx, * )
206* ..
207*
208* =====================================================================
209*
210* .. Parameters ..
211 LOGICAL DOITREF
212 parameter( doitref = .true. )
213*
214 INTEGER ITERMAX
215 parameter( itermax = 30 )
216*
217 DOUBLE PRECISION BWDMAX
218 parameter( bwdmax = 1.0e+00 )
219*
220 DOUBLE PRECISION NEGONE, ONE
221 parameter( negone = -1.0d+0, one = 1.0d+0 )
222*
223* .. Local Scalars ..
224 INTEGER I, IITER, PTSA, PTSX
225 DOUBLE PRECISION ANRM, CTE, EPS, RNRM, XNRM
226*
227* .. External Subroutines ..
228 EXTERNAL daxpy, dgemm, dlacpy, dlag2s, dgetrf,
229 $ dgetrs,
231* ..
232* .. External Functions ..
233 INTEGER IDAMAX
234 DOUBLE PRECISION DLAMCH, DLANGE
235 EXTERNAL idamax, dlamch, dlange
236* ..
237* .. Intrinsic Functions ..
238 INTRINSIC abs, dble, max, sqrt
239* ..
240* .. Executable Statements ..
241*
242 info = 0
243 iter = 0
244*
245* Test the input parameters.
246*
247 IF( n.LT.0 ) THEN
248 info = -1
249 ELSE IF( nrhs.LT.0 ) THEN
250 info = -2
251 ELSE IF( lda.LT.max( 1, n ) ) THEN
252 info = -4
253 ELSE IF( ldb.LT.max( 1, n ) ) THEN
254 info = -7
255 ELSE IF( ldx.LT.max( 1, n ) ) THEN
256 info = -9
257 END IF
258 IF( info.NE.0 ) THEN
259 CALL xerbla( 'DSGESV', -info )
260 RETURN
261 END IF
262*
263* Quick return if (N.EQ.0).
264*
265 IF( n.EQ.0 )
266 $ RETURN
267*
268* Skip single precision iterative refinement if a priori slower
269* than double precision factorization.
270*
271 IF( .NOT.doitref ) THEN
272 iter = -1
273 GO TO 40
274 END IF
275*
276* Compute some constants.
277*
278 anrm = dlange( 'I', n, n, a, lda, work )
279 eps = dlamch( 'Epsilon' )
280 cte = anrm*eps*sqrt( dble( n ) )*bwdmax
281*
282* Set the indices PTSA, PTSX for referencing SA and SX in SWORK.
283*
284 ptsa = 1
285 ptsx = ptsa + n*n
286*
287* Convert B from double precision to single precision and store the
288* result in SX.
289*
290 CALL dlag2s( n, nrhs, b, ldb, swork( ptsx ), n, info )
291*
292 IF( info.NE.0 ) THEN
293 iter = -2
294 GO TO 40
295 END IF
296*
297* Convert A from double precision to single precision and store the
298* result in SA.
299*
300 CALL dlag2s( n, n, a, lda, swork( ptsa ), n, info )
301*
302 IF( info.NE.0 ) THEN
303 iter = -2
304 GO TO 40
305 END IF
306*
307* Compute the LU factorization of SA.
308*
309 CALL sgetrf( n, n, swork( ptsa ), n, ipiv, info )
310*
311 IF( info.NE.0 ) THEN
312 iter = -3
313 GO TO 40
314 END IF
315*
316* Solve the system SA*SX = SB.
317*
318 CALL sgetrs( 'No transpose', n, nrhs, swork( ptsa ), n, ipiv,
319 $ swork( ptsx ), n, info )
320*
321* Convert SX back to double precision
322*
323 CALL slag2d( n, nrhs, swork( ptsx ), n, x, ldx, info )
324*
325* Compute R = B - AX (R is WORK).
326*
327 CALL dlacpy( 'All', n, nrhs, b, ldb, work, n )
328*
329 CALL dgemm( 'No Transpose', 'No Transpose', n, nrhs, n, negone,
330 $ a,
331 $ lda, x, ldx, one, work, n )
332*
333* Check whether the NRHS normwise backward errors satisfy the
334* stopping criterion. If yes, set ITER=0 and return.
335*
336 DO i = 1, nrhs
337 xnrm = abs( x( idamax( n, x( 1, i ), 1 ), i ) )
338 rnrm = abs( work( idamax( n, work( 1, i ), 1 ), i ) )
339 IF( rnrm.GT.xnrm*cte )
340 $ GO TO 10
341 END DO
342*
343* If we are here, the NRHS normwise backward errors satisfy the
344* stopping criterion. We are good to exit.
345*
346 iter = 0
347 RETURN
348*
349 10 CONTINUE
350*
351 DO 30 iiter = 1, itermax
352*
353* Convert R (in WORK) from double precision to single precision
354* and store the result in SX.
355*
356 CALL dlag2s( n, nrhs, work, n, swork( ptsx ), n, info )
357*
358 IF( info.NE.0 ) THEN
359 iter = -2
360 GO TO 40
361 END IF
362*
363* Solve the system SA*SX = SR.
364*
365 CALL sgetrs( 'No transpose', n, nrhs, swork( ptsa ), n,
366 $ ipiv,
367 $ swork( ptsx ), n, info )
368*
369* Convert SX back to double precision and update the current
370* iterate.
371*
372 CALL slag2d( n, nrhs, swork( ptsx ), n, work, n, info )
373*
374 DO i = 1, nrhs
375 CALL daxpy( n, one, work( 1, i ), 1, x( 1, i ), 1 )
376 END DO
377*
378* Compute R = B - AX (R is WORK).
379*
380 CALL dlacpy( 'All', n, nrhs, b, ldb, work, n )
381*
382 CALL dgemm( 'No Transpose', 'No Transpose', n, nrhs, n,
383 $ negone,
384 $ a, lda, x, ldx, one, work, n )
385*
386* Check whether the NRHS normwise backward errors satisfy the
387* stopping criterion. If yes, set ITER=IITER>0 and return.
388*
389 DO i = 1, nrhs
390 xnrm = abs( x( idamax( n, x( 1, i ), 1 ), i ) )
391 rnrm = abs( work( idamax( n, work( 1, i ), 1 ), i ) )
392 IF( rnrm.GT.xnrm*cte )
393 $ GO TO 20
394 END DO
395*
396* If we are here, the NRHS normwise backward errors satisfy the
397* stopping criterion, we are good to exit.
398*
399 iter = iiter
400*
401 RETURN
402*
403 20 CONTINUE
404*
405 30 CONTINUE
406*
407* If we are at this place of the code, this is because we have
408* performed ITER=ITERMAX iterations and never satisfied the
409* stopping criterion, set up the ITER flag accordingly and follow up
410* on double precision routine.
411*
412 iter = -itermax - 1
413*
414 40 CONTINUE
415*
416* Single-precision iterative refinement failed to converge to a
417* satisfactory solution, so we resort to double precision.
418*
419 CALL dgetrf( n, n, a, lda, ipiv, info )
420*
421 IF( info.NE.0 )
422 $ RETURN
423*
424 CALL dlacpy( 'All', n, nrhs, b, ldb, x, ldx )
425 CALL dgetrs( 'No transpose', n, nrhs, a, lda, ipiv, x, ldx,
426 $ info )
427*
428 RETURN
429*
430* End of DSGESV
431*
432 END
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine dlag2s(m, n, a, lda, sa, ldsa, info)
DLAG2S converts a double precision matrix to a single precision matrix.
Definition dlag2s.f:106
subroutine slag2d(m, n, sa, ldsa, a, lda, info)
SLAG2D converts a single precision matrix to a double precision matrix.
Definition slag2d.f:102
subroutine daxpy(n, da, dx, incx, dy, incy)
DAXPY
Definition daxpy.f:89
subroutine dgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
DGEMM
Definition dgemm.f:188
subroutine dsgesv(n, nrhs, a, lda, ipiv, b, ldb, x, ldx, work, swork, iter, info)
DSGESV computes the solution to system of linear equations A * X = B for GE matrices (mixed precision...
Definition dsgesv.f:193
subroutine sgetrf(m, n, a, lda, ipiv, info)
SGETRF
Definition sgetrf.f:106
subroutine dgetrf(m, n, a, lda, ipiv, info)
DGETRF
Definition dgetrf.f:106
subroutine sgetrs(trans, n, nrhs, a, lda, ipiv, b, ldb, info)
SGETRS
Definition sgetrs.f:119
subroutine dgetrs(trans, n, nrhs, a, lda, ipiv, b, ldb, info)
DGETRS
Definition dgetrs.f:119
subroutine dlacpy(uplo, m, n, a, lda, b, ldb)
DLACPY copies all or part of one two-dimensional array to another.
Definition dlacpy.f:101