Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 42 additions & 34 deletions lapack-netlib/SRC/cgels.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,6 @@ typedef struct Namelist Namelist;
*/




/* Table of constant values */

static complex c_b1 = {0.f,0.f};
Expand All @@ -242,7 +240,6 @@ static integer c__0 = 0;
/* Online html documentation available at */
/* http://www.netlib.org/lapack/explore-html/ */

/* > \htmlonly */
/* > Download CGELS + dependencies */
/* > <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/cgels.f
"> */
Expand All @@ -253,7 +250,6 @@ static integer c__0 = 0;
/* > <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/cgels.f
"> */
/* > [TXT]</a> */
/* > \endhtmlonly */

/* Definition: */
/* =========== */
Expand All @@ -273,7 +269,17 @@ static integer c__0 = 0;
/* > */
/* > CGELS solves overdetermined or underdetermined complex linear systems */
/* > involving an M-by-N matrix A, or its conjugate-transpose, using a QR */
/* > or LQ factorization of A. It is assumed that A has full rank. */
/* > or LQ factorization of A. */
/* > */
/* > It is assumed that A has full rank, and only a rudimentary protection */
/* > against rank-deficient matrices is provided. This subroutine only detects */
/* > exact rank-deficiency, where a diagonal element of the triangular factor */
/* > of A is exactly zero. */
/* > */
/* > It is conceivable for one (or more) of the diagonal elements of the triangular */
/* > factor of A to be subnormally tiny numbers without this subroutine signalling */
/* > an error. The solutions computed for such almost-rank-deficient matrices may */
/* > be less accurate due to a loss of numerical precision. */
/* > */
/* > The following options are provided: */
/* > */
Expand Down Expand Up @@ -397,7 +403,7 @@ static integer c__0 = 0;
/* > = 0: successful exit */
/* > < 0: if INFO = -i, the i-th argument had an illegal value */
/* > > 0: if INFO = i, the i-th diagonal element of the */
/* > triangular factor of A is zero, so that A does not have */
/* > triangular factor of A is exactly zero, so that A does not have */
/* > full rank; the least squares solution could not be */
/* > computed. */
/* > \endverbatim */
Expand All @@ -410,9 +416,7 @@ static integer c__0 = 0;
/* > \author Univ. of Colorado Denver */
/* > \author NAG Ltd. */

/* > \date December 2016 */

/* > \ingroup complexGEsolve */
/* > \ingroup gels */

/* ===================================================================== */
/* Subroutine */ void cgels_(char *trans, integer *m, integer *n, integer *
Expand All @@ -424,18 +428,16 @@ static integer c__0 = 0;
real r__1;

/* Local variables */
integer i__, j, nb, mn;
real anrm, bnrm;
integer brow;
logical tpsd;
integer i__, j, iascl, ibscl;
integer iascl, ibscl;
extern logical lsame_(char *, char *);
integer wsize;
real rwork[1];
integer nb;
extern /* Subroutine */ void slabad_(real *, real *);
extern real clange_(char *, integer *, integer *, complex *, integer *,
real *);
integer mn;
extern /* Subroutine */ void cgelqf_(integer *, integer *, complex *,
integer *, complex *, complex *, integer *, integer *), clascl_(
char *, integer *, integer *, real *, real *, integer *, integer *
Expand All @@ -444,8 +446,7 @@ static integer c__0 = 0;
extern /* Subroutine */ void cgeqrf_(integer *, integer *, complex *,
integer *, complex *, complex *, integer *, integer *), claset_(
char *, integer *, integer *, complex *, complex *, complex *,
integer *);
extern void xerbla_(char *, integer *, ftnlen);
integer *), xerbla_(char *, integer *, ftnlen);
extern integer ilaenv_(integer *, char *, char *, integer *, integer *,
integer *, integer *, ftnlen, ftnlen);
integer scllen;
Expand All @@ -461,10 +462,9 @@ static integer c__0 = 0;
integer *, complex *, integer *, complex *, integer *, integer *);


/* -- LAPACK driver routine (version 3.7.0) -- */
/* -- LAPACK driver routine -- */
/* -- LAPACK is a software package provided by Univ. of Tennessee, -- */
/* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- */
/* December 2016 */


/* ===================================================================== */
Expand All @@ -474,10 +474,10 @@ static integer c__0 = 0;

/* Parameter adjustments */
a_dim1 = *lda;
a_offset = 1 + a_dim1 * 1;
a_offset = 1 + a_dim1;
a -= a_offset;
b_dim1 = *ldb;
b_offset = 1 + b_dim1 * 1;
b_offset = 1 + b_dim1;
b -= b_offset;
--work;

Expand Down Expand Up @@ -578,7 +578,6 @@ static integer c__0 = 0;

smlnum = slamch_("S") / slamch_("P");
bignum = 1.f / smlnum;
slabad_(&smlnum, &bignum);

/* Scale A, B if f2cmax element outside range [SMLNUM,BIGNUM] */

Expand Down Expand Up @@ -775,21 +774,30 @@ static integer c__0 = 0;

}

/* Undo scaling */
/* Undo scaling. The solution carries the factor of B divided by */
/* the factor of A. When both were scaled to the same end of the */
/* range the constants cancel and BNRM/ANRM is applied in one step: */
/* applied in two, the first step could flush or overflow an entry */
/* that the second would have brought back into range. */

if (iascl == 1) {
clascl_("G", &c__0, &c__0, &anrm, &smlnum, &scllen, nrhs, &b[b_offset]
, ldb, info);
} else if (iascl == 2) {
clascl_("G", &c__0, &c__0, &anrm, &bignum, &scllen, nrhs, &b[b_offset]
, ldb, info);
}
if (ibscl == 1) {
clascl_("G", &c__0, &c__0, &smlnum, &bnrm, &scllen, nrhs, &b[b_offset]
, ldb, info);
} else if (ibscl == 2) {
clascl_("G", &c__0, &c__0, &bignum, &bnrm, &scllen, nrhs, &b[b_offset]
, ldb, info);
if (iascl == ibscl && iascl != 0) {
clascl_("G", &c__0, &c__0, &anrm, &bnrm, &scllen, nrhs, &b[b_offset],
ldb, info);
} else {
if (iascl == 1) {
clascl_("G", &c__0, &c__0, &anrm, &smlnum, &scllen, nrhs, &b[
b_offset], ldb, info);
} else if (iascl == 2) {
clascl_("G", &c__0, &c__0, &anrm, &bignum, &scllen, nrhs, &b[
b_offset], ldb, info);
}
if (ibscl == 1) {
clascl_("G", &c__0, &c__0, &smlnum, &bnrm, &scllen, nrhs, &b[
b_offset], ldb, info);
} else if (ibscl == 2) {
clascl_("G", &c__0, &c__0, &bignum, &bnrm, &scllen, nrhs, &b[
b_offset], ldb, info);
}
}

L50:
Expand Down
87 changes: 57 additions & 30 deletions lapack-netlib/SRC/cgels.f
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,13 @@
* Online html documentation available at
* http://www.netlib.org/lapack/explore-html/
*
*> \htmlonly
*> Download CGELS + dependencies
*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/cgels.f">
*> [TGZ]</a>
*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/cgels.f">
*> [ZIP]</a>
*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/cgels.f">
*> [TXT]</a>
*> \endhtmlonly
*
* Definition:
* ===========
Expand All @@ -37,7 +35,17 @@
*>
*> CGELS solves overdetermined or underdetermined complex linear systems
*> involving an M-by-N matrix A, or its conjugate-transpose, using a QR
*> or LQ factorization of A. It is assumed that A has full rank.
*> or LQ factorization of A.
*>
*> It is assumed that A has full rank, and only a rudimentary protection
*> against rank-deficient matrices is provided. This subroutine only detects
*> exact rank-deficiency, where a diagonal element of the triangular factor
*> of A is exactly zero.
*>
*> It is conceivable for one (or more) of the diagonal elements of the triangular
*> factor of A to be subnormally tiny numbers without this subroutine signalling
*> an error. The solutions computed for such almost-rank-deficient matrices may
*> be less accurate due to a loss of numerical precision.
*>
*> The following options are provided:
*>
Expand Down Expand Up @@ -161,7 +169,7 @@
*> = 0: successful exit
*> < 0: if INFO = -i, the i-th argument had an illegal value
*> > 0: if INFO = i, the i-th diagonal element of the
*> triangular factor of A is zero, so that A does not have
*> triangular factor of A is exactly zero, so that A does not have
*> full rank; the least squares solution could not be
*> computed.
*> \endverbatim
Expand All @@ -174,11 +182,13 @@
*> \author Univ. of Colorado Denver
*> \author NAG Ltd.
*
*> \ingroup complexGEsolve
*> \ingroup gels
*
* =====================================================================
SUBROUTINE CGELS( TRANS, M, N, NRHS, A, LDA, B, LDB, WORK, LWORK,
SUBROUTINE CGELS( TRANS, M, N, NRHS, A, LDA, B, LDB, WORK,
$ LWORK,
$ INFO )
IMPLICIT NONE
*
* -- LAPACK driver routine --
* -- LAPACK is a software package provided by Univ. of Tennessee, --
Expand Down Expand Up @@ -215,8 +225,9 @@ SUBROUTINE CGELS( TRANS, M, N, NRHS, A, LDA, B, LDB, WORK, LWORK,
EXTERNAL LSAME, ILAENV, CLANGE, SLAMCH
* ..
* .. External Subroutines ..
EXTERNAL CGELQF, CGEQRF, CLASCL, CLASET, CTRTRS, CUNMLQ,
$ CUNMQR, SLABAD, XERBLA
EXTERNAL CGELQF, CGEQRF, CLASCL, CLASET, CTRTRS,
$ CUNMLQ,
$ CUNMQR, XERBLA
* ..
* .. Intrinsic Functions ..
INTRINSIC MAX, MIN, REAL
Expand All @@ -228,7 +239,8 @@ SUBROUTINE CGELS( TRANS, M, N, NRHS, A, LDA, B, LDB, WORK, LWORK,
INFO = 0
MN = MIN( M, N )
LQUERY = ( LWORK.EQ.-1 )
IF( .NOT.( LSAME( TRANS, 'N' ) .OR. LSAME( TRANS, 'C' ) ) ) THEN
IF( .NOT.( LSAME( TRANS, 'N' ) .OR.
$ LSAME( TRANS, 'C' ) ) ) THEN
INFO = -1
ELSE IF( M.LT.0 ) THEN
INFO = -2
Expand Down Expand Up @@ -288,15 +300,15 @@ SUBROUTINE CGELS( TRANS, M, N, NRHS, A, LDA, B, LDB, WORK, LWORK,
* Quick return if possible
*
IF( MIN( M, N, NRHS ).EQ.0 ) THEN
CALL CLASET( 'Full', MAX( M, N ), NRHS, CZERO, CZERO, B, LDB )
CALL CLASET( 'Full', MAX( M, N ), NRHS, CZERO, CZERO, B,
$ LDB )
RETURN
END IF
*
* Get machine parameters
*
SMLNUM = SLAMCH( 'S' ) / SLAMCH( 'P' )
BIGNUM = ONE / SMLNUM
CALL SLABAD( SMLNUM, BIGNUM )
*
* Scale A, B if max element outside range [SMLNUM,BIGNUM]
*
Expand Down Expand Up @@ -347,7 +359,8 @@ SUBROUTINE CGELS( TRANS, M, N, NRHS, A, LDA, B, LDB, WORK, LWORK,
*
* compute QR factorization of A
*
CALL CGEQRF( M, N, A, LDA, WORK( 1 ), WORK( MN+1 ), LWORK-MN,
CALL CGEQRF( M, N, A, LDA, WORK( 1 ), WORK( MN+1 ),
$ LWORK-MN,
$ INFO )
*
* workspace at least N, optimally N*NB
Expand All @@ -358,15 +371,17 @@ SUBROUTINE CGELS( TRANS, M, N, NRHS, A, LDA, B, LDB, WORK, LWORK,
*
* B(1:M,1:NRHS) := Q**H * B(1:M,1:NRHS)
*
CALL CUNMQR( 'Left', 'Conjugate transpose', M, NRHS, N, A,
CALL CUNMQR( 'Left', 'Conjugate transpose', M, NRHS, N,
$ A,
$ LDA, WORK( 1 ), B, LDB, WORK( MN+1 ), LWORK-MN,
$ INFO )
*
* workspace at least NRHS, optimally NRHS*NB
*
* B(1:N,1:NRHS) := inv(R) * B(1:N,1:NRHS)
*
CALL CTRTRS( 'Upper', 'No transpose', 'Non-unit', N, NRHS,
CALL CTRTRS( 'Upper', 'No transpose', 'Non-unit', N,
$ NRHS,
$ A, LDA, B, LDB, INFO )
*
IF( INFO.GT.0 ) THEN
Expand Down Expand Up @@ -412,7 +427,8 @@ SUBROUTINE CGELS( TRANS, M, N, NRHS, A, LDA, B, LDB, WORK, LWORK,
*
* Compute LQ factorization of A
*
CALL CGELQF( M, N, A, LDA, WORK( 1 ), WORK( MN+1 ), LWORK-MN,
CALL CGELQF( M, N, A, LDA, WORK( 1 ), WORK( MN+1 ),
$ LWORK-MN,
$ INFO )
*
* workspace at least M, optimally M*NB.
Expand All @@ -423,7 +439,8 @@ SUBROUTINE CGELS( TRANS, M, N, NRHS, A, LDA, B, LDB, WORK, LWORK,
*
* B(1:M,1:NRHS) := inv(L) * B(1:M,1:NRHS)
*
CALL CTRTRS( 'Lower', 'No transpose', 'Non-unit', M, NRHS,
CALL CTRTRS( 'Lower', 'No transpose', 'Non-unit', M,
$ NRHS,
$ A, LDA, B, LDB, INFO )
*
IF( INFO.GT.0 ) THEN
Expand All @@ -440,7 +457,8 @@ SUBROUTINE CGELS( TRANS, M, N, NRHS, A, LDA, B, LDB, WORK, LWORK,
*
* B(1:N,1:NRHS) := Q(1:N,:)**H * B(1:M,1:NRHS)
*
CALL CUNMLQ( 'Left', 'Conjugate transpose', N, NRHS, M, A,
CALL CUNMLQ( 'Left', 'Conjugate transpose', N, NRHS, M,
$ A,
$ LDA, WORK( 1 ), B, LDB, WORK( MN+1 ), LWORK-MN,
$ INFO )
*
Expand Down Expand Up @@ -475,21 +493,30 @@ SUBROUTINE CGELS( TRANS, M, N, NRHS, A, LDA, B, LDB, WORK, LWORK,
*
END IF
*
* Undo scaling
* Undo scaling. The solution carries the factor of B divided by
* the factor of A. When both were scaled to the same end of the
* range the constants cancel and BNRM/ANRM is applied in one step:
* applied in two, the first step could flush or overflow an entry
* that the second would have brought back into range.
*
IF( IASCL.EQ.1 ) THEN
CALL CLASCL( 'G', 0, 0, ANRM, SMLNUM, SCLLEN, NRHS, B, LDB,
$ INFO )
ELSE IF( IASCL.EQ.2 ) THEN
CALL CLASCL( 'G', 0, 0, ANRM, BIGNUM, SCLLEN, NRHS, B, LDB,
$ INFO )
END IF
IF( IBSCL.EQ.1 ) THEN
CALL CLASCL( 'G', 0, 0, SMLNUM, BNRM, SCLLEN, NRHS, B, LDB,
$ INFO )
ELSE IF( IBSCL.EQ.2 ) THEN
CALL CLASCL( 'G', 0, 0, BIGNUM, BNRM, SCLLEN, NRHS, B, LDB,
IF( IASCL.EQ.IBSCL .AND. IASCL.NE.0 ) THEN
CALL CLASCL( 'G', 0, 0, ANRM, BNRM, SCLLEN, NRHS, B, LDB,
$ INFO )
ELSE
IF( IASCL.EQ.1 ) THEN
CALL CLASCL( 'G', 0, 0, ANRM, SMLNUM, SCLLEN, NRHS, B, LDB,
$ INFO )
ELSE IF( IASCL.EQ.2 ) THEN
CALL CLASCL( 'G', 0, 0, ANRM, BIGNUM, SCLLEN, NRHS, B, LDB,
$ INFO )
END IF
IF( IBSCL.EQ.1 ) THEN
CALL CLASCL( 'G', 0, 0, SMLNUM, BNRM, SCLLEN, NRHS, B, LDB,
$ INFO )
ELSE IF( IBSCL.EQ.2 ) THEN
CALL CLASCL( 'G', 0, 0, BIGNUM, BNRM, SCLLEN, NRHS, B, LDB,
$ INFO )
END IF
END IF
*
50 CONTINUE
Expand Down
Loading
Loading