aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlangou <langou@users.noreply.github.com>2015-11-15 17:15:57 +0000
committerlangou <langou@users.noreply.github.com>2015-11-15 17:15:57 +0000
commite303516715b871b02f69af7d41b1c01f010c72e7 (patch)
tree4324e945125ca70fa4b63f64c163f8af21cb5414
parente5c236b03ae6f2c2af73a3331531825ca6b16e70 (diff)
integration of xGETRF2
-rw-r--r--SRC/Makefile8
-rw-r--r--SRC/cgetrf.f6
-rw-r--r--SRC/cgetrf2.f274
-rw-r--r--SRC/dgetrf.f6
-rw-r--r--SRC/dgetrf2.f272
-rw-r--r--SRC/sgetrf.f6
-rw-r--r--SRC/sgetrf2.f272
-rw-r--r--SRC/zgetrf.f6
-rw-r--r--SRC/zgetrf2.f274
9 files changed, 1108 insertions, 16 deletions
diff --git a/SRC/Makefile b/SRC/Makefile
index d78c6cf6..f2c67e01 100644
--- a/SRC/Makefile
+++ b/SRC/Makefile
@@ -97,7 +97,7 @@ DZLAUX = \
../INSTALL/dlamch.o ../INSTALL/dsecnd_$(TIMER).o
SLASRC = \
- sbdsvdx.o spotrf2.o \
+ sbdsvdx.o spotrf2.o sgetrf2.o \
sgbbrd.o sgbcon.o sgbequ.o sgbrfs.o sgbsv.o \
sgbsvx.o sgbtf2.o sgbtrf.o sgbtrs.o sgebak.o sgebal.o sgebd2.o \
sgebrd.o sgecon.o sgeequ.o sgees.o sgeesx.o sgeev.o sgeevx.o \
@@ -174,7 +174,7 @@ SXLASRC = sgesvxx.o sgerfsx.o sla_gerfsx_extended.o sla_geamv.o \
endif
CLASRC = \
- cpotrf2.o \
+ cpotrf2.o cgetrf2.o \
cbdsqr.o cgbbrd.o cgbcon.o cgbequ.o cgbrfs.o cgbsv.o cgbsvx.o \
cgbtf2.o cgbtrf.o cgbtrs.o cgebak.o cgebal.o cgebd2.o cgebrd.o \
cgecon.o cgeequ.o cgees.o cgeesx.o cgeev.o cgeevx.o \
@@ -262,7 +262,7 @@ endif
ZCLASRC = cpotrs.o cgetrs.o cpotrf.o cgetrf.o
DLASRC = \
- dpotrf2.o \
+ dpotrf2.o dgetrf2.o \
dbdsvdx.o \
dgbbrd.o dgbcon.o dgbequ.o dgbrfs.o dgbsv.o \
dgbsvx.o dgbtf2.o dgbtrf.o dgbtrs.o dgebak.o dgebal.o dgebd2.o \
@@ -339,7 +339,7 @@ DXLASRC = dgesvxx.o dgerfsx.o dla_gerfsx_extended.o dla_geamv.o \
endif
ZLASRC = \
- zpotrf2.o \
+ zpotrf2.o zgetrf2.o \
zbdsqr.o zgbbrd.o zgbcon.o zgbequ.o zgbrfs.o zgbsv.o zgbsvx.o \
zgbtf2.o zgbtrf.o zgbtrs.o zgebak.o zgebal.o zgebd2.o zgebrd.o \
zgecon.o zgeequ.o zgees.o zgeesx.o zgeev.o zgeevx.o \
diff --git a/SRC/cgetrf.f b/SRC/cgetrf.f
index 58817d87..f1960d62 100644
--- a/SRC/cgetrf.f
+++ b/SRC/cgetrf.f
@@ -131,7 +131,7 @@
INTEGER I, IINFO, J, JB, NB
* ..
* .. External Subroutines ..
- EXTERNAL CGEMM, CGETF2, CLASWP, CTRSM, XERBLA
+ EXTERNAL CGEMM, CGETRF2, CLASWP, CTRSM, XERBLA
* ..
* .. External Functions ..
INTEGER ILAENV
@@ -169,7 +169,7 @@
*
* Use unblocked code.
*
- CALL CGETF2( M, N, A, LDA, IPIV, INFO )
+ CALL CGETRF2( M, N, A, LDA, IPIV, INFO )
ELSE
*
* Use blocked code.
@@ -180,7 +180,7 @@
* Factor diagonal and subdiagonal blocks and test for exact
* singularity.
*
- CALL CGETF2( M-J+1, JB, A( J, J ), LDA, IPIV( J ), IINFO )
+ CALL CGETRF2( M-J+1, JB, A( J, J ), LDA, IPIV( J ), IINFO )
*
* Adjust INFO and the pivot indices.
*
diff --git a/SRC/cgetrf2.f b/SRC/cgetrf2.f
new file mode 100644
index 00000000..9e985d0e
--- /dev/null
+++ b/SRC/cgetrf2.f
@@ -0,0 +1,274 @@
+*> \brief \b CGETRF2
+*
+* =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+* http://www.netlib.org/lapack/explore-html/
+*
+* Definition:
+* ===========
+*
+* RECURSIVE SUBROUTINE CGETRF2( M, N, A, LDA, IPIV, INFO )
+*
+* .. Scalar Arguments ..
+* INTEGER INFO, LDA, M, N
+* ..
+* .. Array Arguments ..
+* INTEGER IPIV( * )
+* COMPLEX A( LDA, * )
+* ..
+*
+*
+*> \par Purpose:
+* =============
+*>
+*> \verbatim
+*>
+*> CGETRF2 computes an LU factorization of a general M-by-N matrix A
+*> using partial pivoting with row interchanges.
+*>
+*> The factorization has the form
+*> A = P * L * U
+*> where P is a permutation matrix, L is lower triangular with unit
+*> diagonal elements (lower trapezoidal if m > n), and U is upper
+*> triangular (upper trapezoidal if m < n).
+*>
+*> This is the recursive version of the algorithm. It divides
+*> the matrix into four submatrices:
+*>
+*> [ A11 | A12 ] where A11 is n1 by n1 and A22 is n2 by n2
+*> A = [ -----|----- ] with n1 = min(m,n)
+*> [ A21 | A22 ] n2 = n-n1
+*>
+*> [ A11 ]
+*> The subroutine calls itself to factor [ --- ],
+*> [ A12 ]
+*> [ A12 ]
+*> do the swaps on [ --- ], solve A12, update A22,
+*> [ A22 ]
+*>
+*> then calls itself to factor A22 and do the swaps on A21.
+*>
+*> \endverbatim
+*
+* Arguments:
+* ==========
+*
+*> \param[in] M
+*> \verbatim
+*> M is INTEGER
+*> The number of rows of the matrix A. M >= 0.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*> N is INTEGER
+*> The number of columns of the matrix A. N >= 0.
+*> \endverbatim
+*>
+*> \param[in,out] A
+*> \verbatim
+*> A is COMPLEX array, dimension (LDA,N)
+*> On entry, the M-by-N matrix to be factored.
+*> On exit, the factors L and U from the factorization
+*> A = P*L*U; the unit diagonal elements of L are not stored.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*> LDA is INTEGER
+*> The leading dimension of the array A. LDA >= max(1,M).
+*> \endverbatim
+*>
+*> \param[out] IPIV
+*> \verbatim
+*> IPIV is INTEGER array, dimension (min(M,N))
+*> The pivot indices; for 1 <= i <= min(M,N), row i of the
+*> matrix was interchanged with row IPIV(i).
+*> \endverbatim
+*>
+*> \param[out] INFO
+*> \verbatim
+*> INFO is INTEGER
+*> = 0: successful exit
+*> < 0: if INFO = -i, the i-th argument had an illegal value
+*> > 0: if INFO = i, U(i,i) is exactly zero. The factorization
+*> has been completed, but the factor U is exactly
+*> singular, and division by zero will occur if it is used
+*> to solve a system of equations.
+*> \endverbatim
+*
+* Authors:
+* ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date November 2015
+*
+*> \ingroup complexGEcomputational
+*
+* =====================================================================
+ RECURSIVE SUBROUTINE CGETRF2( M, N, A, LDA, IPIV, INFO )
+*
+* -- LAPACK computational routine (version 3.6.0) --
+* -- LAPACK is a software package provided by Univ. of Tennessee, --
+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+* November 2015
+*
+* .. Scalar Arguments ..
+ INTEGER INFO, LDA, M, N
+* ..
+* .. Array Arguments ..
+ INTEGER IPIV( * )
+ COMPLEX A( LDA, * )
+* ..
+*
+* =====================================================================
+*
+* .. Parameters ..
+ COMPLEX ONE, ZERO
+ PARAMETER ( ONE = ( 1.0E+0, 0.0E+0 ),
+ $ ZERO = ( 0.0E+0, 0.0E+0 ) )
+* ..
+* .. Local Scalars ..
+ REAL SFMIN
+ COMPLEX TEMP
+ INTEGER I, IINFO, N1, N2
+* ..
+* .. External Functions ..
+ REAL SLAMCH
+ INTEGER ICAMAX
+ EXTERNAL SLAMCH, ICAMAX
+* ..
+* .. External Subroutines ..
+ EXTERNAL CGEMM, CSCAL, CLASWP, CTRSM, XERBLA
+* ..
+* .. Intrinsic Functions ..
+ INTRINSIC MAX, MIN
+* ..
+* .. Executable Statements ..
+*
+* Test the input parameters
+*
+ INFO = 0
+ IF( M.LT.0 ) THEN
+ INFO = -1
+ ELSE IF( N.LT.0 ) THEN
+ INFO = -2
+ ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+ INFO = -4
+ END IF
+ IF( INFO.NE.0 ) THEN
+ CALL XERBLA( 'CGETRF2', -INFO )
+ RETURN
+ END IF
+*
+* Quick return if possible
+*
+ IF( M.EQ.0 .OR. N.EQ.0 )
+ $ RETURN
+
+ IF ( M.EQ.1 ) THEN
+*
+* Use unblocked code for one row case
+* Just need to handle IPIV and INFO
+*
+ IPIV( 1 ) = 1
+ IF ( A(1,1).EQ.ZERO )
+ $ INFO = 1
+*
+ ELSE IF( N.EQ.1 ) THEN
+*
+* Use unblocked code for one column case
+*
+*
+* Compute machine safe minimum
+*
+ SFMIN = SLAMCH('S')
+*
+* Find pivot and test for singularity
+*
+ I = ICAMAX( M, A( 1, 1 ), 1 )
+ IPIV( 1 ) = I
+ IF( A( I, 1 ).NE.ZERO ) THEN
+*
+* Apply the interchange
+*
+ IF( I.NE.1 ) THEN
+ TEMP = A( 1, 1 )
+ A( 1, 1 ) = A( I, 1 )
+ A( I, 1 ) = TEMP
+ END IF
+*
+* Compute elements 2:M of the column
+*
+ IF( ABS(A( 1, 1 )) .GE. SFMIN ) THEN
+ CALL CSCAL( M-1, ONE / A( 1, 1 ), A( 2, 1 ), 1 )
+ ELSE
+ DO 10 I = 1, M-1
+ A( 1+I, 1 ) = A( 1+I, 1 ) / A( 1, 1 )
+ 10 CONTINUE
+ END IF
+*
+ ELSE
+ INFO = 1
+ END IF
+*
+ ELSE
+*
+* Use recursive code
+*
+ N1 = MIN( M, N ) / 2
+ N2 = N-N1
+*
+* [ A11 ]
+* Factor [ --- ]
+* [ A21 ]
+*
+ CALL CGETRF2( M, N1, A, LDA, IPIV, IINFO )
+
+ IF ( INFO.EQ.0 .AND. IINFO.GT.0 )
+ $ INFO = IINFO
+*
+* [ A12 ]
+* Apply interchanges to [ --- ]
+* [ A22 ]
+*
+ CALL CLASWP( N2, A( 1, N1+1 ), LDA, 1, N1, IPIV, 1 )
+*
+* Solve A12
+*
+ CALL CTRSM( 'L', 'L', 'N', 'U', N1, N2, ONE, A, LDA,
+ $ A( 1, N1+1 ), LDA )
+*
+* Update A22
+*
+ CALL CGEMM( 'N', 'N', M-N1, N2, N1, -ONE, A( N1+1, 1 ), LDA,
+ $ A( 1, N1+1 ), LDA, ONE, A( N1+1, N1+1 ), LDA )
+*
+* Factor A22
+*
+ CALL CGETRF2( M-N1, N2, A( N1+1, N1+1 ), LDA, IPIV( N1+1 ),
+ $ IINFO )
+*
+* Adjust INFO and the pivot indices
+*
+ IF ( INFO.EQ.0 .AND. IINFO.GT.0 )
+ $ INFO = IINFO + N1
+ DO 20 I = N1+1, MIN( M, N )
+ IPIV( I ) = IPIV( I ) + N1
+ 20 CONTINUE
+*
+* Apply interchanges to A21
+*
+ CALL CLASWP( N1, A( 1, 1 ), LDA, N1+1, MIN( M, N), IPIV, 1 )
+*
+ END IF
+ RETURN
+*
+* End of CGETRF2
+*
+ END
diff --git a/SRC/dgetrf.f b/SRC/dgetrf.f
index 45bb97f3..b8940bc1 100644
--- a/SRC/dgetrf.f
+++ b/SRC/dgetrf.f
@@ -131,7 +131,7 @@
INTEGER I, IINFO, J, JB, NB
* ..
* .. External Subroutines ..
- EXTERNAL DGEMM, DGETF2, DLASWP, DTRSM, XERBLA
+ EXTERNAL DGEMM, DGETRF2, DLASWP, DTRSM, XERBLA
* ..
* .. External Functions ..
INTEGER ILAENV
@@ -169,7 +169,7 @@
*
* Use unblocked code.
*
- CALL DGETF2( M, N, A, LDA, IPIV, INFO )
+ CALL DGETRF2( M, N, A, LDA, IPIV, INFO )
ELSE
*
* Use blocked code.
@@ -180,7 +180,7 @@
* Factor diagonal and subdiagonal blocks and test for exact
* singularity.
*
- CALL DGETF2( M-J+1, JB, A( J, J ), LDA, IPIV( J ), IINFO )
+ CALL DGETRF2( M-J+1, JB, A( J, J ), LDA, IPIV( J ), IINFO )
*
* Adjust INFO and the pivot indices.
*
diff --git a/SRC/dgetrf2.f b/SRC/dgetrf2.f
new file mode 100644
index 00000000..b1871b5d
--- /dev/null
+++ b/SRC/dgetrf2.f
@@ -0,0 +1,272 @@
+*> \brief \b DGETRF2
+*
+* =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+* http://www.netlib.org/lapack/explore-html/
+*
+* Definition:
+* ===========
+*
+* RECURSIVE SUBROUTINE DGETRF2( M, N, A, LDA, IPIV, INFO )
+*
+* .. Scalar Arguments ..
+* INTEGER INFO, LDA, M, N
+* ..
+* .. Array Arguments ..
+* INTEGER IPIV( * )
+* DOUBLE PRECISION A( LDA, * )
+* ..
+*
+*
+*> \par Purpose:
+* =============
+*>
+*> \verbatim
+*>
+*> DGETRF2 computes an LU factorization of a general M-by-N matrix A
+*> using partial pivoting with row interchanges.
+*>
+*> The factorization has the form
+*> A = P * L * U
+*> where P is a permutation matrix, L is lower triangular with unit
+*> diagonal elements (lower trapezoidal if m > n), and U is upper
+*> triangular (upper trapezoidal if m < n).
+*>
+*> This is the recursive version of the algorithm. It divides
+*> the matrix into four submatrices:
+*>
+*> [ A11 | A12 ] where A11 is n1 by n1 and A22 is n2 by n2
+*> A = [ -----|----- ] with n1 = min(m,n)
+*> [ A21 | A22 ] n2 = n-n1
+*>
+*> [ A11 ]
+*> The subroutine calls itself to factor [ --- ],
+*> [ A12 ]
+*> [ A12 ]
+*> do the swaps on [ --- ], solve A12, update A22,
+*> [ A22 ]
+*>
+*> then calls itself to factor A22 and do the swaps on A21.
+*>
+*> \endverbatim
+*
+* Arguments:
+* ==========
+*
+*> \param[in] M
+*> \verbatim
+*> M is INTEGER
+*> The number of rows of the matrix A. M >= 0.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*> N is INTEGER
+*> The number of columns of the matrix A. N >= 0.
+*> \endverbatim
+*>
+*> \param[in,out] A
+*> \verbatim
+*> A is DOUBLE PRECISION array, dimension (LDA,N)
+*> On entry, the M-by-N matrix to be factored.
+*> On exit, the factors L and U from the factorization
+*> A = P*L*U; the unit diagonal elements of L are not stored.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*> LDA is INTEGER
+*> The leading dimension of the array A. LDA >= max(1,M).
+*> \endverbatim
+*>
+*> \param[out] IPIV
+*> \verbatim
+*> IPIV is INTEGER array, dimension (min(M,N))
+*> The pivot indices; for 1 <= i <= min(M,N), row i of the
+*> matrix was interchanged with row IPIV(i).
+*> \endverbatim
+*>
+*> \param[out] INFO
+*> \verbatim
+*> INFO is INTEGER
+*> = 0: successful exit
+*> < 0: if INFO = -i, the i-th argument had an illegal value
+*> > 0: if INFO = i, U(i,i) is exactly zero. The factorization
+*> has been completed, but the factor U is exactly
+*> singular, and division by zero will occur if it is used
+*> to solve a system of equations.
+*> \endverbatim
+*
+* Authors:
+* ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date November 2015
+*
+*> \ingroup doubleGEcomputational
+*
+* =====================================================================
+ RECURSIVE SUBROUTINE DGETRF2( M, N, A, LDA, IPIV, INFO )
+*
+* -- LAPACK computational routine (version 3.6.0) --
+* -- LAPACK is a software package provided by Univ. of Tennessee, --
+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+* November 2015
+*
+* .. Scalar Arguments ..
+ INTEGER INFO, LDA, M, N
+* ..
+* .. Array Arguments ..
+ INTEGER IPIV( * )
+ DOUBLE PRECISION A( LDA, * )
+* ..
+*
+* =====================================================================
+*
+* .. Parameters ..
+ DOUBLE PRECISION ONE, ZERO
+ PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+* ..
+* .. Local Scalars ..
+ DOUBLE PRECISION SFMIN, TEMP
+ INTEGER I, IINFO, N1, N2
+* ..
+* .. External Functions ..
+ DOUBLE PRECISION DLAMCH
+ INTEGER IDAMAX
+ EXTERNAL DLAMCH, IDAMAX
+* ..
+* .. External Subroutines ..
+ EXTERNAL DGEMM, DSCAL, DLASWP, DTRSM, XERBLA
+* ..
+* .. Intrinsic Functions ..
+ INTRINSIC MAX, MIN
+* ..
+* .. Executable Statements ..
+*
+* Test the input parameters
+*
+ INFO = 0
+ IF( M.LT.0 ) THEN
+ INFO = -1
+ ELSE IF( N.LT.0 ) THEN
+ INFO = -2
+ ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+ INFO = -4
+ END IF
+ IF( INFO.NE.0 ) THEN
+ CALL XERBLA( 'DGETRF2', -INFO )
+ RETURN
+ END IF
+*
+* Quick return if possible
+*
+ IF( M.EQ.0 .OR. N.EQ.0 )
+ $ RETURN
+
+ IF ( M.EQ.1 ) THEN
+*
+* Use unblocked code for one row case
+* Just need to handle IPIV and INFO
+*
+ IPIV( 1 ) = 1
+ IF ( A(1,1).EQ.ZERO )
+ $ INFO = 1
+*
+ ELSE IF( N.EQ.1 ) THEN
+*
+* Use unblocked code for one column case
+*
+*
+* Compute machine safe minimum
+*
+ SFMIN = DLAMCH('S')
+*
+* Find pivot and test for singularity
+*
+ I = IDAMAX( M, A( 1, 1 ), 1 )
+ IPIV( 1 ) = I
+ IF( A( I, 1 ).NE.ZERO ) THEN
+*
+* Apply the interchange
+*
+ IF( I.NE.1 ) THEN
+ TEMP = A( 1, 1 )
+ A( 1, 1 ) = A( I, 1 )
+ A( I, 1 ) = TEMP
+ END IF
+*
+* Compute elements 2:M of the column
+*
+ IF( ABS(A( 1, 1 )) .GE. SFMIN ) THEN
+ CALL DSCAL( M-1, ONE / A( 1, 1 ), A( 2, 1 ), 1 )
+ ELSE
+ DO 10 I = 1, M-1
+ A( 1+I, 1 ) = A( 1+I, 1 ) / A( 1, 1 )
+ 10 CONTINUE
+ END IF
+*
+ ELSE
+ INFO = 1
+ END IF
+*
+ ELSE
+*
+* Use recursive code
+*
+ N1 = MIN( M, N ) / 2
+ N2 = N-N1
+*
+* [ A11 ]
+* Factor [ --- ]
+* [ A21 ]
+*
+ CALL DGETRF2( M, N1, A, LDA, IPIV, IINFO )
+
+ IF ( INFO.EQ.0 .AND. IINFO.GT.0 )
+ $ INFO = IINFO
+*
+* [ A12 ]
+* Apply interchanges to [ --- ]
+* [ A22 ]
+*
+ CALL DLASWP( N2, A( 1, N1+1 ), LDA, 1, N1, IPIV, 1 )
+*
+* Solve A12
+*
+ CALL DTRSM( 'L', 'L', 'N', 'U', N1, N2, ONE, A, LDA,
+ $ A( 1, N1+1 ), LDA )
+*
+* Update A22
+*
+ CALL DGEMM( 'N', 'N', M-N1, N2, N1, -ONE, A( N1+1, 1 ), LDA,
+ $ A( 1, N1+1 ), LDA, ONE, A( N1+1, N1+1 ), LDA )
+*
+* Factor A22
+*
+ CALL DGETRF2( M-N1, N2, A( N1+1, N1+1 ), LDA, IPIV( N1+1 ),
+ $ IINFO )
+*
+* Adjust INFO and the pivot indices
+*
+ IF ( INFO.EQ.0 .AND. IINFO.GT.0 )
+ $ INFO = IINFO + N1
+ DO 20 I = N1+1, MIN( M, N )
+ IPIV( I ) = IPIV( I ) + N1
+ 20 CONTINUE
+*
+* Apply interchanges to A21
+*
+ CALL DLASWP( N1, A( 1, 1 ), LDA, N1+1, MIN( M, N), IPIV, 1 )
+*
+ END IF
+ RETURN
+*
+* End of DGETRF2
+*
+ END
diff --git a/SRC/sgetrf.f b/SRC/sgetrf.f
index b7ac344d..c5779838 100644
--- a/SRC/sgetrf.f
+++ b/SRC/sgetrf.f
@@ -131,7 +131,7 @@
INTEGER I, IINFO, J, JB, NB
* ..
* .. External Subroutines ..
- EXTERNAL SGEMM, SGETF2, SLASWP, STRSM, XERBLA
+ EXTERNAL SGEMM, SGETRF2, SLASWP, STRSM, XERBLA
* ..
* .. External Functions ..
INTEGER ILAENV
@@ -169,7 +169,7 @@
*
* Use unblocked code.
*
- CALL SGETF2( M, N, A, LDA, IPIV, INFO )
+ CALL SGETRF2( M, N, A, LDA, IPIV, INFO )
ELSE
*
* Use blocked code.
@@ -180,7 +180,7 @@
* Factor diagonal and subdiagonal blocks and test for exact
* singularity.
*
- CALL SGETF2( M-J+1, JB, A( J, J ), LDA, IPIV( J ), IINFO )
+ CALL SGETRF2( M-J+1, JB, A( J, J ), LDA, IPIV( J ), IINFO )
*
* Adjust INFO and the pivot indices.
*
diff --git a/SRC/sgetrf2.f b/SRC/sgetrf2.f
new file mode 100644
index 00000000..068710b7
--- /dev/null
+++ b/SRC/sgetrf2.f
@@ -0,0 +1,272 @@
+*> \brief \b SGETRF2
+*
+* =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+* http://www.netlib.org/lapack/explore-html/
+*
+* Definition:
+* ===========
+*
+* RECURSIVE SUBROUTINE SGETRF2( M, N, A, LDA, IPIV, INFO )
+*
+* .. Scalar Arguments ..
+* INTEGER INFO, LDA, M, N
+* ..
+* .. Array Arguments ..
+* INTEGER IPIV( * )
+* REAL A( LDA, * )
+* ..
+*
+*
+*> \par Purpose:
+* =============
+*>
+*> \verbatim
+*>
+*> SGETRF2 computes an LU factorization of a general M-by-N matrix A
+*> using partial pivoting with row interchanges.
+*>
+*> The factorization has the form
+*> A = P * L * U
+*> where P is a permutation matrix, L is lower triangular with unit
+*> diagonal elements (lower trapezoidal if m > n), and U is upper
+*> triangular (upper trapezoidal if m < n).
+*>
+*> This is the recursive version of the algorithm. It divides
+*> the matrix into four submatrices:
+*>
+*> [ A11 | A12 ] where A11 is n1 by n1 and A22 is n2 by n2
+*> A = [ -----|----- ] with n1 = min(m,n)
+* [ A21 | A22 ] n2 = n-n1
+*>
+*> [ A11 ]
+*> The subroutine calls itself to factor [ --- ],
+*> [ A12 ]
+*> [ A12 ]
+*> do the swaps on [ --- ], solve A12, update A22,
+*> [ A22 ]
+*>
+*> then calls itself to factor A22 and do the swaps on A21.
+*>
+*> \endverbatim
+*
+* Arguments:
+* ==========
+*
+*> \param[in] M
+*> \verbatim
+*> M is INTEGER
+*> The number of rows of the matrix A. M >= 0.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*> N is INTEGER
+*> The number of columns of the matrix A. N >= 0.
+*> \endverbatim
+*>
+*> \param[in,out] A
+*> \verbatim
+*> A is REAL array, dimension (LDA,N)
+*> On entry, the M-by-N matrix to be factored.
+*> On exit, the factors L and U from the factorization
+*> A = P*L*U; the unit diagonal elements of L are not stored.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*> LDA is INTEGER
+*> The leading dimension of the array A. LDA >= max(1,M).
+*> \endverbatim
+*>
+*> \param[out] IPIV
+*> \verbatim
+*> IPIV is INTEGER array, dimension (min(M,N))
+*> The pivot indices; for 1 <= i <= min(M,N), row i of the
+*> matrix was interchanged with row IPIV(i).
+*> \endverbatim
+*>
+*> \param[out] INFO
+*> \verbatim
+*> INFO is INTEGER
+*> = 0: successful exit
+*> < 0: if INFO = -i, the i-th argument had an illegal value
+*> > 0: if INFO = i, U(i,i) is exactly zero. The factorization
+*> has been completed, but the factor U is exactly
+*> singular, and division by zero will occur if it is used
+*> to solve a system of equations.
+*> \endverbatim
+*
+* Authors:
+* ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date November 2015
+*
+*> \ingroup realGEcomputational
+*
+* =====================================================================
+ RECURSIVE SUBROUTINE SGETRF2( M, N, A, LDA, IPIV, INFO )
+*
+* -- LAPACK computational routine (version 3.6.0) --
+* -- LAPACK is a software package provided by Univ. of Tennessee, --
+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+* November 2015
+*
+* .. Scalar Arguments ..
+ INTEGER INFO, LDA, M, N
+* ..
+* .. Array Arguments ..
+ INTEGER IPIV( * )
+ REAL A( LDA, * )
+* ..
+*
+* =====================================================================
+*
+* .. Parameters ..
+ REAL ONE, ZERO
+ PARAMETER ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+* ..
+* .. Local Scalars ..
+ REAL SFMIN, TEMP
+ INTEGER I, IINFO, n1, n2
+* ..
+* .. External Functions ..
+ REAL SLAMCH
+ INTEGER ISAMAX
+ EXTERNAL SLAMCH, ISAMAX
+* ..
+* .. External Subroutines ..
+ EXTERNAL SGEMM, SSCAL, SLASWP, STRSM, XERBLA
+* ..
+* .. Intrinsic Functions ..
+ INTRINSIC MAX, MIN
+* ..
+* .. Executable Statements ..
+*
+* Test the input parameters
+*
+ INFO = 0
+ IF( M.LT.0 ) THEN
+ INFO = -1
+ ELSE IF( N.LT.0 ) THEN
+ INFO = -2
+ ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+ INFO = -4
+ END IF
+ IF( INFO.NE.0 ) THEN
+ CALL XERBLA( 'SGETRF2', -INFO )
+ RETURN
+ END IF
+*
+* Quick return if possible
+*
+ IF( M.EQ.0 .OR. N.EQ.0 )
+ $ RETURN
+
+ IF ( M.EQ.1 ) THEN
+*
+* Use unblocked code for one row case
+* Just need to handle IPIV and INFO
+*
+ IPIV( 1 ) = 1
+ IF ( A(1,1).EQ.ZERO )
+ $ INFO = 1
+*
+ ELSE IF( N.EQ.1 ) THEN
+*
+* Use unblocked code for one column case
+*
+*
+* Compute machine safe minimum
+*
+ SFMIN = SLAMCH('S')
+*
+* Find pivot and test for singularity
+*
+ I = ISAMAX( M, A( 1, 1 ), 1 )
+ IPIV( 1 ) = I
+ IF( A( I, 1 ).NE.ZERO ) THEN
+*
+* Apply the interchange
+*
+ IF( I.NE.1 ) THEN
+ TEMP = A( 1, 1 )
+ A( 1, 1 ) = A( I, 1 )
+ A( I, 1 ) = TEMP
+ END IF
+*
+* Compute elements 2:M of the column
+*
+ IF( ABS(A( 1, 1 )) .GE. SFMIN ) THEN
+ CALL SSCAL( M-1, ONE / A( 1, 1 ), A( 2, 1 ), 1 )
+ ELSE
+ DO 10 I = 1, M-1
+ A( 1+I, 1 ) = A( 1+I, 1 ) / A( 1, 1 )
+ 10 CONTINUE
+ END IF
+*
+ ELSE
+ INFO = 1
+ END IF
+*
+ ELSE
+*
+* Use recursive code
+*
+ N1 = MIN( M, N ) / 2
+ N2 = N-N1
+*
+* [ A11 ]
+* Factor [ --- ]
+* [ A21 ]
+*
+ CALL SGETRF2( m, n1, A, lda, ipiv, iinfo )
+
+ IF ( info.EQ.0 .AND. iinfo.GT.0 )
+ $ info = iinfo
+*
+* [ A12 ]
+* Apply interchanges to [ --- ]
+* [ A22 ]
+*
+ CALL SLASWP( N2, A( 1, N1+1 ), LDA, 1, N1, IPIV, 1 )
+*
+* Solve A12
+*
+ CALL STRSM( 'L', 'L', 'N', 'U', N1, N2, ONE, A, LDA,
+ $ A( 1, N1+1 ), LDA )
+*
+* Update A22
+*
+ CALL SGEMM( 'N', 'N', M-N1, N2, N1, -ONE, A( N1+1, 1 ), LDA,
+ $ A( 1, N1+1 ), LDA, ONE, A( N1+1, N1+1 ), LDA )
+*
+* Factor A22
+*
+ CALL SGETRF2( M-N1, N2, A( N1+1, N1+1 ), LDA, IPIV( N1+1 ),
+ $ IINFO )
+*
+* Adjust INFO and the pivot indices
+*
+ IF ( INFO.EQ.0 .AND. IINFO.GT.0 )
+ $ INFO = IINFO + N1
+ DO 20 I = N1+1, MIN( M, N )
+ IPIV( I ) = IPIV( I ) + N1
+ 20 CONTINUE
+*
+* Apply interchanges to A21
+*
+ CALL SLASWP( N1, A( 1, 1 ), LDA, N1+1, MIN( M, N), IPIV, 1 )
+*
+ END IF
+ RETURN
+*
+* End of SGETRF2
+*
+ END
diff --git a/SRC/zgetrf.f b/SRC/zgetrf.f
index 5428a8ff..a8ff39ce 100644
--- a/SRC/zgetrf.f
+++ b/SRC/zgetrf.f
@@ -131,7 +131,7 @@
INTEGER I, IINFO, J, JB, NB
* ..
* .. External Subroutines ..
- EXTERNAL XERBLA, ZGEMM, ZGETF2, ZLASWP, ZTRSM
+ EXTERNAL XERBLA, ZGEMM, ZGETRF2, ZLASWP, ZTRSM
* ..
* .. External Functions ..
INTEGER ILAENV
@@ -169,7 +169,7 @@
*
* Use unblocked code.
*
- CALL ZGETF2( M, N, A, LDA, IPIV, INFO )
+ CALL ZGETRF2( M, N, A, LDA, IPIV, INFO )
ELSE
*
* Use blocked code.
@@ -180,7 +180,7 @@
* Factor diagonal and subdiagonal blocks and test for exact
* singularity.
*
- CALL ZGETF2( M-J+1, JB, A( J, J ), LDA, IPIV( J ), IINFO )
+ CALL ZGETRF2( M-J+1, JB, A( J, J ), LDA, IPIV( J ), IINFO )
*
* Adjust INFO and the pivot indices.
*
diff --git a/SRC/zgetrf2.f b/SRC/zgetrf2.f
new file mode 100644
index 00000000..290d4847
--- /dev/null
+++ b/SRC/zgetrf2.f
@@ -0,0 +1,274 @@
+*> \brief \b ZGETRF2
+*
+* =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+* http://www.netlib.org/lapack/explore-html/
+*
+* Definition:
+* ===========
+*
+* RECURSIVE SUBROUTINE ZGETRF2( M, N, A, LDA, IPIV, INFO )
+*
+* .. Scalar Arguments ..
+* INTEGER INFO, LDA, M, N
+* ..
+* .. Array Arguments ..
+* INTEGER IPIV( * )
+* COMPLEX*16 A( LDA, * )
+* ..
+*
+*
+*> \par Purpose:
+* =============
+*>
+*> \verbatim
+*>
+*> ZGETRF2 computes an LU factorization of a general M-by-N matrix A
+*> using partial pivoting with row interchanges.
+*>
+*> The factorization has the form
+*> A = P * L * U
+*> where P is a permutation matrix, L is lower triangular with unit
+*> diagonal elements (lower trapezoidal if m > n), and U is upper
+*> triangular (upper trapezoidal if m < n).
+*>
+*> This is the recursive version of the algorithm. It divides
+*> the matrix into four submatrices:
+*>
+*> [ A11 | A12 ] where A11 is n1 by n1 and A22 is n2 by n2
+*> A = [ -----|----- ] with n1 = min(m,n)
+*> [ A21 | A22 ] n2 = n-n1
+*>
+*> [ A11 ]
+*> The subroutine calls itself to factor [ --- ],
+*> [ A12 ]
+*> [ A12 ]
+*> do the swaps on [ --- ], solve A12, update A22,
+*> [ A22 ]
+*>
+*> then calls itself to factor A22 and do the swaps on A21.
+*>
+*> \endverbatim
+*
+* Arguments:
+* ==========
+*
+*> \param[in] M
+*> \verbatim
+*> M is INTEGER
+*> The number of rows of the matrix A. M >= 0.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*> N is INTEGER
+*> The number of columns of the matrix A. N >= 0.
+*> \endverbatim
+*>
+*> \param[in,out] A
+*> \verbatim
+*> A is COMPLEX*16 array, dimension (LDA,N)
+*> On entry, the M-by-N matrix to be factored.
+*> On exit, the factors L and U from the factorization
+*> A = P*L*U; the unit diagonal elements of L are not stored.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*> LDA is INTEGER
+*> The leading dimension of the array A. LDA >= max(1,M).
+*> \endverbatim
+*>
+*> \param[out] IPIV
+*> \verbatim
+*> IPIV is INTEGER array, dimension (min(M,N))
+*> The pivot indices; for 1 <= i <= min(M,N), row i of the
+*> matrix was interchanged with row IPIV(i).
+*> \endverbatim
+*>
+*> \param[out] INFO
+*> \verbatim
+*> INFO is INTEGER
+*> = 0: successful exit
+*> < 0: if INFO = -i, the i-th argument had an illegal value
+*> > 0: if INFO = i, U(i,i) is exactly zero. The factorization
+*> has been completed, but the factor U is exactly
+*> singular, and division by zero will occur if it is used
+*> to solve a system of equations.
+*> \endverbatim
+*
+* Authors:
+* ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date November 2015
+*
+*> \ingroup complex16GEcomputational
+*
+* =====================================================================
+ RECURSIVE SUBROUTINE ZGETRF2( M, N, A, LDA, IPIV, INFO )
+*
+* -- LAPACK computational routine (version 3.6.0) --
+* -- LAPACK is a software package provided by Univ. of Tennessee, --
+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+* November 2015
+*
+* .. Scalar Arguments ..
+ INTEGER INFO, LDA, M, N
+* ..
+* .. Array Arguments ..
+ INTEGER IPIV( * )
+ COMPLEX*16 A( LDA, * )
+* ..
+*
+* =====================================================================
+*
+* .. Parameters ..
+ COMPLEX*16 ONE, ZERO
+ PARAMETER ( ONE = ( 1.0D+0, 0.0D+0 ),
+ $ ZERO = ( 0.0D+0, 0.0D+0 ) )
+* ..
+* .. Local Scalars ..
+ DOUBLE PRECISION SFMIN
+ COMPLEX*16 TEMP
+ INTEGER I, IINFO, N1, N2
+* ..
+* .. External Functions ..
+ DOUBLE PRECISION DLAMCH
+ INTEGER IZAMAX
+ EXTERNAL DLAMCH, IZAMAX
+* ..
+* .. External Subroutines ..
+ EXTERNAL ZGEMM, ZSCAL, ZLASWP, ZTRSM, ZERBLA
+* ..
+* .. Intrinsic Functions ..
+ INTRINSIC MAX, MIN
+* ..
+* .. Executable Statements ..
+*
+* Test the input parameters
+*
+ INFO = 0
+ IF( M.LT.0 ) THEN
+ INFO = -1
+ ELSE IF( N.LT.0 ) THEN
+ INFO = -2
+ ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
+ INFO = -4
+ END IF
+ IF( INFO.NE.0 ) THEN
+ CALL XERBLA( 'ZGETRF2', -INFO )
+ RETURN
+ END IF
+*
+* Quick return if possible
+*
+ IF( M.EQ.0 .OR. N.EQ.0 )
+ $ RETURN
+
+ IF ( M.EQ.1 ) THEN
+*
+* Use unblocked code for one row case
+* Just need to handle IPIV and INFO
+*
+ IPIV( 1 ) = 1
+ IF ( A(1,1).EQ.ZERO )
+ $ INFO = 1
+*
+ ELSE IF( N.EQ.1 ) THEN
+*
+* Use unblocked code for one column case
+*
+*
+* Compute machine safe minimum
+*
+ SFMIN = DLAMCH('S')
+*
+* Find pivot and test for singularity
+*
+ I = IZAMAX( M, A( 1, 1 ), 1 )
+ IPIV( 1 ) = I
+ IF( A( I, 1 ).NE.ZERO ) THEN
+*
+* Apply the interchange
+*
+ IF( I.NE.1 ) THEN
+ TEMP = A( 1, 1 )
+ A( 1, 1 ) = A( I, 1 )
+ A( I, 1 ) = TEMP
+ END IF
+*
+* Compute elements 2:M of the column
+*
+ IF( ABS(A( 1, 1 )) .GE. SFMIN ) THEN
+ CALL ZSCAL( M-1, ONE / A( 1, 1 ), A( 2, 1 ), 1 )
+ ELSE
+ DO 10 I = 1, M-1
+ A( 1+I, 1 ) = A( 1+I, 1 ) / A( 1, 1 )
+ 10 CONTINUE
+ END IF
+*
+ ELSE
+ INFO = 1
+ END IF
+
+ ELSE
+*
+* Use recursive code
+*
+ N1 = MIN( M, N ) / 2
+ N2 = N-N1
+*
+* [ A11 ]
+* Factor [ --- ]
+* [ A21 ]
+*
+ CALL ZGETRF2( M, N1, A, LDA, IPIV, IINFO )
+
+ IF ( INFO.EQ.0 .AND. IINFO.GT.0 )
+ $ INFO = IINFO
+*
+* [ A12 ]
+* Apply interchanges to [ --- ]
+* [ A22 ]
+*
+ CALL ZLASWP( N2, A( 1, N1+1 ), LDA, 1, N1, IPIV, 1 )
+*
+* Solve A12
+*
+ CALL ZTRSM( 'L', 'L', 'N', 'U', N1, N2, ONE, A, LDA,
+ $ A( 1, N1+1 ), LDA )
+*
+* Update A22
+*
+ CALL ZGEMM( 'N', 'N', M-N1, N2, N1, -ONE, A( N1+1, 1 ), LDA,
+ $ A( 1, N1+1 ), LDA, ONE, A( N1+1, N1+1 ), LDA )
+*
+* Factor A22
+*
+ CALL ZGETRF2( M-N1, N2, A( N1+1, N1+1 ), LDA, IPIV( N1+1 ),
+ $ IINFO )
+*
+* Adjust INFO and the pivot indices
+*
+ IF ( INFO.EQ.0 .AND. IINFO.GT.0 )
+ $ INFO = IINFO + N1
+ DO 20 I = N1+1, MIN( M, N )
+ IPIV( I ) = IPIV( I ) + N1
+ 20 CONTINUE
+*
+* Apply interchanges to A21
+*
+ CALL ZLASWP( N1, A( 1, 1 ), LDA, N1+1, MIN( M, N), IPIV, 1 )
+*
+ END IF
+ RETURN
+*
+* End of ZGETRF2
+*
+ END