Import LAPACK: SRC directory
authorMartin Köhler <koehlerm@mpi-magdeburg.mpg.de>
Wed, 26 Oct 2016 13:12:09 +0000 (15:12 +0200)
committerMartin Köhler <koehlerm@mpi-magdeburg.mpg.de>
Wed, 26 Oct 2016 13:12:09 +0000 (15:12 +0200)
253 files changed:
lapack-netlib/SRC/CMakeLists.txt
lapack-netlib/SRC/Makefile
lapack-netlib/SRC/cbbcsd.f
lapack-netlib/SRC/cgbequb.f
lapack-netlib/SRC/cgbrfsx.f
lapack-netlib/SRC/cgeesx.f
lapack-netlib/SRC/cgeev.f
lapack-netlib/SRC/cgeevx.f
lapack-netlib/SRC/cgejsv.f
lapack-netlib/SRC/cgelss.f
lapack-netlib/SRC/cgeqrt3.f
lapack-netlib/SRC/cgesdd.f
lapack-netlib/SRC/cgesvd.f
lapack-netlib/SRC/cgesvdx.f
lapack-netlib/SRC/cgesvj.f
lapack-netlib/SRC/cgetc2.f
lapack-netlib/SRC/cgetrf2.f
lapack-netlib/SRC/cgges3.f
lapack-netlib/SRC/cggev3.f
lapack-netlib/SRC/cgghd3.f
lapack-netlib/SRC/cggsvp3.f
lapack-netlib/SRC/cgsvj0.f
lapack-netlib/SRC/cgsvj1.f
lapack-netlib/SRC/chbevx.f
lapack-netlib/SRC/chbgvd.f
lapack-netlib/SRC/chbgvx.f
lapack-netlib/SRC/cheevr.f
lapack-netlib/SRC/cheevx.f
lapack-netlib/SRC/chegvx.f
lapack-netlib/SRC/chetrf_rook.f
lapack-netlib/SRC/chgeqz.f
lapack-netlib/SRC/chpevx.f
lapack-netlib/SRC/chpgvx.f
lapack-netlib/SRC/cla_gbamv.f
lapack-netlib/SRC/cla_herpvgrw.f
lapack-netlib/SRC/cla_lin_berr.f
lapack-netlib/SRC/cla_porcond_c.f
lapack-netlib/SRC/cla_porpvgrw.f
lapack-netlib/SRC/claed7.f
lapack-netlib/SRC/claqr3.f
lapack-netlib/SRC/claqr5.f
lapack-netlib/SRC/clarcm.f
lapack-netlib/SRC/clarrv.f
lapack-netlib/SRC/clarscl2.f
lapack-netlib/SRC/clascl.f
lapack-netlib/SRC/clascl2.f
lapack-netlib/SRC/clatdf.f
lapack-netlib/SRC/cpotrf2.f
lapack-netlib/SRC/cpttrs.f
lapack-netlib/SRC/cptts2.f
lapack-netlib/SRC/cstegr.f
lapack-netlib/SRC/cstemr.f
lapack-netlib/SRC/csytrf_rook.f
lapack-netlib/SRC/ctgsen.f
lapack-netlib/SRC/ctrevc3.f [new file with mode: 0644]
lapack-netlib/SRC/ctrttf.f
lapack-netlib/SRC/cunbdb1.f
lapack-netlib/SRC/cunbdb2.f
lapack-netlib/SRC/cunbdb3.f
lapack-netlib/SRC/cunbdb4.f
lapack-netlib/SRC/cuncsd.f
lapack-netlib/SRC/cuncsd2by1.f
lapack-netlib/SRC/dbbcsd.f
lapack-netlib/SRC/dbdsdc.f
lapack-netlib/SRC/dbdsvdx.f
lapack-netlib/SRC/dgbrfsx.f
lapack-netlib/SRC/dgeesx.f
lapack-netlib/SRC/dgeev.f
lapack-netlib/SRC/dgeevx.f
lapack-netlib/SRC/dgejsv.f
lapack-netlib/SRC/dgeqrt3.f
lapack-netlib/SRC/dgesdd.f
lapack-netlib/SRC/dgesvd.f
lapack-netlib/SRC/dgesvdx.f
lapack-netlib/SRC/dgetc2.f
lapack-netlib/SRC/dgetrf2.f
lapack-netlib/SRC/dgghd3.f
lapack-netlib/SRC/dgsvj1.f
lapack-netlib/SRC/dhgeqz.f
lapack-netlib/SRC/dlaed1.f
lapack-netlib/SRC/dlaed7.f
lapack-netlib/SRC/dlag2.f
lapack-netlib/SRC/dlamrg.f
lapack-netlib/SRC/dlaqr3.f
lapack-netlib/SRC/dlaqr5.f
lapack-netlib/SRC/dlarrc.f
lapack-netlib/SRC/dlarrd.f
lapack-netlib/SRC/dlarre.f
lapack-netlib/SRC/dlarrf.f
lapack-netlib/SRC/dlarrv.f
lapack-netlib/SRC/dlarscl2.f
lapack-netlib/SRC/dlascl.f
lapack-netlib/SRC/dlascl2.f
lapack-netlib/SRC/dlasd1.f
lapack-netlib/SRC/dlasd6.f
lapack-netlib/SRC/dlasdq.f
lapack-netlib/SRC/dlasq3.f
lapack-netlib/SRC/dlasq4.f
lapack-netlib/SRC/dlasrt.f
lapack-netlib/SRC/dlasy2.f
lapack-netlib/SRC/dlatdf.f
lapack-netlib/SRC/dorbdb1.f
lapack-netlib/SRC/dorbdb2.f
lapack-netlib/SRC/dorbdb3.f
lapack-netlib/SRC/dorbdb4.f
lapack-netlib/SRC/dorcsd2by1.f
lapack-netlib/SRC/dsbevx.f
lapack-netlib/SRC/dsbgvd.f
lapack-netlib/SRC/dsbgvx.f
lapack-netlib/SRC/dsgesv.f
lapack-netlib/SRC/dspevx.f
lapack-netlib/SRC/dspgvx.f
lapack-netlib/SRC/dsposv.f
lapack-netlib/SRC/dstebz.f
lapack-netlib/SRC/dstegr.f
lapack-netlib/SRC/dstemr.f
lapack-netlib/SRC/dstevr.f
lapack-netlib/SRC/dstevx.f
lapack-netlib/SRC/dsyevr.f
lapack-netlib/SRC/dsyevx.f
lapack-netlib/SRC/dsygvx.f
lapack-netlib/SRC/dsytrf_rook.f
lapack-netlib/SRC/dsytrs2.f
lapack-netlib/SRC/dtgsen.f
lapack-netlib/SRC/dtrevc3.f [new file with mode: 0644]
lapack-netlib/SRC/ilaenv.f
lapack-netlib/SRC/ilaver.f
lapack-netlib/SRC/sbbcsd.f
lapack-netlib/SRC/sbdsdc.f
lapack-netlib/SRC/sbdsvdx.f
lapack-netlib/SRC/sgbequb.f
lapack-netlib/SRC/sgbrfsx.f
lapack-netlib/SRC/sgeesx.f
lapack-netlib/SRC/sgeev.f
lapack-netlib/SRC/sgeevx.f
lapack-netlib/SRC/sgejsv.f
lapack-netlib/SRC/sgeqrt3.f
lapack-netlib/SRC/sgesdd.f
lapack-netlib/SRC/sgesvd.f
lapack-netlib/SRC/sgesvdx.f
lapack-netlib/SRC/sgetc2.f
lapack-netlib/SRC/sgetrf2.f
lapack-netlib/SRC/sgghd3.f
lapack-netlib/SRC/sggsvp3.f
lapack-netlib/SRC/shgeqz.f
lapack-netlib/SRC/slaed1.f
lapack-netlib/SRC/slaed7.f
lapack-netlib/SRC/slag2.f
lapack-netlib/SRC/slamrg.f
lapack-netlib/SRC/slaqr3.f
lapack-netlib/SRC/slaqr5.f
lapack-netlib/SRC/slarrc.f
lapack-netlib/SRC/slarrd.f
lapack-netlib/SRC/slarre.f
lapack-netlib/SRC/slarrf.f
lapack-netlib/SRC/slarrv.f
lapack-netlib/SRC/slarscl2.f
lapack-netlib/SRC/slascl.f
lapack-netlib/SRC/slascl2.f
lapack-netlib/SRC/slasd1.f
lapack-netlib/SRC/slasd6.f
lapack-netlib/SRC/slasdq.f
lapack-netlib/SRC/slasq3.f
lapack-netlib/SRC/slasq4.f
lapack-netlib/SRC/slasrt.f
lapack-netlib/SRC/slasy2.f
lapack-netlib/SRC/slatdf.f
lapack-netlib/SRC/sorbdb1.f
lapack-netlib/SRC/sorbdb2.f
lapack-netlib/SRC/sorbdb3.f
lapack-netlib/SRC/sorbdb4.f
lapack-netlib/SRC/sorcsd2by1.f
lapack-netlib/SRC/ssbevx.f
lapack-netlib/SRC/ssbgvd.f
lapack-netlib/SRC/ssbgvx.f
lapack-netlib/SRC/sspevx.f
lapack-netlib/SRC/sspgvx.f
lapack-netlib/SRC/sstebz.f
lapack-netlib/SRC/sstegr.f
lapack-netlib/SRC/sstemr.f
lapack-netlib/SRC/sstevr.f
lapack-netlib/SRC/sstevx.f
lapack-netlib/SRC/ssyevr.f
lapack-netlib/SRC/ssyevx.f
lapack-netlib/SRC/ssygvx.f
lapack-netlib/SRC/ssytrf_rook.f
lapack-netlib/SRC/stgsen.f
lapack-netlib/SRC/strevc3.f [new file with mode: 0644]
lapack-netlib/SRC/zbbcsd.f
lapack-netlib/SRC/zcgesv.f
lapack-netlib/SRC/zcposv.f
lapack-netlib/SRC/zgbequb.f
lapack-netlib/SRC/zgbrfsx.f
lapack-netlib/SRC/zgeesx.f
lapack-netlib/SRC/zgeev.f
lapack-netlib/SRC/zgeevx.f
lapack-netlib/SRC/zgejsv.f
lapack-netlib/SRC/zgelss.f
lapack-netlib/SRC/zgeqrt3.f
lapack-netlib/SRC/zgesdd.f
lapack-netlib/SRC/zgesvd.f
lapack-netlib/SRC/zgesvdx.f
lapack-netlib/SRC/zgesvj.f
lapack-netlib/SRC/zgetc2.f
lapack-netlib/SRC/zgetrf2.f
lapack-netlib/SRC/zggbal.f
lapack-netlib/SRC/zgges3.f
lapack-netlib/SRC/zggev3.f
lapack-netlib/SRC/zgghd3.f
lapack-netlib/SRC/zggsvd3.f
lapack-netlib/SRC/zggsvp3.f
lapack-netlib/SRC/zgsvj0.f
lapack-netlib/SRC/zgsvj1.f
lapack-netlib/SRC/zhbevx.f
lapack-netlib/SRC/zhbgvd.f
lapack-netlib/SRC/zhbgvx.f
lapack-netlib/SRC/zheevr.f
lapack-netlib/SRC/zheevx.f
lapack-netlib/SRC/zhegvx.f
lapack-netlib/SRC/zhetrf_rook.f
lapack-netlib/SRC/zhetrs2.f
lapack-netlib/SRC/zhgeqz.f
lapack-netlib/SRC/zhpevx.f
lapack-netlib/SRC/zhpgvx.f
lapack-netlib/SRC/zla_gerpvgrw.f
lapack-netlib/SRC/zla_herpvgrw.f
lapack-netlib/SRC/zla_lin_berr.f
lapack-netlib/SRC/zla_porpvgrw.f
lapack-netlib/SRC/zlaed7.f
lapack-netlib/SRC/zlaqr3.f
lapack-netlib/SRC/zlaqr5.f
lapack-netlib/SRC/zlarcm.f
lapack-netlib/SRC/zlarft.f
lapack-netlib/SRC/zlarrv.f
lapack-netlib/SRC/zlarscl2.f
lapack-netlib/SRC/zlascl.f
lapack-netlib/SRC/zlascl2.f
lapack-netlib/SRC/zlatdf.f
lapack-netlib/SRC/zpbrfs.f
lapack-netlib/SRC/zpftrf.f
lapack-netlib/SRC/zpttrs.f
lapack-netlib/SRC/zptts2.f
lapack-netlib/SRC/zstegr.f
lapack-netlib/SRC/zstemr.f
lapack-netlib/SRC/zsytrf_rook.f
lapack-netlib/SRC/zsytrs2.f
lapack-netlib/SRC/ztgsen.f
lapack-netlib/SRC/ztrevc3.f [new file with mode: 0644]
lapack-netlib/SRC/zunbdb1.f
lapack-netlib/SRC/zunbdb2.f
lapack-netlib/SRC/zunbdb3.f
lapack-netlib/SRC/zunbdb4.f
lapack-netlib/SRC/zuncsd2by1.f

index 03441b942634df739ceafef874e4cb179ddc5469..4857f474745b79f3bbca55668464c0c682d16940 100644 (file)
@@ -141,7 +141,7 @@ set(SLASRC
    stbrfs.f stbtrs.f stgevc.f stgex2.f stgexc.f stgsen.f 
    stgsja.f stgsna.f stgsy2.f stgsyl.f stpcon.f stprfs.f stptri.f 
    stptrs.f 
-   strcon.f strevc.f strexc.f strrfs.f strsen.f strsna.f strsyl.f 
+   strcon.f strevc.f strevc3.f strexc.f strrfs.f strsen.f strsna.f strsyl.f 
    strti2.f strtri.f strtrs.f stzrzf.f sstemr.f 
    slansf.f spftrf.f spftri.f spftrs.f ssfrk.f stfsm.f stftri.f stfttp.f 
    stfttr.f stpttf.f stpttr.f strttf.f strttp.f 
@@ -221,7 +221,7 @@ set(CLASRC
    ctbcon.f ctbrfs.f ctbtrs.f ctgevc.f ctgex2.f 
    ctgexc.f ctgsen.f ctgsja.f ctgsna.f ctgsy2.f ctgsyl.f ctpcon.f 
    ctprfs.f ctptri.f 
-   ctptrs.f ctrcon.f ctrevc.f ctrexc.f ctrrfs.f ctrsen.f ctrsna.f 
+   ctptrs.f ctrcon.f ctrevc.f ctrevc3.f ctrexc.f ctrrfs.f ctrsen.f ctrsna.f 
    ctrsyl.f ctrti2.f ctrtri.f ctrtrs.f ctzrzf.f cung2l.f cung2r.f 
    cungbr.f cunghr.f cungl2.f cunglq.f cungql.f cungqr.f cungr2.f 
    cungrq.f cungtr.f cunm2l.f cunm2r.f cunmbr.f cunmhr.f cunml2.f cunm22.f
@@ -302,7 +302,7 @@ set(DLASRC
    dtbrfs.f dtbtrs.f dtgevc.f dtgex2.f dtgexc.f dtgsen.f 
    dtgsja.f dtgsna.f dtgsy2.f dtgsyl.f dtpcon.f dtprfs.f dtptri.f 
    dtptrs.f 
-   dtrcon.f dtrevc.f dtrexc.f dtrrfs.f dtrsen.f dtrsna.f dtrsyl.f 
+   dtrcon.f dtrevc.f dtrevc3.f dtrexc.f dtrrfs.f dtrsen.f dtrsna.f dtrsyl.f 
    dtrti2.f dtrtri.f dtrtrs.f dtzrzf.f dstemr.f 
    dsgesv.f dsposv.f dlag2s.f slag2d.f dlat2s.f 
    dlansf.f dpftrf.f dpftri.f dpftrs.f dsfrk.f dtfsm.f dtftri.f dtfttp.f 
@@ -383,7 +383,7 @@ set(ZLASRC
    ztbcon.f ztbrfs.f ztbtrs.f ztgevc.f ztgex2.f 
    ztgexc.f ztgsen.f ztgsja.f ztgsna.f ztgsy2.f ztgsyl.f ztpcon.f 
    ztprfs.f ztptri.f 
-   ztptrs.f ztrcon.f ztrevc.f ztrexc.f ztrrfs.f ztrsen.f ztrsna.f 
+   ztptrs.f ztrcon.f ztrevc.f ztrevc3.f ztrexc.f ztrrfs.f ztrsen.f ztrsna.f 
    ztrsyl.f ztrti2.f ztrtri.f ztrtrs.f ztzrzf.f zung2l.f 
    zung2r.f zungbr.f zunghr.f zungl2.f zunglq.f zungql.f zungqr.f zungr2.f 
    zungrq.f zungtr.f zunm2l.f zunm2r.f zunmbr.f zunmhr.f zunml2.f zunm22.f
index 22799769abacd70156e0c8f04d41eefc4e8ceb5c..bb2d9562c3bc3b7815db23a6b697bfe4f6dfc7f7 100644 (file)
@@ -150,7 +150,7 @@ SLASRC = \
    stbrfs.o stbtrs.o stgevc.o stgex2.o stgexc.o stgsen.o \
    stgsja.o stgsna.o stgsy2.o stgsyl.o stpcon.o stprfs.o stptri.o \
    stptrs.o \
-   strcon.o strevc.o strexc.o strrfs.o strsen.o strsna.o strsyl.o \
+   strcon.o strevc.o strevc3.o strexc.o strrfs.o strsen.o strsna.o strsyl.o \
    strtrs.o stzrzf.o sstemr.o \
    slansf.o spftrf.o spftri.o spftrs.o ssfrk.o stfsm.o stftri.o stfttp.o \
    stfttr.o stpttf.o stpttr.o strttf.o strttp.o \
@@ -231,7 +231,7 @@ CLASRC = \
    ctbcon.o ctbrfs.o ctbtrs.o ctgevc.o ctgex2.o \
    ctgexc.o ctgsen.o ctgsja.o ctgsna.o ctgsy2.o ctgsyl.o ctpcon.o \
    ctprfs.o ctptri.o \
-   ctptrs.o ctrcon.o ctrevc.o ctrexc.o ctrrfs.o ctrsen.o ctrsna.o \
+   ctptrs.o ctrcon.o ctrevc.o ctrevc3.o ctrexc.o ctrrfs.o ctrsen.o ctrsna.o \
    ctrsyl.o ctrtrs.o ctzrzf.o cung2l.o cung2r.o \
    cungbr.o cunghr.o cungl2.o cunglq.o cungql.o cungqr.o cungr2.o \
    cungrq.o cungtr.o cunm2l.o cunm2r.o cunmbr.o cunmhr.o cunml2.o cunm22.o \
@@ -316,7 +316,7 @@ DLASRC = \
    dtbcon.o dtbrfs.o dtbtrs.o dtgevc.o dtgex2.o dtgexc.o dtgsen.o \
    dtgsja.o dtgsna.o dtgsy2.o dtgsyl.o dtpcon.o dtprfs.o dtptri.o \
    dtptrs.o \
-   dtrcon.o dtrevc.o dtrexc.o dtrrfs.o dtrsen.o dtrsna.o dtrsyl.o \
+   dtrcon.o dtrevc.o dtrevc3.o dtrexc.o dtrrfs.o dtrsen.o dtrsna.o dtrsyl.o \
    dtrtrs.o dtzrzf.o dstemr.o \
    dsgesv.o dsposv.o dlag2s.o slag2d.o dlat2s.o \
    dlansf.o dpftrf.o dpftri.o dpftrs.o dsfrk.o dtfsm.o dtftri.o dtfttp.o \
@@ -400,7 +400,7 @@ ZLASRC = \
    ztbcon.o ztbrfs.o ztbtrs.o ztgevc.o ztgex2.o \
    ztgexc.o ztgsen.o ztgsja.o ztgsna.o ztgsy2.o ztgsyl.o ztpcon.o \
    ztprfs.o ztptri.o \
-   ztptrs.o ztrcon.o ztrevc.o ztrexc.o ztrrfs.o ztrsen.o ztrsna.o \
+   ztptrs.o ztrcon.o ztrevc.o ztrevc3.o ztrexc.o ztrrfs.o ztrsen.o ztrsna.o \
    ztrsyl.o ztrtrs.o ztzrzf.o zung2l.o \
    zung2r.o zungbr.o zunghr.o zungl2.o zunglq.o zungql.o zungqr.o zungr2.o \
    zungrq.o zungtr.o zunm2l.o zunm2r.o zunmbr.o zunmhr.o zunml2.o zunm22.o \
index 2d619cde11ecc2836be85da308ac3331c06a1730..a2d1a1339a76a8cdddc4cbbd5e4a426e462cfc47 100644 (file)
 *> \param[in,out] U1
 *> \verbatim
 *>          U1 is COMPLEX array, dimension (LDU1,P)
-*>          On entry, an LDU1-by-P matrix. On exit, U1 is postmultiplied
+*>          On entry, a P-by-P matrix. On exit, U1 is postmultiplied
 *>          by the left singular vector matrix common to [ B11 ; 0 ] and
 *>          [ B12 0 0 ; 0 -I 0 0 ].
 *> \endverbatim
 *> \param[in] LDU1
 *> \verbatim
 *>          LDU1 is INTEGER
-*>          The leading dimension of the array U1.
+*>          The leading dimension of the array U1, LDU1 >= MAX(1,P).
 *> \endverbatim
 *>
 *> \param[in,out] U2
 *> \verbatim
 *>          U2 is COMPLEX array, dimension (LDU2,M-P)
-*>          On entry, an LDU2-by-(M-P) matrix. On exit, U2 is
+*>          On entry, an (M-P)-by-(M-P) matrix. On exit, U2 is
 *>          postmultiplied by the left singular vector matrix common to
 *>          [ B21 ; 0 ] and [ B22 0 0 ; 0 0 I ].
 *> \endverbatim
 *> \param[in] LDU2
 *> \verbatim
 *>          LDU2 is INTEGER
-*>          The leading dimension of the array U2.
+*>          The leading dimension of the array U2, LDU2 >= MAX(1,M-P).
 *> \endverbatim
 *>
 *> \param[in,out] V1T
 *> \verbatim
 *>          V1T is COMPLEX array, dimension (LDV1T,Q)
-*>          On entry, a LDV1T-by-Q matrix. On exit, V1T is premultiplied
+*>          On entry, a Q-by-Q matrix. On exit, V1T is premultiplied
 *>          by the conjugate transpose of the right singular vector
 *>          matrix common to [ B11 ; 0 ] and [ B21 ; 0 ].
 *> \endverbatim
 *> \param[in] LDV1T
 *> \verbatim
 *>          LDV1T is INTEGER
-*>          The leading dimension of the array V1T.
+*>          The leading dimension of the array V1T, LDV1T >= MAX(1,Q).
 *> \endverbatim
 *>
 *> \param[in,out] V2T
 *> \verbatim
 *>          V2T is COMPLEX array, dimenison (LDV2T,M-Q)
-*>          On entry, a LDV2T-by-(M-Q) matrix. On exit, V2T is
+*>          On entry, an (M-Q)-by-(M-Q) matrix. On exit, V2T is
 *>          premultiplied by the conjugate transpose of the right
 *>          singular vector matrix common to [ B12 0 0 ; 0 -I 0 ] and
 *>          [ B22 0 0 ; 0 0 I ].
 *> \param[in] LDV2T
 *> \verbatim
 *>          LDV2T is INTEGER
-*>          The leading dimension of the array V2T.
+*>          The leading dimension of the array V2T, LDV2T >= MAX(1,M-Q).
 *> \endverbatim
 *>
 *> \param[out] B11D
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2013
+*> \date June 2016
 *
 *> \ingroup complexOTHERcomputational
 *
      $                   V2T, LDV2T, B11D, B11E, B12D, B12E, B21D, B21E,
      $                   B22D, B22E, RWORK, LRWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.5.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2013
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBU1, JOBU2, JOBV1T, JOBV2T, TRANS
index 0e2875fe8ae40a0c4c6681e6d829b85ed5a5257a..f93413be4e3aacb1753038fdf9bb22a08786829c 100644 (file)
@@ -84,7 +84,7 @@
 *>
 *> \param[in] AB
 *> \verbatim
-*>          AB is DOUBLE PRECISION array, dimension (LDAB,N)
+*>          AB is COMPLEX array, dimension (LDAB,N)
 *>          On entry, the matrix A in band storage, in rows 1 to KL+KU+1.
 *>          The j-th column of A is stored in the j-th column of the
 *>          array AB as follows:
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup complexGBcomputational
 *
       SUBROUTINE CGBEQUB( M, N, KL, KU, AB, LDAB, R, C, ROWCND, COLCND,
      $                    AMAX, INFO )
 *
-*  -- LAPACK computational routine (version 3.4.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            INFO, KL, KU, LDAB, M, N
index fc73496910bab6818370bde7c8e7be4c5a1f7c16..31caebe61dfe73ae9f391c1795f4d88a6ad57bab 100644 (file)
      $                    ERR_BNDS_COMP, NPARAMS, PARAMS, WORK, RWORK,
      $                    INFO )
 *
-*  -- LAPACK computational routine (version 3.4.1) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     April 2012
 *
 *     Perform refinement on each right-hand side
 *
-      IF ( REF_TYPE .NE. 0 ) THEN
+      IF ( REF_TYPE .NE. 0 .AND. INFO .EQ. 0 ) THEN
 
          PREC_TYPE = ILAPREC( 'D' )
 
index 81157717a046b3e1ec0e30a58dec6235204b23dc..4d3c459a7b8060945940118a8be0cb63083e1e80 100644 (file)
@@ -83,7 +83,7 @@
 *>
 *> \param[in] SELECT
 *> \verbatim
-*>          SELECT is procedure) LOGICAL FUNCTION of one COMPLEX argument
+*>          SELECT is a LOGICAL FUNCTION of one COMPLEX argument
 *>          SELECT must be declared EXTERNAL in the calling subroutine.
 *>          If SORT = 'S', SELECT is used to select eigenvalues to order
 *>          to the top left of the Schur form.
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup complexGEeigen
 *
      $                   VS, LDVS, RCONDE, RCONDV, WORK, LWORK, RWORK,
      $                   BWORK, INFO )
 *
-*  -- LAPACK driver routine (version 3.4.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBVS, SENSE, SORT
index 0f48322a8e4a56e54aaca9f1f858c9689da77aa7..7d19c0228c1ae9a39674619d3a471a7e4a7ab118 100644 (file)
@@ -26,8 +26,8 @@
 *       INTEGER            INFO, LDA, LDVL, LDVR, LWORK, N
 *       ..
 *       .. Array Arguments ..
-*       REAL               RWORK( * )
-*       COMPLEX            A( LDA, * ), VL( LDVL, * ), VR( LDVR, * ),
+*       REAL   RWORK( * )
+*       COMPLEX         A( LDA, * ), VL( LDVL, * ), VR( LDVR, * ),
 *      $                   W( * ), WORK( * )
 *       ..
 *  
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
+*
+*  @generated from zgeev.f, fortran z -> c, Tue Apr 19 01:47:44 2016
 *
 *> \ingroup complexGEeigen
 *
 *  =====================================================================
       SUBROUTINE CGEEV( JOBVL, JOBVR, N, A, LDA, W, VL, LDVL, VR, LDVR,
      $                  WORK, LWORK, RWORK, INFO )
+      implicit none
 *
-*  -- LAPACK driver routine (version 3.4.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBVL, JOBVR
       INTEGER            INFO, LDA, LDVL, LDVR, LWORK, N
 *     ..
 *     .. Array Arguments ..
-      REAL               RWORK( * )
-      COMPLEX            A( LDA, * ), VL( LDVL, * ), VR( LDVR, * ),
+      REAL   RWORK( * )
+      COMPLEX         A( LDA, * ), VL( LDVL, * ), VR( LDVR, * ),
      $                   W( * ), WORK( * )
 *     ..
 *
 *  =====================================================================
 *
 *     .. Parameters ..
-      REAL               ZERO, ONE
+      REAL   ZERO, ONE
       PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0 )
 *     ..
 *     .. Local Scalars ..
       LOGICAL            LQUERY, SCALEA, WANTVL, WANTVR
       CHARACTER          SIDE
       INTEGER            HSWORK, I, IBAL, IERR, IHI, ILO, IRWORK, ITAU,
-     $                   IWRK, K, MAXWRK, MINWRK, NOUT
-      REAL               ANRM, BIGNUM, CSCALE, EPS, SCL, SMLNUM
-      COMPLEX            TMP
+     $                   IWRK, K, LWORK_TREVC, MAXWRK, MINWRK, NOUT
+      REAL   ANRM, BIGNUM, CSCALE, EPS, SCL, SMLNUM
+      COMPLEX         TMP
 *     ..
 *     .. Local Arrays ..
       LOGICAL            SELECT( 1 )
-      REAL               DUM( 1 )
+      REAL   DUM( 1 )
 *     ..
 *     .. External Subroutines ..
-      EXTERNAL           CGEBAK, CGEBAL, CGEHRD, CHSEQR, CLACPY, CLASCL,
-     $                   CSCAL, CSSCAL, CTREVC, CUNGHR, SLABAD, XERBLA
+      EXTERNAL           SLABAD, XERBLA, CSSCAL, CGEBAK, CGEBAL, CGEHRD,
+     $                   CHSEQR, CLACPY, CLASCL, CSCAL, CTREVC3, CUNGHR
 *     ..
 *     .. External Functions ..
       LOGICAL            LSAME
-      INTEGER            ILAENV, ISAMAX
-      REAL               CLANGE, SCNRM2, SLAMCH
-      EXTERNAL           LSAME, ILAENV, ISAMAX, CLANGE, SCNRM2, SLAMCH
+      INTEGER            ISAMAX, ILAENV
+      REAL   SLAMCH, SCNRM2, CLANGE
+      EXTERNAL           LSAME, ISAMAX, ILAENV, SLAMCH, SCNRM2, CLANGE
 *     ..
 *     .. Intrinsic Functions ..
-      INTRINSIC          AIMAG, CMPLX, CONJG, MAX, REAL, SQRT
+      INTRINSIC          REAL, CMPLX, CONJG, AIMAG, MAX, SQRT
 *     ..
 *     .. Executable Statements ..
 *
       ELSE IF( LDVR.LT.1 .OR. ( WANTVR .AND. LDVR.LT.N ) ) THEN
          INFO = -10
       END IF
-
 *
 *     Compute workspace
 *      (Note: Comments in the code beginning "Workspace:" describe the
             IF( WANTVL ) THEN
                MAXWRK = MAX( MAXWRK, N + ( N - 1 )*ILAENV( 1, 'CUNGHR',
      $                       ' ', N, 1, N, -1 ) )
+               CALL CTREVC3( 'L', 'B', SELECT, N, A, LDA,
+     $                       VL, LDVL, VR, LDVR,
+     $                       N, NOUT, WORK, -1, RWORK, -1, IERR )
+               LWORK_TREVC = INT( WORK(1) )
+               MAXWRK = MAX( MAXWRK, N + LWORK_TREVC )
                CALL CHSEQR( 'S', 'V', N, 1, N, A, LDA, W, VL, LDVL,
-     $                WORK, -1, INFO )
+     $                      WORK, -1, INFO )
             ELSE IF( WANTVR ) THEN
                MAXWRK = MAX( MAXWRK, N + ( N - 1 )*ILAENV( 1, 'CUNGHR',
      $                       ' ', N, 1, N, -1 ) )
+               CALL CTREVC3( 'R', 'B', SELECT, N, A, LDA,
+     $                       VL, LDVL, VR, LDVR,
+     $                       N, NOUT, WORK, -1, RWORK, -1, IERR )
+               LWORK_TREVC = INT( WORK(1) )
+               MAXWRK = MAX( MAXWRK, N + LWORK_TREVC )
                CALL CHSEQR( 'S', 'V', N, 1, N, A, LDA, W, VR, LDVR,
-     $                WORK, -1, INFO )
+     $                      WORK, -1, INFO )
             ELSE
                CALL CHSEQR( 'E', 'N', N, 1, N, A, LDA, W, VR, LDVR,
-     $                WORK, -1, INFO )
+     $                      WORK, -1, INFO )
             END IF
-            HSWORK = WORK( 1 )
+            HSWORK = INT( WORK(1) )
             MAXWRK = MAX( MAXWRK, HSWORK, MINWRK )
          END IF
          WORK( 1 ) = MAXWRK
       IF( WANTVL .OR. WANTVR ) THEN
 *
 *        Compute left and/or right eigenvectors
-*        (CWorkspace: need 2*N)
+*        (CWorkspace: need 2*N, prefer N + 2*N*NB)
 *        (RWorkspace: need 2*N)
 *
          IRWORK = IBAL + N
-         CALL CTREVC( SIDE, 'B', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,
-     $                N, NOUT, WORK( IWRK ), RWORK( IRWORK ), IERR )
+         CALL CTREVC3( SIDE, 'B', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,
+     $                 N, NOUT, WORK( IWRK ), LWORK-IWRK+1,
+     $                 RWORK( IRWORK ), N, IERR )
       END IF
 *
       IF( WANTVL ) THEN
index 539a7b95fa4625543692cc26590ef810ee65f153..7ad229e72cdeebaad70b753c02a6965dd1256c61 100644 (file)
 *       .. Scalar Arguments ..
 *       CHARACTER          BALANC, JOBVL, JOBVR, SENSE
 *       INTEGER            IHI, ILO, INFO, LDA, LDVL, LDVR, LWORK, N
-*       REAL               ABNRM
+*       REAL   ABNRM
 *       ..
 *       .. Array Arguments ..
-*       REAL               RCONDE( * ), RCONDV( * ), RWORK( * ),
+*       REAL   RCONDE( * ), RCONDV( * ), RWORK( * ),
 *      $                   SCALE( * )
-*       COMPLEX            A( LDA, * ), VL( LDVL, * ), VR( LDVR, * ),
+*       COMPLEX         A( LDA, * ), VL( LDVL, * ), VR( LDVR, * ),
 *      $                   W( * ), WORK( * )
 *       ..
 *  
 *>          A is COMPLEX array, dimension (LDA,N)
 *>          On entry, the N-by-N matrix A.
 *>          On exit, A has been overwritten.  If JOBVL = 'V' or
-*>          JOBVR = 'V', A contains the Schur form of the balanced 
+*>          JOBVR = 'V', A contains the Schur form of the balanced
 *>          version of the matrix A.
 *> \endverbatim
 *>
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
+*
+*  @generated from zgeevx.f, fortran z -> c, Tue Apr 19 01:47:44 2016
 *
 *> \ingroup complexGEeigen
 *
       SUBROUTINE CGEEVX( BALANC, JOBVL, JOBVR, SENSE, N, A, LDA, W, VL,
      $                   LDVL, VR, LDVR, ILO, IHI, SCALE, ABNRM, RCONDE,
      $                   RCONDV, WORK, LWORK, RWORK, INFO )
+      implicit none
 *
-*  -- LAPACK driver routine (version 3.4.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          BALANC, JOBVL, JOBVR, SENSE
       INTEGER            IHI, ILO, INFO, LDA, LDVL, LDVR, LWORK, N
-      REAL               ABNRM
+      REAL   ABNRM
 *     ..
 *     .. Array Arguments ..
-      REAL               RCONDE( * ), RCONDV( * ), RWORK( * ),
+      REAL   RCONDE( * ), RCONDV( * ), RWORK( * ),
      $                   SCALE( * )
-      COMPLEX            A( LDA, * ), VL( LDVL, * ), VR( LDVR, * ),
+      COMPLEX         A( LDA, * ), VL( LDVL, * ), VR( LDVR, * ),
      $                   W( * ), WORK( * )
 *     ..
 *
 *  =====================================================================
 *
 *     .. Parameters ..
-      REAL               ZERO, ONE
+      REAL   ZERO, ONE
       PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0 )
 *     ..
 *     .. Local Scalars ..
       LOGICAL            LQUERY, SCALEA, WANTVL, WANTVR, WNTSNB, WNTSNE,
      $                   WNTSNN, WNTSNV
       CHARACTER          JOB, SIDE
-      INTEGER            HSWORK, I, ICOND, IERR, ITAU, IWRK, K, MAXWRK,
-     $                   MINWRK, NOUT
-      REAL               ANRM, BIGNUM, CSCALE, EPS, SCL, SMLNUM
-      COMPLEX            TMP
+      INTEGER            HSWORK, I, ICOND, IERR, ITAU, IWRK, K,
+     $                   LWORK_TREVC, MAXWRK, MINWRK, NOUT
+      REAL   ANRM, BIGNUM, CSCALE, EPS, SCL, SMLNUM
+      COMPLEX         TMP
 *     ..
 *     .. Local Arrays ..
       LOGICAL            SELECT( 1 )
-      REAL               DUM( 1 )
+      REAL   DUM( 1 )
 *     ..
 *     .. External Subroutines ..
-      EXTERNAL           CGEBAK, CGEBAL, CGEHRD, CHSEQR, CLACPY, CLASCL,
-     $                   CSCAL, CSSCAL, CTREVC, CTRSNA, CUNGHR, SLABAD,
-     $                   SLASCL, XERBLA
+      EXTERNAL           SLABAD, SLASCL, XERBLA, CSSCAL, CGEBAK, CGEBAL,
+     $                   CGEHRD, CHSEQR, CLACPY, CLASCL, CSCAL, CTREVC3,
+     $                   CTRSNA, CUNGHR
 *     ..
 *     .. External Functions ..
       LOGICAL            LSAME
-      INTEGER            ILAENV, ISAMAX
-      REAL               CLANGE, SCNRM2, SLAMCH
-      EXTERNAL           LSAME, ILAENV, ISAMAX, CLANGE, SCNRM2, SLAMCH
+      INTEGER            ISAMAX, ILAENV
+      REAL   SLAMCH, SCNRM2, CLANGE
+      EXTERNAL           LSAME, ISAMAX, ILAENV, SLAMCH, SCNRM2, CLANGE
 *     ..
 *     .. Intrinsic Functions ..
-      INTRINSIC          AIMAG, CMPLX, CONJG, MAX, REAL, SQRT
+      INTRINSIC          REAL, CMPLX, CONJG, AIMAG, MAX, SQRT
 *     ..
 *     .. Executable Statements ..
 *
             MAXWRK = N + N*ILAENV( 1, 'CGEHRD', ' ', N, 1, N, 0 )
 *
             IF( WANTVL ) THEN
+               CALL CTREVC3( 'L', 'B', SELECT, N, A, LDA,
+     $                       VL, LDVL, VR, LDVR,
+     $                       N, NOUT, WORK, -1, RWORK, -1, IERR )
+               LWORK_TREVC = INT( WORK(1) )
+               MAXWRK = MAX( MAXWRK, LWORK_TREVC )
                CALL CHSEQR( 'S', 'V', N, 1, N, A, LDA, W, VL, LDVL,
      $                WORK, -1, INFO )
             ELSE IF( WANTVR ) THEN
+               CALL CTREVC3( 'R', 'B', SELECT, N, A, LDA,
+     $                       VL, LDVL, VR, LDVR,
+     $                       N, NOUT, WORK, -1, RWORK, -1, IERR )
+               LWORK_TREVC = INT( WORK(1) )
+               MAXWRK = MAX( MAXWRK, LWORK_TREVC )
                CALL CHSEQR( 'S', 'V', N, 1, N, A, LDA, W, VR, LDVR,
      $                WORK, -1, INFO )
             ELSE
      $                WORK, -1, INFO )
                END IF
             END IF
-            HSWORK = WORK( 1 )
+            HSWORK = INT( WORK(1) )
 *
             IF( ( .NOT.WANTVL ) .AND. ( .NOT.WANTVR ) ) THEN
                MINWRK = 2*N
      $                WORK( IWRK ), LWORK-IWRK+1, INFO )
       END IF
 *
-*     If INFO > 0 from CHSEQR, then quit
+*     If INFO .NE. 0 from CHSEQR, then quit
 *
-      IF( INFO.GT.0 )
+      IF( INFO.NE.0 )
      $   GO TO 50
 *
       IF( WANTVL .OR. WANTVR ) THEN
 *
 *        Compute left and/or right eigenvectors
-*        (CWorkspace: need 2*N)
+*        (CWorkspace: need 2*N, prefer N + 2*N*NB)
 *        (RWorkspace: need N)
 *
-         CALL CTREVC( SIDE, 'B', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,
-     $                N, NOUT, WORK( IWRK ), RWORK, IERR )
+         CALL CTREVC3( SIDE, 'B', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,
+     $                 N, NOUT, WORK( IWRK ), LWORK-IWRK+1,
+     $                 RWORK, N, IERR )
       END IF
 *
 *     Compute condition numbers if desired
index 4b3e9056530e275a045840877032f6225008c952..bee18fdf839ca5e77f2aaf5b205c1851a391a607 100644 (file)
 *>
 *> \verbatim
 *>
-*> CGEJSV computes the singular value decomposition (SVD) of a real M-by-N
+*> CGEJSV computes the singular value decomposition (SVD) of a complex M-by-N
 *> matrix [A], where M >= N. The SVD of [A] is written as
 *>
 *>              [A] = [U] * [SIGMA] * [V]^*,
 *>
 *> where [SIGMA] is an N-by-N (M-by-N) matrix which is zero except for its N
-*> diagonal elements, [U] is an M-by-N (or M-by-M) orthonormal matrix, and
-*> [V] is an N-by-N orthogonal matrix. The diagonal elements of [SIGMA] are
+*> diagonal elements, [U] is an M-by-N (or M-by-M) unitary matrix, and
+*> [V] is an N-by-N unitary matrix. The diagonal elements of [SIGMA] are
 *> the singular values of [A]. The columns of [U] and [V] are the left and
 *> the right singular vectors of [A], respectively. The matrices [U] and [V]
 *> are computed and stored in the arrays U and V, respectively. The diagonal
 *> of [SIGMA] is computed and stored in the array SVA.
+*> \endverbatim
 *>
 *>  Arguments:
 *>  ==========
 *>
 *> \param[out] U
 *> \verbatim
-*>          U is COMPLEX array, dimension ( LDU, N )
+*>          U is COMPLEX array, dimension ( LDU, N ) or ( LDU, M )
 *>          If JOBU = 'U', then U contains on exit the M-by-N matrix of
 *>                         the left singular vectors.
 *>          If JOBU = 'F', then U contains on exit the M-by-M matrix of
 *>                         copied back to the V array. This 'W' option is just
 *>                         a reminder to the caller that in this case U is
 *>                         reserved as workspace of length N*N.
-*>          If JOBU = 'N'  U is not referenced.
+*>          If JOBU = 'N'  U is not referenced, unless JOBT='T'.
 *> \endverbatim
 *>
 *> \param[in] LDU
 *>                         copied back to the U array. This 'W' option is just
 *>                         a reminder to the caller that in this case V is
 *>                         reserved as workspace of length N*N.
-*>          If JOBV = 'N'  V is not referenced.
+*>          If JOBV = 'N'  V is not referenced, unless JOBT='T'.
 *> \endverbatim
 *>
 *> \param[in] LDV
 *>          LWORK depends on the job:
 *>
 *>          1. If only SIGMA is needed ( JOBU.EQ.'N', JOBV.EQ.'N' ) and
-*>            1.1 .. no scaled condition estimate required (JOBE.EQ.'N'):
+*>            1.1 .. no scaled condition estimate required (JOBA.NE.'E'.AND.JOBA.NE.'G'):
 *>               LWORK >= 2*N+1. This is the minimal requirement.
 *>               ->> For optimal performance (blocked code) the optimal value
 *>               is LWORK >= N + (N+1)*NB. Here NB is the optimal
 *>             (JOBU.EQ.'N')
 *>            -> the minimal requirement is LWORK >= 3*N.
 *>            -> For optimal performance, LWORK >= max(N+(N+1)*NB, 3*N,2*N+N*NB),
-*>               where NB is the optimal block size for CGEQP3, CGEQRF, CGELQ,
+*>               where NB is the optimal block size for CGEQP3, CGEQRF, CGELQF,
 *>               CUNMLQ. In general, the optimal length LWORK is computed as
 *>               LWORK >= max(N+LWORK(CGEQP3), N+LWORK(CPOCON), N+LWORK(CGESVJ),
 *>                       N+LWORK(CGELQF), 2*N+LWORK(CGEQRF), N+LWORK(CUNMLQ)).
 *>               the minimal requirement is LWORK >= 5*N+2*N*N. 
 *>            4.2. if JOBV.EQ.'J' the minimal requirement is 
 *>               LWORK >= 4*N+N*N.
-*>            In both cases, the allocated CWORK can accomodate blocked runs
-*>            of CGEQP3, CGEQRF, CGELQF, SUNMQR, CUNMLQ.
+*>            In both cases, the allocated CWORK can accommodate blocked runs
+*>            of CGEQP3, CGEQRF, CGELQF, CUNMQR, CUNMLQ.
 *> \endverbatim
 *>
 *> \param[out] RWORK
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complexGEsing
 *
 *>     LAPACK Working note 170.
 *> [3] Z. Drmac and Z. Bujanovic: On the failure of rank-revealing QR
 *>     factorization software - a case study.
-*>     ACM Trans. math. Softw. Vol. 35, No 2 (2008), pp. 1-28.
+*>     ACM Trans. Math. Softw. Vol. 35, No 2 (2008), pp. 1-28.
 *>     LAPACK Working note 176.
 *> [4] Z. Drmac: SIGMA - mathematical software library for accurate SVD, PSV,
 *>     QSVD, (H,K)-SVD computations.
      $                   M, N, A, LDA, SVA, U, LDU, V, LDV,
      $                   CWORK, LWORK, RWORK, LRWORK, IWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       IMPLICIT    NONE
 *     ..
 *     .. External Functions ..
       REAL      SLAMCH, SCNRM2
-      INTEGER   ISAMAX
+      INTEGER   ISAMAX, ICAMAX
       LOGICAL   LSAME
-      EXTERNAL  ISAMAX, LSAME, SLAMCH, SCNRM2
+      EXTERNAL  ISAMAX, ICAMAX, LSAME, SLAMCH, SCNRM2
 *     ..
 *     .. External Subroutines ..
       EXTERNAL  CCOPY,  CGELQF, CGEQP3, CGEQRF, CLACPY, CLASCL,
-     $          CLASET, CLASSQ, CLASWP, CUNGQR, CUNMLQ,
+     $          SLASCL, CLASET, CLASSQ, SLASSQ, CLASWP, CUNGQR, CUNMLQ,
      $          CUNMQR, CPOCON, SSCAL, CSSCAL, CSWAP,  CTRSM,  XERBLA
 *
       EXTERNAL  CGESVJ
 *
 *     Quick return for void matrix (Y3K safe)
 * #:)
-      IF ( ( M .EQ. 0 ) .OR. ( N .EQ. 0 ) ) RETURN
+      IF ( ( M .EQ. 0 ) .OR. ( N .EQ. 0 ) ) THEN
+         IWORK(1:3) = 0
+         RWORK(1:7) = 0
+         RETURN
+      ENDIF
 *
 *     Determine whether the matrix U should be M x N or M x M
 *
  1950       CONTINUE
          ELSE
             DO 1904 p = 1, M
-               RWORK(M+N+p) = SCALEM*ABS( A(p,ISAMAX(N,A(p,1),LDA)) )
+               RWORK(M+N+p) = SCALEM*ABS( A(p,ICAMAX(N,A(p,1),LDA)) )
                AATMAX = AMAX1( AATMAX, RWORK(M+N+p) )
                AATMIN = AMIN1( AATMIN, RWORK(M+N+p) )
  1904       CONTINUE
 *
          XSC   = ZERO
          TEMP1 = ONE
-         CALL CLASSQ( N, SVA, 1, XSC, TEMP1 )
+         CALL SLASSQ( N, SVA, 1, XSC, TEMP1 )
          TEMP1 = ONE / TEMP1
 *
          ENTRA = ZERO
       BIG1   = SQRT( BIG )
       TEMP1  = SQRT( BIG / FLOAT(N) )
 *
-      CALL CLASCL( 'G', 0, 0, AAPP, TEMP1, N, 1, SVA, N, IERR )
+      CALL SLASCL( 'G', 0, 0, AAPP, TEMP1, N, 1, SVA, N, IERR )
       IF ( AAQQ .GT. (AAPP * SFMIN) ) THEN
           AAQQ = ( AAQQ / AAPP ) * TEMP1
       ELSE
                CALL CCOPY( NR-p+1, V(p,p), LDV, V(p,p), 1 )
                CALL CLACGV( NR-p+1, V(p,p), 1 ) 
  8998       CONTINUE
-            CALL CLASET( 'Upper', NR-1, NR-1, ZERO, ZERO, V(1,2), LDV )
+            CALL CLASET('Upper', NR-1, NR-1, CZERO, CZERO, V(1,2), LDV)
 *
             CALL CGESVJ( 'Lower', 'U','N', NR, NR, V,LDV, SVA, NR, U,
      $                  LDU, CWORK(N+1), LWORK-N, RWORK, LRWORK, INFO )
                   CALL CTRSM('L','U','C','N',NR,NR,CONE,CWORK(2*N+1),
      $                 N,V,LDV)
                   IF ( NR .LT. N ) THEN
-                   CALL CLASET('A',N-NR,NR,ZERO,CZERO,V(NR+1,1),LDV)
-                   CALL CLASET('A',NR,N-NR,ZERO,CZERO,V(1,NR+1),LDV)
-                   CALL CLASET('A',N-NR,N-NR,ZERO,CONE,V(NR+1,NR+1),LDV)
+                  CALL CLASET('A',N-NR,NR,CZERO,CZERO,V(NR+1,1),LDV)
+                  CALL CLASET('A',NR,N-NR,CZERO,CZERO,V(1,NR+1),LDV)
+                  CALL CLASET('A',N-NR,N-NR,CZERO,CONE,V(NR+1,NR+1),LDV)
                   END IF
                   CALL CUNMQR('L','N',N,N,NR,CWORK(2*N+1),N,CWORK(N+1),
      $                V,LDV,CWORK(2*N+N*NR+NR+1),LWORK-2*N-N*NR-NR,IERR)
          NUMRANK = NINT(RWORK(2))
 
          IF ( NR .LT. N ) THEN
-            CALL CLASET( 'A',N-NR,NR,ZERO,ZERO,V(NR+1,1),LDV )
-            CALL CLASET( 'A',NR,N-NR,ZERO,ZERO,V(1,NR+1),LDV )
-            CALL CLASET( 'A',N-NR,N-NR,ZERO,ONE,V(NR+1,NR+1),LDV )
+            CALL CLASET( 'A',N-NR,NR,CZERO,CZERO,V(NR+1,1),LDV )
+            CALL CLASET( 'A',NR,N-NR,CZERO,CZERO,V(1,NR+1),LDV )
+            CALL CLASET( 'A',N-NR,N-NR,CZERO,CONE,V(NR+1,NR+1),LDV )
          END IF
 
          CALL CUNMQR( 'L','N',N,N,NR,CWORK(2*N+1),N,CWORK(N+1),
 *     Undo scaling, if necessary (and possible)
 *
       IF ( USCAL2 .LE. (BIG/SVA(1))*USCAL1 ) THEN
-         CALL CLASCL( 'G', 0, 0, USCAL1, USCAL2, NR, 1, SVA, N, IERR )
+         CALL SLASCL( 'G', 0, 0, USCAL1, USCAL2, NR, 1, SVA, N, IERR )
          USCAL1 = ONE
          USCAL2 = ONE
       END IF
index 2d09053582f71e780be7d451aa6f84b4cb4663ac..6cb4026a42f0b20c7148df9af2bdd2de31fb97ff 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup complexGEsolve
 *
       SUBROUTINE CGELSS( M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK,
      $                   WORK, LWORK, RWORK, INFO )
 *
-*  -- LAPACK driver routine (version 3.4.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
 *              Path 1 - overdetermined or exactly determined
 *
 *              Compute space needed for CGEBRD
-               CALL CGEBRD( MM, N, A, LDA, S, DUM(1), DUM(1),
-     $                      DUM(1), DUM(1), -1, INFO )
+               CALL CGEBRD( MM, N, A, LDA, S, S, DUM(1), DUM(1), DUM(1),
+     $                      -1, INFO )
                LWORK_CGEBRD=DUM(1)
 *              Compute space needed for CUNMBR
                CALL CUNMBR( 'Q', 'L', 'C', MM, NRHS, N, A, LDA, DUM(1),
      $                -1, INFO )
                   LWORK_CGELQF=DUM(1)
 *                 Compute space needed for CGEBRD
-                  CALL CGEBRD( M, M, A, LDA, S, DUM(1), DUM(1),
-     $                      DUM(1), DUM(1), -1, INFO )
+                  CALL CGEBRD( M, M, A, LDA, S, S, DUM(1), DUM(1),
+     $                         DUM(1), -1, INFO )
                   LWORK_CGEBRD=DUM(1)
 *                 Compute space needed for CUNMBR
                   CALL CUNMBR( 'Q', 'L', 'C', M, NRHS, N, A, LDA, 
 *                 Path 2 - underdetermined
 *
 *                 Compute space needed for CGEBRD
-                  CALL CGEBRD( M, N, A, LDA, S, DUM(1), DUM(1),
-     $                      DUM(1), DUM(1), -1, INFO )
+                  CALL CGEBRD( M, N, A, LDA, S, S, DUM(1), DUM(1),
+     $                         DUM(1), -1, INFO )
                   LWORK_CGEBRD=DUM(1)
 *                 Compute space needed for CUNMBR
                   CALL CUNMBR( 'Q', 'L', 'C', M, NRHS, M, A, LDA, 
index a5b55c1d32ae85abe9966112ecb140e51e368533..9bcb82d71f8af701d6ea932213a7ddf28f414c1c 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup complexGEcomputational
 *
 *  =====================================================================
       RECURSIVE SUBROUTINE CGEQRT3( M, N, A, LDA, T, LDT, INFO )
 *
-*  -- LAPACK computational routine (version 3.4.2) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER   INFO, LDA, M, N, LDT
 *
 *        Compute Householder transform when N=1
 *
-         CALL CLARFG( M, A, A( MIN( 2, M ), 1 ), 1, T )
+         CALL CLARFG( M, A(1,1), A( MIN( 2, M ), 1 ), 1, T(1,1) )
 *         
       ELSE
 *
index 7f16b63b6617dfe92f55e04422cf605f00bf89bd..986619c6c5e735baed780c42b07bad0bbc630242 100644 (file)
 *> \param[in] LDU
 *> \verbatim
 *>          LDU is INTEGER
-*>          The leading dimension of the array U.  LDU >= 1; if
-*>          JOBZ = 'S' or 'A' or JOBZ = 'O' and M < N, LDU >= M.
+*>          The leading dimension of the array U.  LDU >= 1;
+*>          if JOBZ = 'S' or 'A' or JOBZ = 'O' and M < N, LDU >= M.
 *> \endverbatim
 *>
 *> \param[out] VT
 *> \param[in] LDVT
 *> \verbatim
 *>          LDVT is INTEGER
-*>          The leading dimension of the array VT.  LDVT >= 1; if
-*>          JOBZ = 'A' or JOBZ = 'O' and M >= N, LDVT >= N;
+*>          The leading dimension of the array VT.  LDVT >= 1;
+*>          if JOBZ = 'A' or JOBZ = 'O' and M >= N, LDVT >= N;
 *>          if JOBZ = 'S', LDVT >= min(M,N).
 *> \endverbatim
 *>
 *> \verbatim
 *>          LWORK is INTEGER
 *>          The dimension of the array WORK. LWORK >= 1.
-*>          if JOBZ = 'N', LWORK >= 2*min(M,N)+max(M,N).
-*>          if JOBZ = 'O',
-*>                LWORK >= 2*min(M,N)*min(M,N)+2*min(M,N)+max(M,N).
-*>          if JOBZ = 'S' or 'A',
-*>                LWORK >= min(M,N)*min(M,N)+2*min(M,N)+max(M,N).
-*>          For good performance, LWORK should generally be larger.
-*>
 *>          If LWORK = -1, a workspace query is assumed.  The optimal
 *>          size for the WORK array is calculated and stored in WORK(1),
 *>          and no other work except argument checking is performed.
+*>
+*>          Let mx = max(M,N) and mn = min(M,N).
+*>          If JOBZ = 'N', LWORK >= 2*mn + mx.
+*>          If JOBZ = 'O', LWORK >= 2*mn*mn + 2*mn + mx.
+*>          If JOBZ = 'S', LWORK >=   mn*mn + 3*mn.
+*>          If JOBZ = 'A', LWORK >=   mn*mn + 2*mn + mx.
+*>          These are not tight minimums in all cases; see comments inside code.
+*>          For good performance, LWORK should generally be larger;
+*>          a query is recommended.
 *> \endverbatim
 *>
 *> \param[out] RWORK
 *> \verbatim
 *>          RWORK is REAL array, dimension (MAX(1,LRWORK))
-*>          If JOBZ = 'N', LRWORK >= 7*min(M,N).
-*>          Otherwise, 
-*>          LRWORK >= min(M,N)*max(5*min(M,N)+7,2*max(M,N)+2*min(M,N)+1)
+*>          Let mx = max(M,N) and mn = min(M,N).
+*>          If JOBZ = 'N',    LRWORK >= 5*mn (LAPACK <= 3.6 needs 7*mn);
+*>          else if mx >> mn, LRWORK >= 5*mn*mn + 5*mn;
+*>          else              LRWORK >= max( 5*mn*mn + 5*mn,
+*>                                           2*mx*mn + 2*mn*mn + mn ).
 *> \endverbatim
 *>
 *> \param[out] IWORK
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complexGEsing
 *
 *  =====================================================================
       SUBROUTINE CGESDD( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT,
      $                   WORK, LWORK, RWORK, IWORK, INFO )
+      implicit none
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ
 *  =====================================================================
 *
 *     .. Parameters ..
-      INTEGER            LQUERV
-      PARAMETER          ( LQUERV = -1 )
       COMPLEX            CZERO, CONE
       PARAMETER          ( CZERO = ( 0.0E+0, 0.0E+0 ),
      $                   CONE = ( 1.0E+0, 0.0E+0 ) )
       PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
 *     ..
 *     .. Local Scalars ..
-      LOGICAL            WNTQA, WNTQAS, WNTQN, WNTQO, WNTQS
+      LOGICAL            LQUERY, WNTQA, WNTQAS, WNTQN, WNTQO, WNTQS
       INTEGER            BLK, CHUNK, I, IE, IERR, IL, IR, IRU, IRVT,
      $                   ISCL, ITAU, ITAUP, ITAUQ, IU, IVT, LDWKVT,
      $                   LDWRKL, LDWRKR, LDWRKU, MAXWRK, MINMN, MINWRK,
      $                   MNTHR1, MNTHR2, NRWORK, NWORK, WRKBL
-      REAL               ANRM, BIGNUM, EPS, SMLNUM
+      INTEGER            LWORK_CGEBRD_MN, LWORK_CGEBRD_MM, 
+     $                   LWORK_CGEBRD_NN, LWORK_CGELQF_MN,
+     $                   LWORK_CGEQRF_MN,
+     $                   LWORK_CUNGBR_P_MN, LWORK_CUNGBR_P_NN,
+     $                   LWORK_CUNGBR_Q_MN, LWORK_CUNGBR_Q_MM,
+     $                   LWORK_CUNGLQ_MN, LWORK_CUNGLQ_NN,
+     $                   LWORK_CUNGQR_MM, LWORK_CUNGQR_MN,
+     $                   LWORK_CUNMBR_PRC_MM, LWORK_CUNMBR_QLN_MM,
+     $                   LWORK_CUNMBR_PRC_MN, LWORK_CUNMBR_QLN_MN,
+     $                   LWORK_CUNMBR_PRC_NN, LWORK_CUNMBR_QLN_NN
+      REAL   ANRM, BIGNUM, EPS, SMLNUM
 *     ..
 *     .. Local Arrays ..
       INTEGER            IDUM( 1 )
       REAL               DUM( 1 )
+      COMPLEX            CDUM( 1 )
 *     ..
 *     .. External Subroutines ..
       EXTERNAL           CGEBRD, CGELQF, CGEMM, CGEQRF, CLACP2, CLACPY,
 *     ..
 *     .. External Functions ..
       LOGICAL            LSAME
-      INTEGER            ILAENV
-      REAL               CLANGE, SLAMCH
-      EXTERNAL           CLANGE, SLAMCH, ILAENV, LSAME
+      REAL               SLAMCH, CLANGE
+      EXTERNAL           LSAME, SLAMCH, CLANGE
 *     ..
 *     .. Intrinsic Functions ..
       INTRINSIC          INT, MAX, MIN, SQRT
 *
 *     Test the input arguments
 *
-      INFO = 0
-      MINMN = MIN( M, N )
-      MNTHR1 = INT( MINMN*17.0 / 9.0 )
-      MNTHR2 = INT( MINMN*5.0 / 3.0 )
-      WNTQA = LSAME( JOBZ, 'A' )
-      WNTQS = LSAME( JOBZ, 'S' )
+      INFO   = 0
+      MINMN  = MIN( M, N )
+      MNTHR1 = INT( MINMN*17.0E0 / 9.0E0 )
+      MNTHR2 = INT( MINMN*5.0E0 / 3.0E0 )
+      WNTQA  = LSAME( JOBZ, 'A' )
+      WNTQS  = LSAME( JOBZ, 'S' )
       WNTQAS = WNTQA .OR. WNTQS
-      WNTQO = LSAME( JOBZ, 'O' )
-      WNTQN = LSAME( JOBZ, 'N' )
+      WNTQO  = LSAME( JOBZ, 'O' )
+      WNTQN  = LSAME( JOBZ, 'N' )
+      LQUERY = ( LWORK.EQ.-1 )
       MINWRK = 1
       MAXWRK = 1
 *
       END IF
 *
 *     Compute workspace
-*      (Note: Comments in the code beginning "Workspace:" describe the
-*       minimal amount of workspace needed at that point in the code,
+*       Note: Comments in the code beginning "Workspace:" describe the
+*       minimal amount of workspace allocated at that point in the code,
 *       as well as the preferred amount for good performance.
 *       CWorkspace refers to complex workspace, and RWorkspace to
 *       real workspace. NB refers to the optimal block size for the
          IF( M.GE.N ) THEN
 *
 *           There is no complex work space needed for bidiagonal SVD
-*           The real work space needed for bidiagonal SVD is BDSPAC
-*           for computing singular values and singular vectors; BDSPAN
-*           for computing singular values only.
-*           BDSPAC = 5*N*N + 7*N
-*           BDSPAN = MAX(7*N+4, 3*N+2+SMLSIZ*(SMLSIZ+8))
+*           The real work space needed for bidiagonal SVD (sbdsdc) is
+*           BDSPAC = 3*N*N + 4*N for singular values and vectors;
+*           BDSPAC = 4*N         for singular values only;
+*           not including e, RU, and RVT matrices.
+*
+*           Compute space preferred for each routine
+            CALL CGEBRD( M, N, CDUM(1), M, DUM(1), DUM(1), CDUM(1),
+     $                   CDUM(1), CDUM(1), -1, IERR )
+            LWORK_CGEBRD_MN = INT( CDUM(1) )
+*
+            CALL CGEBRD( N, N, CDUM(1), N, DUM(1), DUM(1), CDUM(1),
+     $                   CDUM(1), CDUM(1), -1, IERR )
+            LWORK_CGEBRD_NN = INT( CDUM(1) )
+*
+            CALL CGEQRF( M, N, CDUM(1), M, CDUM(1), CDUM(1), -1, IERR )
+            LWORK_CGEQRF_MN = INT( CDUM(1) )
+*
+            CALL CUNGBR( 'P', N, N, N, CDUM(1), N, CDUM(1), CDUM(1),
+     $                   -1, IERR )
+            LWORK_CUNGBR_P_NN = INT( CDUM(1) )
+*
+            CALL CUNGBR( 'Q', M, M, N, CDUM(1), M, CDUM(1), CDUM(1),
+     $                   -1, IERR )
+            LWORK_CUNGBR_Q_MM = INT( CDUM(1) )
+*
+            CALL CUNGBR( 'Q', M, N, N, CDUM(1), M, CDUM(1), CDUM(1),
+     $                   -1, IERR )
+            LWORK_CUNGBR_Q_MN = INT( CDUM(1) )
+*
+            CALL CUNGQR( M, M, N, CDUM(1), M, CDUM(1), CDUM(1),
+     $                   -1, IERR )
+            LWORK_CUNGQR_MM = INT( CDUM(1) )
+*
+            CALL CUNGQR( M, N, N, CDUM(1), M, CDUM(1), CDUM(1),
+     $                   -1, IERR )
+            LWORK_CUNGQR_MN = INT( CDUM(1) )
+*
+            CALL CUNMBR( 'P', 'R', 'C', N, N, N, CDUM(1), N, CDUM(1),
+     $                   CDUM(1), N, CDUM(1), -1, IERR )
+            LWORK_CUNMBR_PRC_NN = INT( CDUM(1) )
+*
+            CALL CUNMBR( 'Q', 'L', 'N', M, M, N, CDUM(1), M, CDUM(1),
+     $                   CDUM(1), M, CDUM(1), -1, IERR )
+            LWORK_CUNMBR_QLN_MM = INT( CDUM(1) )
+*
+            CALL CUNMBR( 'Q', 'L', 'N', M, N, N, CDUM(1), M, CDUM(1),
+     $                   CDUM(1), M, CDUM(1), -1, IERR )
+            LWORK_CUNMBR_QLN_MN = INT( CDUM(1) )
+*
+            CALL CUNMBR( 'Q', 'L', 'N', N, N, N, CDUM(1), N, CDUM(1),
+     $                   CDUM(1), N, CDUM(1), -1, IERR )
+            LWORK_CUNMBR_QLN_NN = INT( CDUM(1) )
 *
             IF( M.GE.MNTHR1 ) THEN
                IF( WNTQN ) THEN
 *
-*                 Path 1 (M much larger than N, JOBZ='N')
+*                 Path 1 (M >> N, JOBZ='N')
 *
-                  MAXWRK = N + N*ILAENV( 1, 'CGEQRF', ' ', M, N, -1,
-     $                     -1 )
-                  MAXWRK = MAX( MAXWRK, 2*N+2*N*
-     $                     ILAENV( 1, 'CGEBRD', ' ', N, N, -1, -1 ) )
+                  MAXWRK = N + LWORK_CGEQRF_MN
+                  MAXWRK = MAX( MAXWRK, 2*N + LWORK_CGEBRD_NN )
                   MINWRK = 3*N
                ELSE IF( WNTQO ) THEN
 *
-*                 Path 2 (M much larger than N, JOBZ='O')
-*
-                  WRKBL = N + N*ILAENV( 1, 'CGEQRF', ' ', M, N, -1, -1 )
-                  WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'CUNGQR', ' ', M,
-     $                    N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*N+2*N*
-     $                    ILAENV( 1, 'CGEBRD', ' ', N, N, -1, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*N+N*
-     $                    ILAENV( 1, 'CUNMBR', 'QLN', N, N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*N+N*
-     $                    ILAENV( 1, 'CUNMBR', 'PRC', N, N, N, -1 ) )
+*                 Path 2 (M >> N, JOBZ='O')
+*
+                  WRKBL = N + LWORK_CGEQRF_MN
+                  WRKBL = MAX( WRKBL,   N + LWORK_CUNGQR_MN )
+                  WRKBL = MAX( WRKBL, 2*N + LWORK_CGEBRD_NN )
+                  WRKBL = MAX( WRKBL, 2*N + LWORK_CUNMBR_QLN_NN )
+                  WRKBL = MAX( WRKBL, 2*N + LWORK_CUNMBR_PRC_NN )
                   MAXWRK = M*N + N*N + WRKBL
                   MINWRK = 2*N*N + 3*N
                ELSE IF( WNTQS ) THEN
 *
-*                 Path 3 (M much larger than N, JOBZ='S')
-*
-                  WRKBL = N + N*ILAENV( 1, 'CGEQRF', ' ', M, N, -1, -1 )
-                  WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'CUNGQR', ' ', M,
-     $                    N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*N+2*N*
-     $                    ILAENV( 1, 'CGEBRD', ' ', N, N, -1, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*N+N*
-     $                    ILAENV( 1, 'CUNMBR', 'QLN', N, N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*N+N*
-     $                    ILAENV( 1, 'CUNMBR', 'PRC', N, N, N, -1 ) )
+*                 Path 3 (M >> N, JOBZ='S')
+*
+                  WRKBL = N + LWORK_CGEQRF_MN
+                  WRKBL = MAX( WRKBL,   N + LWORK_CUNGQR_MN )
+                  WRKBL = MAX( WRKBL, 2*N + LWORK_CGEBRD_NN )
+                  WRKBL = MAX( WRKBL, 2*N + LWORK_CUNMBR_QLN_NN )
+                  WRKBL = MAX( WRKBL, 2*N + LWORK_CUNMBR_PRC_NN )
                   MAXWRK = N*N + WRKBL
                   MINWRK = N*N + 3*N
                ELSE IF( WNTQA ) THEN
 *
-*                 Path 4 (M much larger than N, JOBZ='A')
-*
-                  WRKBL = N + N*ILAENV( 1, 'CGEQRF', ' ', M, N, -1, -1 )
-                  WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'CUNGQR', ' ', M,
-     $                    M, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*N+2*N*
-     $                    ILAENV( 1, 'CGEBRD', ' ', N, N, -1, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*N+N*
-     $                    ILAENV( 1, 'CUNMBR', 'QLN', N, N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*N+N*
-     $                    ILAENV( 1, 'CUNMBR', 'PRC', N, N, N, -1 ) )
+*                 Path 4 (M >> N, JOBZ='A')
+*
+                  WRKBL = N + LWORK_CGEQRF_MN
+                  WRKBL = MAX( WRKBL,   N + LWORK_CUNGQR_MM )
+                  WRKBL = MAX( WRKBL, 2*N + LWORK_CGEBRD_NN )
+                  WRKBL = MAX( WRKBL, 2*N + LWORK_CUNMBR_QLN_NN )
+                  WRKBL = MAX( WRKBL, 2*N + LWORK_CUNMBR_PRC_NN )
                   MAXWRK = N*N + WRKBL
-                  MINWRK = N*N + 2*N + M
+                  MINWRK = N*N + MAX( 3*N, N + M )
                END IF
             ELSE IF( M.GE.MNTHR2 ) THEN
 *
-*              Path 5 (M much larger than N, but not as much as MNTHR1)
+*              Path 5 (M >> N, but not as much as MNTHR1)
 *
-               MAXWRK = 2*N + ( M+N )*ILAENV( 1, 'CGEBRD', ' ', M, N,
-     $                  -1, -1 )
+               MAXWRK = 2*N + LWORK_CGEBRD_MN
                MINWRK = 2*N + M
                IF( WNTQO ) THEN
-                  MAXWRK = MAX( MAXWRK, 2*N+N*
-     $                     ILAENV( 1, 'CUNGBR', 'P', N, N, N, -1 ) )
-                  MAXWRK = MAX( MAXWRK, 2*N+N*
-     $                     ILAENV( 1, 'CUNGBR', 'Q', M, N, N, -1 ) )
+*                 Path 5o (M >> N, JOBZ='O')
+                  MAXWRK = MAX( MAXWRK, 2*N + LWORK_CUNGBR_P_NN )
+                  MAXWRK = MAX( MAXWRK, 2*N + LWORK_CUNGBR_Q_MN )
                   MAXWRK = MAXWRK + M*N
                   MINWRK = MINWRK + N*N
                ELSE IF( WNTQS ) THEN
-                  MAXWRK = MAX( MAXWRK, 2*N+N*
-     $                     ILAENV( 1, 'CUNGBR', 'P', N, N, N, -1 ) )
-                  MAXWRK = MAX( MAXWRK, 2*N+N*
-     $                     ILAENV( 1, 'CUNGBR', 'Q', M, N, N, -1 ) )
+*                 Path 5s (M >> N, JOBZ='S')
+                  MAXWRK = MAX( MAXWRK, 2*N + LWORK_CUNGBR_P_NN )
+                  MAXWRK = MAX( MAXWRK, 2*N + LWORK_CUNGBR_Q_MN )
                ELSE IF( WNTQA ) THEN
-                  MAXWRK = MAX( MAXWRK, 2*N+N*
-     $                     ILAENV( 1, 'CUNGBR', 'P', N, N, N, -1 ) )
-                  MAXWRK = MAX( MAXWRK, 2*N+M*
-     $                     ILAENV( 1, 'CUNGBR', 'Q', M, M, N, -1 ) )
+*                 Path 5a (M >> N, JOBZ='A')
+                  MAXWRK = MAX( MAXWRK, 2*N + LWORK_CUNGBR_P_NN )
+                  MAXWRK = MAX( MAXWRK, 2*N + LWORK_CUNGBR_Q_MM )
                END IF
             ELSE
 *
-*              Path 6 (M at least N, but not much larger)
+*              Path 6 (M >= N, but not much larger)
 *
-               MAXWRK = 2*N + ( M+N )*ILAENV( 1, 'CGEBRD', ' ', M, N,
-     $                  -1, -1 )
+               MAXWRK = 2*N + LWORK_CGEBRD_MN
                MINWRK = 2*N + M
                IF( WNTQO ) THEN
-                  MAXWRK = MAX( MAXWRK, 2*N+N*
-     $                     ILAENV( 1, 'CUNMBR', 'PRC', N, N, N, -1 ) )
-                  MAXWRK = MAX( MAXWRK, 2*N+N*
-     $                     ILAENV( 1, 'CUNMBR', 'QLN', M, N, N, -1 ) )
+*                 Path 6o (M >= N, JOBZ='O')
+                  MAXWRK = MAX( MAXWRK, 2*N + LWORK_CUNMBR_PRC_NN )
+                  MAXWRK = MAX( MAXWRK, 2*N + LWORK_CUNMBR_QLN_MN )
                   MAXWRK = MAXWRK + M*N
                   MINWRK = MINWRK + N*N
                ELSE IF( WNTQS ) THEN
-                  MAXWRK = MAX( MAXWRK, 2*N+N*
-     $                     ILAENV( 1, 'CUNMBR', 'PRC', N, N, N, -1 ) )
-                  MAXWRK = MAX( MAXWRK, 2*N+N*
-     $                     ILAENV( 1, 'CUNMBR', 'QLN', M, N, N, -1 ) )
+*                 Path 6s (M >= N, JOBZ='S')
+                  MAXWRK = MAX( MAXWRK, 2*N + LWORK_CUNMBR_QLN_MN )
+                  MAXWRK = MAX( MAXWRK, 2*N + LWORK_CUNMBR_PRC_NN )
                ELSE IF( WNTQA ) THEN
-                  MAXWRK = MAX( MAXWRK, 2*N+N*
-     $                     ILAENV( 1, 'CUNGBR', 'PRC', N, N, N, -1 ) )
-                  MAXWRK = MAX( MAXWRK, 2*N+M*
-     $                     ILAENV( 1, 'CUNGBR', 'QLN', M, M, N, -1 ) )
+*                 Path 6a (M >= N, JOBZ='A')
+                  MAXWRK = MAX( MAXWRK, 2*N + LWORK_CUNMBR_QLN_MM )
+                  MAXWRK = MAX( MAXWRK, 2*N + LWORK_CUNMBR_PRC_NN )
                END IF
             END IF
          ELSE
 *
 *           There is no complex work space needed for bidiagonal SVD
-*           The real work space needed for bidiagonal SVD is BDSPAC
-*           for computing singular values and singular vectors; BDSPAN
-*           for computing singular values only.
-*           BDSPAC = 5*M*M + 7*M
-*           BDSPAN = MAX(7*M+4, 3*M+2+SMLSIZ*(SMLSIZ+8))
+*           The real work space needed for bidiagonal SVD (sbdsdc) is
+*           BDSPAC = 3*M*M + 4*M for singular values and vectors;
+*           BDSPAC = 4*M         for singular values only;
+*           not including e, RU, and RVT matrices.
+*
+*           Compute space preferred for each routine
+            CALL CGEBRD( M, N, CDUM(1), M, DUM(1), DUM(1), CDUM(1),
+     $                   CDUM(1), CDUM(1), -1, IERR )
+            LWORK_CGEBRD_MN = INT( CDUM(1) )
+*
+            CALL CGEBRD( M, M, CDUM(1), M, DUM(1), DUM(1), CDUM(1),
+     $                   CDUM(1), CDUM(1), -1, IERR )
+            LWORK_CGEBRD_MM = INT( CDUM(1) )
+*
+            CALL CGELQF( M, N, CDUM(1), M, CDUM(1), CDUM(1), -1, IERR )
+            LWORK_CGELQF_MN = INT( CDUM(1) )
+*
+            CALL CUNGBR( 'P', M, N, M, CDUM(1), M, CDUM(1), CDUM(1),
+     $                   -1, IERR )
+            LWORK_CUNGBR_P_MN = INT( CDUM(1) )
+*
+            CALL CUNGBR( 'P', N, N, M, CDUM(1), N, CDUM(1), CDUM(1),
+     $                   -1, IERR )
+            LWORK_CUNGBR_P_NN = INT( CDUM(1) )
+*
+            CALL CUNGBR( 'Q', M, M, N, CDUM(1), M, CDUM(1), CDUM(1),
+     $                   -1, IERR )
+            LWORK_CUNGBR_Q_MM = INT( CDUM(1) )
+*
+            CALL CUNGLQ( M, N, M, CDUM(1), M, CDUM(1), CDUM(1),
+     $                   -1, IERR )
+            LWORK_CUNGLQ_MN = INT( CDUM(1) )
+*
+            CALL CUNGLQ( N, N, M, CDUM(1), N, CDUM(1), CDUM(1),
+     $                   -1, IERR )
+            LWORK_CUNGLQ_NN = INT( CDUM(1) )
+*
+            CALL CUNMBR( 'P', 'R', 'C', M, M, M, CDUM(1), M, CDUM(1),
+     $                   CDUM(1), M, CDUM(1), -1, IERR )
+            LWORK_CUNMBR_PRC_MM = INT( CDUM(1) )
+*
+            CALL CUNMBR( 'P', 'R', 'C', M, N, M, CDUM(1), M, CDUM(1),
+     $                   CDUM(1), M, CDUM(1), -1, IERR )
+            LWORK_CUNMBR_PRC_MN = INT( CDUM(1) )
+*
+            CALL CUNMBR( 'P', 'R', 'C', N, N, M, CDUM(1), N, CDUM(1),
+     $                   CDUM(1), N, CDUM(1), -1, IERR )
+            LWORK_CUNMBR_PRC_NN = INT( CDUM(1) )
+*
+            CALL CUNMBR( 'Q', 'L', 'N', M, M, M, CDUM(1), M, CDUM(1),
+     $                   CDUM(1), M, CDUM(1), -1, IERR )
+            LWORK_CUNMBR_QLN_MM = INT( CDUM(1) )
 *
             IF( N.GE.MNTHR1 ) THEN
                IF( WNTQN ) THEN
 *
-*                 Path 1t (N much larger than M, JOBZ='N')
+*                 Path 1t (N >> M, JOBZ='N')
 *
-                  MAXWRK = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1,
-     $                     -1 )
-                  MAXWRK = MAX( MAXWRK, 2*M+2*M*
-     $                     ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
+                  MAXWRK = M + LWORK_CGELQF_MN
+                  MAXWRK = MAX( MAXWRK, 2*M + LWORK_CGEBRD_MM )
                   MINWRK = 3*M
                ELSE IF( WNTQO ) THEN
 *
-*                 Path 2t (N much larger than M, JOBZ='O')
-*
-                  WRKBL = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1, -1 )
-                  WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'CUNGLQ', ' ', M,
-     $                    N, M, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*M+2*M*
-     $                    ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*M+M*
-     $                    ILAENV( 1, 'CUNMBR', 'PRC', M, M, M, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*M+M*
-     $                    ILAENV( 1, 'CUNMBR', 'QLN', M, M, M, -1 ) )
+*                 Path 2t (N >> M, JOBZ='O')
+*
+                  WRKBL = M + LWORK_CGELQF_MN
+                  WRKBL = MAX( WRKBL,   M + LWORK_CUNGLQ_MN )
+                  WRKBL = MAX( WRKBL, 2*M + LWORK_CGEBRD_MM )
+                  WRKBL = MAX( WRKBL, 2*M + LWORK_CUNMBR_QLN_MM )
+                  WRKBL = MAX( WRKBL, 2*M + LWORK_CUNMBR_PRC_MM )
                   MAXWRK = M*N + M*M + WRKBL
                   MINWRK = 2*M*M + 3*M
                ELSE IF( WNTQS ) THEN
 *
-*                 Path 3t (N much larger than M, JOBZ='S')
-*
-                  WRKBL = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1, -1 )
-                  WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'CUNGLQ', ' ', M,
-     $                    N, M, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*M+2*M*
-     $                    ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*M+M*
-     $                    ILAENV( 1, 'CUNMBR', 'PRC', M, M, M, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*M+M*
-     $                    ILAENV( 1, 'CUNMBR', 'QLN', M, M, M, -1 ) )
+*                 Path 3t (N >> M, JOBZ='S')
+*
+                  WRKBL = M + LWORK_CGELQF_MN
+                  WRKBL = MAX( WRKBL,   M + LWORK_CUNGLQ_MN )
+                  WRKBL = MAX( WRKBL, 2*M + LWORK_CGEBRD_MM )
+                  WRKBL = MAX( WRKBL, 2*M + LWORK_CUNMBR_QLN_MM )
+                  WRKBL = MAX( WRKBL, 2*M + LWORK_CUNMBR_PRC_MM )
                   MAXWRK = M*M + WRKBL
                   MINWRK = M*M + 3*M
                ELSE IF( WNTQA ) THEN
 *
-*                 Path 4t (N much larger than M, JOBZ='A')
-*
-                  WRKBL = M + M*ILAENV( 1, 'CGELQF', ' ', M, N, -1, -1 )
-                  WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'CUNGLQ', ' ', N,
-     $                    N, M, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*M+2*M*
-     $                    ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*M+M*
-     $                    ILAENV( 1, 'CUNMBR', 'PRC', M, M, M, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*M+M*
-     $                    ILAENV( 1, 'CUNMBR', 'QLN', M, M, M, -1 ) )
+*                 Path 4t (N >> M, JOBZ='A')
+*
+                  WRKBL = M + LWORK_CGELQF_MN
+                  WRKBL = MAX( WRKBL,   M + LWORK_CUNGLQ_NN )
+                  WRKBL = MAX( WRKBL, 2*M + LWORK_CGEBRD_MM )
+                  WRKBL = MAX( WRKBL, 2*M + LWORK_CUNMBR_QLN_MM )
+                  WRKBL = MAX( WRKBL, 2*M + LWORK_CUNMBR_PRC_MM )
                   MAXWRK = M*M + WRKBL
-                  MINWRK = M*M + 2*M + N
+                  MINWRK = M*M + MAX( 3*M, M + N )
                END IF
             ELSE IF( N.GE.MNTHR2 ) THEN
 *
-*              Path 5t (N much larger than M, but not as much as MNTHR1)
+*              Path 5t (N >> M, but not as much as MNTHR1)
 *
-               MAXWRK = 2*M + ( M+N )*ILAENV( 1, 'CGEBRD', ' ', M, N,
-     $                  -1, -1 )
+               MAXWRK = 2*M + LWORK_CGEBRD_MN
                MINWRK = 2*M + N
                IF( WNTQO ) THEN
-                  MAXWRK = MAX( MAXWRK, 2*M+M*
-     $                     ILAENV( 1, 'CUNGBR', 'P', M, N, M, -1 ) )
-                  MAXWRK = MAX( MAXWRK, 2*M+M*
-     $                     ILAENV( 1, 'CUNGBR', 'Q', M, M, N, -1 ) )
+*                 Path 5to (N >> M, JOBZ='O')
+                  MAXWRK = MAX( MAXWRK, 2*M + LWORK_CUNGBR_Q_MM )
+                  MAXWRK = MAX( MAXWRK, 2*M + LWORK_CUNGBR_P_MN )
                   MAXWRK = MAXWRK + M*N
                   MINWRK = MINWRK + M*M
                ELSE IF( WNTQS ) THEN
-                  MAXWRK = MAX( MAXWRK, 2*M+M*
-     $                     ILAENV( 1, 'CUNGBR', 'P', M, N, M, -1 ) )
-                  MAXWRK = MAX( MAXWRK, 2*M+M*
-     $                     ILAENV( 1, 'CUNGBR', 'Q', M, M, N, -1 ) )
+*                 Path 5ts (N >> M, JOBZ='S')
+                  MAXWRK = MAX( MAXWRK, 2*M + LWORK_CUNGBR_Q_MM )
+                  MAXWRK = MAX( MAXWRK, 2*M + LWORK_CUNGBR_P_MN )
                ELSE IF( WNTQA ) THEN
-                  MAXWRK = MAX( MAXWRK, 2*M+N*
-     $                     ILAENV( 1, 'CUNGBR', 'P', N, N, M, -1 ) )
-                  MAXWRK = MAX( MAXWRK, 2*M+M*
-     $                     ILAENV( 1, 'CUNGBR', 'Q', M, M, N, -1 ) )
+*                 Path 5ta (N >> M, JOBZ='A')
+                  MAXWRK = MAX( MAXWRK, 2*M + LWORK_CUNGBR_Q_MM )
+                  MAXWRK = MAX( MAXWRK, 2*M + LWORK_CUNGBR_P_NN )
                END IF
             ELSE
 *
-*              Path 6t (N greater than M, but not much larger)
+*              Path 6t (N > M, but not much larger)
 *
-               MAXWRK = 2*M + ( M+N )*ILAENV( 1, 'CGEBRD', ' ', M, N,
-     $                  -1, -1 )
+               MAXWRK = 2*M + LWORK_CGEBRD_MN
                MINWRK = 2*M + N
                IF( WNTQO ) THEN
-                  MAXWRK = MAX( MAXWRK, 2*M+M*
-     $                     ILAENV( 1, 'CUNMBR', 'PRC', M, N, M, -1 ) )
-                  MAXWRK = MAX( MAXWRK, 2*M+M*
-     $                     ILAENV( 1, 'CUNMBR', 'QLN', M, M, N, -1 ) )
+*                 Path 6to (N > M, JOBZ='O')
+                  MAXWRK = MAX( MAXWRK, 2*M + LWORK_CUNMBR_QLN_MM )
+                  MAXWRK = MAX( MAXWRK, 2*M + LWORK_CUNMBR_PRC_MN )
                   MAXWRK = MAXWRK + M*N
                   MINWRK = MINWRK + M*M
                ELSE IF( WNTQS ) THEN
-                  MAXWRK = MAX( MAXWRK, 2*M+M*
-     $                     ILAENV( 1, 'CUNGBR', 'PRC', M, N, M, -1 ) )
-                  MAXWRK = MAX( MAXWRK, 2*M+M*
-     $                     ILAENV( 1, 'CUNGBR', 'QLN', M, M, N, -1 ) )
+*                 Path 6ts (N > M, JOBZ='S')
+                  MAXWRK = MAX( MAXWRK, 2*M + LWORK_CUNMBR_QLN_MM )
+                  MAXWRK = MAX( MAXWRK, 2*M + LWORK_CUNMBR_PRC_MN )
                ELSE IF( WNTQA ) THEN
-                  MAXWRK = MAX( MAXWRK, 2*M+N*
-     $                     ILAENV( 1, 'CUNGBR', 'PRC', N, N, M, -1 ) )
-                  MAXWRK = MAX( MAXWRK, 2*M+M*
-     $                     ILAENV( 1, 'CUNGBR', 'QLN', M, M, N, -1 ) )
+*                 Path 6ta (N > M, JOBZ='A')
+                  MAXWRK = MAX( MAXWRK, 2*M + LWORK_CUNMBR_QLN_MM )
+                  MAXWRK = MAX( MAXWRK, 2*M + LWORK_CUNMBR_PRC_NN )
                END IF
             END IF
          END IF
       END IF
       IF( INFO.EQ.0 ) THEN
          WORK( 1 ) = MAXWRK
-         IF( LWORK.LT.MINWRK .AND. LWORK.NE.LQUERV )
-     $      INFO = -13
+         IF( LWORK.LT.MINWRK .AND. .NOT. LQUERY ) THEN
+            INFO = -12
+         END IF
       END IF
-*
-*     Quick returns
 *
       IF( INFO.NE.0 ) THEN
          CALL XERBLA( 'CGESDD', -INFO )
          RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
       END IF
-      IF( LWORK.EQ.LQUERV )
-     $   RETURN
+*
+*     Quick return if possible
+*
       IF( M.EQ.0 .OR. N.EQ.0 ) THEN
          RETURN
       END IF
 *
             IF( WNTQN ) THEN
 *
-*              Path 1 (M much larger than N, JOBZ='N')
+*              Path 1 (M >> N, JOBZ='N')
 *              No singular vectors to be computed
 *
                ITAU = 1
                NWORK = ITAU + N
 *
 *              Compute A=Q*R
-*              (CWorkspace: need 2*N, prefer N+N*NB)
-*              (RWorkspace: need 0)
+*              CWorkspace: need   N [tau] + N    [work]
+*              CWorkspace: prefer N [tau] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL CGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
      $                      LWORK-NWORK+1, IERR )
                NWORK = ITAUP + N
 *
 *              Bidiagonalize R in A
-*              (CWorkspace: need 3*N, prefer 2*N+2*N*NB)
-*              (RWorkspace: need N)
+*              CWorkspace: need   2*N [tauq, taup] + N      [work]
+*              CWorkspace: prefer 2*N [tauq, taup] + 2*N*NB [work]
+*              RWorkspace: need   N [e]
 *
                CALL CGEBRD( N, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
      $                      WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
                NRWORK = IE + N
 *
 *              Perform bidiagonal SVD, compute singular values only
-*              (CWorkspace: 0)
-*              (RWorkspace: need BDSPAN)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + BDSPAC
 *
-               CALL SBDSDC( 'U', 'N', N, S, RWORK( IE ), DUM, 1, DUM, 1,
+               CALL SBDSDC( 'U', 'N', N, S, RWORK( IE ), DUM,1,DUM,1,
      $                      DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
 *
             ELSE IF( WNTQO ) THEN
 *
-*              Path 2 (M much larger than N, JOBZ='O')
+*              Path 2 (M >> N, JOBZ='O')
 *              N left singular vectors to be overwritten on A and
 *              N right singular vectors to be computed in VT
 *
 *
                LDWRKU = N
                IR = IU + LDWRKU*N
-               IF( LWORK.GE.M*N+N*N+3*N ) THEN
+               IF( LWORK .GE. M*N + N*N + 3*N ) THEN
 *
 *                 WORK(IR) is M by N
 *
                   LDWRKR = M
                ELSE
-                  LDWRKR = ( LWORK-N*N-3*N ) / N
+                  LDWRKR = ( LWORK - N*N - 3*N ) / N
                END IF
                ITAU = IR + LDWRKR*N
                NWORK = ITAU + N
 *
 *              Compute A=Q*R
-*              (CWorkspace: need N*N+2*N, prefer M*N+N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   N*N [U] + N*N [R] + N [tau] + N    [work]
+*              CWorkspace: prefer N*N [U] + N*N [R] + N [tau] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL CGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
      $                      LWORK-NWORK+1, IERR )
      $                      LDWRKR )
 *
 *              Generate Q in A
-*              (CWorkspace: need 2*N, prefer N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   N*N [U] + N*N [R] + N [tau] + N    [work]
+*              CWorkspace: prefer N*N [U] + N*N [R] + N [tau] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL CUNGQR( M, N, N, A, LDA, WORK( ITAU ),
      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                NWORK = ITAUP + N
 *
 *              Bidiagonalize R in WORK(IR)
-*              (CWorkspace: need N*N+3*N, prefer M*N+2*N+2*N*NB)
-*              (RWorkspace: need N)
+*              CWorkspace: need   N*N [U] + N*N [R] + 2*N [tauq, taup] + N      [work]
+*              CWorkspace: prefer N*N [U] + N*N [R] + 2*N [tauq, taup] + 2*N*NB [work]
+*              RWorkspace: need   N [e]
 *
                CALL CGEBRD( N, N, WORK( IR ), LDWRKR, S, RWORK( IE ),
      $                      WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of R in WORK(IRU) and computing right singular vectors
 *              of R in WORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT] + BDSPAC
 *
                IRU = IE + N
                IRVT = IRU + N*N
 *
 *              Copy real matrix RWORK(IRU) to complex matrix WORK(IU)
 *              Overwrite WORK(IU) by the left singular vectors of R
-*              (CWorkspace: need 2*N*N+3*N, prefer M*N+N*N+2*N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   N*N [U] + N*N [R] + 2*N [tauq, taup] + N    [work]
+*              CWorkspace: prefer N*N [U] + N*N [R] + 2*N [tauq, taup] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL CLACP2( 'F', N, N, RWORK( IRU ), N, WORK( IU ),
      $                      LDWRKU )
 *
 *              Copy real matrix RWORK(IRVT) to complex matrix VT
 *              Overwrite VT by the right singular vectors of R
-*              (CWorkspace: need N*N+3*N, prefer M*N+2*N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   N*N [U] + N*N [R] + 2*N [tauq, taup] + N    [work]
+*              CWorkspace: prefer N*N [U] + N*N [R] + 2*N [tauq, taup] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL CLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
                CALL CUNMBR( 'P', 'R', 'C', N, N, N, WORK( IR ), LDWRKR,
 *
 *              Multiply Q in A by left singular vectors of R in
 *              WORK(IU), storing result in WORK(IR) and copying to A
-*              (CWorkspace: need 2*N*N, prefer N*N+M*N)
-*              (RWorkspace: 0)
+*              CWorkspace: need   N*N [U] + N*N [R]
+*              CWorkspace: prefer N*N [U] + M*N [R]
+*              RWorkspace: need   0
 *
                DO 10 I = 1, M, LDWRKR
                   CHUNK = MIN( M-I+1, LDWRKR )
 *
             ELSE IF( WNTQS ) THEN
 *
-*              Path 3 (M much larger than N, JOBZ='S')
+*              Path 3 (M >> N, JOBZ='S')
 *              N left singular vectors to be computed in U and
 *              N right singular vectors to be computed in VT
 *
                NWORK = ITAU + N
 *
 *              Compute A=Q*R
-*              (CWorkspace: need N*N+2*N, prefer N*N+N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   N*N [R] + N [tau] + N    [work]
+*              CWorkspace: prefer N*N [R] + N [tau] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL CGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
      $                      LWORK-NWORK+1, IERR )
      $                      LDWRKR )
 *
 *              Generate Q in A
-*              (CWorkspace: need 2*N, prefer N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   N*N [R] + N [tau] + N    [work]
+*              CWorkspace: prefer N*N [R] + N [tau] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL CUNGQR( M, N, N, A, LDA, WORK( ITAU ),
      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                NWORK = ITAUP + N
 *
 *              Bidiagonalize R in WORK(IR)
-*              (CWorkspace: need N*N+3*N, prefer N*N+2*N+2*N*NB)
-*              (RWorkspace: need N)
+*              CWorkspace: need   N*N [R] + 2*N [tauq, taup] + N      [work]
+*              CWorkspace: prefer N*N [R] + 2*N [tauq, taup] + 2*N*NB [work]
+*              RWorkspace: need   N [e]
 *
                CALL CGEBRD( N, N, WORK( IR ), LDWRKR, S, RWORK( IE ),
      $                      WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT] + BDSPAC
 *
                IRU = IE + N
                IRVT = IRU + N*N
 *
 *              Copy real matrix RWORK(IRU) to complex matrix U
 *              Overwrite U by left singular vectors of R
-*              (CWorkspace: need N*N+3*N, prefer N*N+2*N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   N*N [R] + 2*N [tauq, taup] + N    [work]
+*              CWorkspace: prefer N*N [R] + 2*N [tauq, taup] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL CLACP2( 'F', N, N, RWORK( IRU ), N, U, LDU )
                CALL CUNMBR( 'Q', 'L', 'N', N, N, N, WORK( IR ), LDWRKR,
 *
 *              Copy real matrix RWORK(IRVT) to complex matrix VT
 *              Overwrite VT by right singular vectors of R
-*              (CWorkspace: need N*N+3*N, prefer N*N+2*N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   N*N [R] + 2*N [tauq, taup] + N    [work]
+*              CWorkspace: prefer N*N [R] + 2*N [tauq, taup] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL CLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
                CALL CUNMBR( 'P', 'R', 'C', N, N, N, WORK( IR ), LDWRKR,
 *
 *              Multiply Q in A by left singular vectors of R in
 *              WORK(IR), storing result in U
-*              (CWorkspace: need N*N)
-*              (RWorkspace: 0)
+*              CWorkspace: need   N*N [R]
+*              RWorkspace: need   0
 *
                CALL CLACPY( 'F', N, N, U, LDU, WORK( IR ), LDWRKR )
                CALL CGEMM( 'N', 'N', M, N, N, CONE, A, LDA, WORK( IR ),
 *
             ELSE IF( WNTQA ) THEN
 *
-*              Path 4 (M much larger than N, JOBZ='A')
+*              Path 4 (M >> N, JOBZ='A')
 *              M left singular vectors to be computed in U and
 *              N right singular vectors to be computed in VT
 *
                NWORK = ITAU + N
 *
 *              Compute A=Q*R, copying result to U
-*              (CWorkspace: need 2*N, prefer N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   N*N [U] + N [tau] + N    [work]
+*              CWorkspace: prefer N*N [U] + N [tau] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL CGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
      $                      LWORK-NWORK+1, IERR )
                CALL CLACPY( 'L', M, N, A, LDA, U, LDU )
 *
 *              Generate Q in U
-*              (CWorkspace: need N+M, prefer N+M*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   N*N [U] + N [tau] + M    [work]
+*              CWorkspace: prefer N*N [U] + N [tau] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL CUNGQR( M, M, N, U, LDU, WORK( ITAU ),
      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                NWORK = ITAUP + N
 *
 *              Bidiagonalize R in A
-*              (CWorkspace: need 3*N, prefer 2*N+2*N*NB)
-*              (RWorkspace: need N)
+*              CWorkspace: need   N*N [U] + 2*N [tauq, taup] + N      [work]
+*              CWorkspace: prefer N*N [U] + 2*N [tauq, taup] + 2*N*NB [work]
+*              RWorkspace: need   N [e]
 *
                CALL CGEBRD( N, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
      $                      WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT] + BDSPAC
 *
                CALL SBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
      $                      N, RWORK( IRVT ), N, DUM, IDUM,
 *
 *              Copy real matrix RWORK(IRU) to complex matrix WORK(IU)
 *              Overwrite WORK(IU) by left singular vectors of R
-*              (CWorkspace: need N*N+3*N, prefer N*N+2*N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   N*N [U] + 2*N [tauq, taup] + N    [work]
+*              CWorkspace: prefer N*N [U] + 2*N [tauq, taup] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL CLACP2( 'F', N, N, RWORK( IRU ), N, WORK( IU ),
      $                      LDWRKU )
 *
 *              Copy real matrix RWORK(IRVT) to complex matrix VT
 *              Overwrite VT by right singular vectors of R
-*              (CWorkspace: need 3*N, prefer 2*N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   N*N [U] + 2*N [tauq, taup] + N    [work]
+*              CWorkspace: prefer N*N [U] + 2*N [tauq, taup] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL CLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
                CALL CUNMBR( 'P', 'R', 'C', N, N, N, A, LDA,
 *
 *              Multiply Q in U by left singular vectors of R in
 *              WORK(IU), storing result in A
-*              (CWorkspace: need N*N)
-*              (RWorkspace: 0)
+*              CWorkspace: need   N*N [U]
+*              RWorkspace: need   0
 *
                CALL CGEMM( 'N', 'N', M, N, N, CONE, U, LDU, WORK( IU ),
      $                     LDWRKU, CZERO, A, LDA )
 *
 *           MNTHR2 <= M < MNTHR1
 *
-*           Path 5 (M much larger than N, but not as much as MNTHR1)
+*           Path 5 (M >> N, but not as much as MNTHR1)
 *           Reduce to bidiagonal form without QR decomposition, use
 *           CUNGBR and matrix multiplication to compute singular vectors
 *
             NWORK = ITAUP + N
 *
 *           Bidiagonalize A
-*           (CWorkspace: need 2*N+M, prefer 2*N+(M+N)*NB)
-*           (RWorkspace: need N)
+*           CWorkspace: need   2*N [tauq, taup] + M        [work]
+*           CWorkspace: prefer 2*N [tauq, taup] + (M+N)*NB [work]
+*           RWorkspace: need   N [e]
 *
             CALL CGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
      $                   WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
      $                   IERR )
             IF( WNTQN ) THEN
 *
+*              Path 5n (M >> N, JOBZ='N')
 *              Compute singular values only
-*              (Cworkspace: 0)
-*              (Rworkspace: need BDSPAN)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + BDSPAC
 *
-               CALL SBDSDC( 'U', 'N', N, S, RWORK( IE ), DUM, 1, DUM, 1,
+               CALL SBDSDC( 'U', 'N', N, S, RWORK( IE ), DUM, 1,DUM,1,
      $                      DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
             ELSE IF( WNTQO ) THEN
                IU = NWORK
                IRVT = IRU + N*N
                NRWORK = IRVT + N*N
 *
+*              Path 5o (M >> N, JOBZ='O')
 *              Copy A to VT, generate P**H
-*              (Cworkspace: need 2*N, prefer N+N*NB)
-*              (Rworkspace: 0)
+*              CWorkspace: need   2*N [tauq, taup] + N    [work]
+*              CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL CLACPY( 'U', N, N, A, LDA, VT, LDVT )
                CALL CUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
 *
 *              Generate Q in A
-*              (CWorkspace: need 2*N, prefer N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   2*N [tauq, taup] + N    [work]
+*              CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL CUNGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
 *
-               IF( LWORK.GE.M*N+3*N ) THEN
+               IF( LWORK .GE. M*N + 3*N ) THEN
 *
 *                 WORK( IU ) is M by N
 *
 *
 *                 WORK(IU) is LDWRKU by N
 *
-                  LDWRKU = ( LWORK-3*N ) / N
+                  LDWRKU = ( LWORK - 3*N ) / N
                END IF
                NWORK = IU + LDWRKU*N
 *
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT] + BDSPAC
 *
                CALL SBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
      $                      N, RWORK( IRVT ), N, DUM, IDUM,
 *
 *              Multiply real matrix RWORK(IRVT) by P**H in VT,
 *              storing the result in WORK(IU), copying to VT
-*              (Cworkspace: need 0)
-*              (Rworkspace: need 3*N*N)
+*              CWorkspace: need   2*N [tauq, taup] + N*N [U]
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT] + 2*N*N [rwork]
 *
                CALL CLARCM( N, N, RWORK( IRVT ), N, VT, LDVT,
      $                      WORK( IU ), LDWRKU, RWORK( NRWORK ) )
 *
 *              Multiply Q in A by real matrix RWORK(IRU), storing the
 *              result in WORK(IU), copying to A
-*              (CWorkspace: need N*N, prefer M*N)
-*              (Rworkspace: need 3*N*N, prefer N*N+2*M*N)
+*              CWorkspace: need   2*N [tauq, taup] + N*N [U]
+*              CWorkspace: prefer 2*N [tauq, taup] + M*N [U]
+*              RWorkspace: need   N [e] + N*N [RU] + 2*N*N [rwork]
+*              RWorkspace: prefer N [e] + N*N [RU] + 2*M*N [rwork] < N + 5*N*N since M < 2*N here
 *
                NRWORK = IRVT
                DO 20 I = 1, M, LDWRKU
 *
             ELSE IF( WNTQS ) THEN
 *
+*              Path 5s (M >> N, JOBZ='S')
 *              Copy A to VT, generate P**H
-*              (Cworkspace: need 2*N, prefer N+N*NB)
-*              (Rworkspace: 0)
+*              CWorkspace: need   2*N [tauq, taup] + N    [work]
+*              CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL CLACPY( 'U', N, N, A, LDA, VT, LDVT )
                CALL CUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
 *
 *              Copy A to U, generate Q
-*              (Cworkspace: need 2*N, prefer N+N*NB)
-*              (Rworkspace: 0)
+*              CWorkspace: need   2*N [tauq, taup] + N    [work]
+*              CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL CLACPY( 'L', M, N, A, LDA, U, LDU )
                CALL CUNGBR( 'Q', M, N, N, U, LDU, WORK( ITAUQ ),
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT] + BDSPAC
 *
                IRU = NRWORK
                IRVT = IRU + N*N
 *
 *              Multiply real matrix RWORK(IRVT) by P**H in VT,
 *              storing the result in A, copying to VT
-*              (Cworkspace: need 0)
-*              (Rworkspace: need 3*N*N)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT] + 2*N*N [rwork]
 *
                CALL CLARCM( N, N, RWORK( IRVT ), N, VT, LDVT, A, LDA,
      $                      RWORK( NRWORK ) )
 *
 *              Multiply Q in U by real matrix RWORK(IRU), storing the
 *              result in A, copying to U
-*              (CWorkspace: need 0)
-*              (Rworkspace: need N*N+2*M*N)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + N*N [RU] + 2*M*N [rwork] < N + 5*N*N since M < 2*N here
 *
                NRWORK = IRVT
                CALL CLACRM( M, N, U, LDU, RWORK( IRU ), N, A, LDA,
                CALL CLACPY( 'F', M, N, A, LDA, U, LDU )
             ELSE
 *
+*              Path 5a (M >> N, JOBZ='A')
 *              Copy A to VT, generate P**H
-*              (Cworkspace: need 2*N, prefer N+N*NB)
-*              (Rworkspace: 0)
+*              CWorkspace: need   2*N [tauq, taup] + N    [work]
+*              CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL CLACPY( 'U', N, N, A, LDA, VT, LDVT )
                CALL CUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
 *
 *              Copy A to U, generate Q
-*              (Cworkspace: need 2*N, prefer N+N*NB)
-*              (Rworkspace: 0)
+*              CWorkspace: need   2*N [tauq, taup] + M    [work]
+*              CWorkspace: prefer 2*N [tauq, taup] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL CLACPY( 'L', M, N, A, LDA, U, LDU )
                CALL CUNGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT] + BDSPAC
 *
                IRU = NRWORK
                IRVT = IRU + N*N
 *
 *              Multiply real matrix RWORK(IRVT) by P**H in VT,
 *              storing the result in A, copying to VT
-*              (Cworkspace: need 0)
-*              (Rworkspace: need 3*N*N)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT] + 2*N*N [rwork]
 *
                CALL CLARCM( N, N, RWORK( IRVT ), N, VT, LDVT, A, LDA,
      $                      RWORK( NRWORK ) )
 *
 *              Multiply Q in U by real matrix RWORK(IRU), storing the
 *              result in A, copying to U
-*              (CWorkspace: 0)
-*              (Rworkspace: need 3*N*N)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + N*N [RU] + 2*M*N [rwork] < N + 5*N*N since M < 2*N here
 *
                NRWORK = IRVT
                CALL CLACRM( M, N, U, LDU, RWORK( IRU ), N, A, LDA,
 *
 *           M .LT. MNTHR2
 *
-*           Path 6 (M at least N, but not much larger)
+*           Path 6 (M >= N, but not much larger)
 *           Reduce to bidiagonal form without QR decomposition
 *           Use CUNMBR to compute singular vectors
 *
             NWORK = ITAUP + N
 *
 *           Bidiagonalize A
-*           (CWorkspace: need 2*N+M, prefer 2*N+(M+N)*NB)
-*           (RWorkspace: need N)
+*           CWorkspace: need   2*N [tauq, taup] + M        [work]
+*           CWorkspace: prefer 2*N [tauq, taup] + (M+N)*NB [work]
+*           RWorkspace: need   N [e]
 *
             CALL CGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
      $                   WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
      $                   IERR )
             IF( WNTQN ) THEN
 *
+*              Path 6n (M >= N, JOBZ='N')
 *              Compute singular values only
-*              (Cworkspace: 0)
-*              (Rworkspace: need BDSPAN)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + BDSPAC
 *
-               CALL SBDSDC( 'U', 'N', N, S, RWORK( IE ), DUM, 1, DUM, 1,
+               CALL SBDSDC( 'U', 'N', N, S, RWORK( IE ), DUM,1,DUM,1,
      $                      DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
             ELSE IF( WNTQO ) THEN
                IU = NWORK
                IRU = NRWORK
                IRVT = IRU + N*N
                NRWORK = IRVT + N*N
-               IF( LWORK.GE.M*N+3*N ) THEN
+               IF( LWORK .GE. M*N + 3*N ) THEN
 *
 *                 WORK( IU ) is M by N
 *
 *
 *                 WORK( IU ) is LDWRKU by N
 *
-                  LDWRKU = ( LWORK-3*N ) / N
+                  LDWRKU = ( LWORK - 3*N ) / N
                END IF
                NWORK = IU + LDWRKU*N
 *
+*              Path 6o (M >= N, JOBZ='O')
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT] + BDSPAC
 *
                CALL SBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
      $                      N, RWORK( IRVT ), N, DUM, IDUM,
 *
 *              Copy real matrix RWORK(IRVT) to complex matrix VT
 *              Overwrite VT by right singular vectors of A
-*              (Cworkspace: need 2*N, prefer N+N*NB)
-*              (Rworkspace: need 0)
+*              CWorkspace: need   2*N [tauq, taup] + N*N [U] + N    [work]
+*              CWorkspace: prefer 2*N [tauq, taup] + N*N [U] + N*NB [work]
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT]
 *
                CALL CLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
                CALL CUNMBR( 'P', 'R', 'C', N, N, N, A, LDA,
      $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
      $                      LWORK-NWORK+1, IERR )
 *
-               IF( LWORK.GE.M*N+3*N ) THEN
+               IF( LWORK .GE. M*N + 3*N ) THEN
 *
-*              Copy real matrix RWORK(IRU) to complex matrix WORK(IU)
-*              Overwrite WORK(IU) by left singular vectors of A, copying
-*              to A
-*              (Cworkspace: need M*N+2*N, prefer M*N+N+N*NB)
-*              (Rworkspace: need 0)
+*                 Path 6o-fast
+*                 Copy real matrix RWORK(IRU) to complex matrix WORK(IU)
+*                 Overwrite WORK(IU) by left singular vectors of A, copying
+*                 to A
+*                 CWorkspace: need   2*N [tauq, taup] + M*N [U] + N    [work]
+*                 CWorkspace: prefer 2*N [tauq, taup] + M*N [U] + N*NB [work]
+*                 RWorkspace: need   N [e] + N*N [RU]
 *
                   CALL CLASET( 'F', M, N, CZERO, CZERO, WORK( IU ),
      $                         LDWRKU )
                   CALL CLACPY( 'F', M, N, WORK( IU ), LDWRKU, A, LDA )
                ELSE
 *
+*                 Path 6o-slow
 *                 Generate Q in A
-*                 (Cworkspace: need 2*N, prefer N+N*NB)
-*                 (Rworkspace: need 0)
+*                 CWorkspace: need   2*N [tauq, taup] + N*N [U] + N    [work]
+*                 CWorkspace: prefer 2*N [tauq, taup] + N*N [U] + N*NB [work]
+*                 RWorkspace: need   0
 *
                   CALL CUNGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
      $                         WORK( NWORK ), LWORK-NWORK+1, IERR )
 *
 *                 Multiply Q in A by real matrix RWORK(IRU), storing the
 *                 result in WORK(IU), copying to A
-*                 (CWorkspace: need N*N, prefer M*N)
-*                 (Rworkspace: need 3*N*N, prefer N*N+2*M*N)
+*                 CWorkspace: need   2*N [tauq, taup] + N*N [U]
+*                 CWorkspace: prefer 2*N [tauq, taup] + M*N [U]
+*                 RWorkspace: need   N [e] + N*N [RU] + 2*N*N [rwork]
+*                 RWorkspace: prefer N [e] + N*N [RU] + 2*M*N [rwork] < N + 5*N*N since M < 2*N here
 *
                   NRWORK = IRVT
                   DO 30 I = 1, M, LDWRKU
 *
             ELSE IF( WNTQS ) THEN
 *
+*              Path 6s (M >= N, JOBZ='S')
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT] + BDSPAC
 *
                IRU = NRWORK
                IRVT = IRU + N*N
 *
 *              Copy real matrix RWORK(IRU) to complex matrix U
 *              Overwrite U by left singular vectors of A
-*              (CWorkspace: need 3*N, prefer 2*N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   2*N [tauq, taup] + N    [work]
+*              CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT]
 *
                CALL CLASET( 'F', M, N, CZERO, CZERO, U, LDU )
                CALL CLACP2( 'F', N, N, RWORK( IRU ), N, U, LDU )
 *
 *              Copy real matrix RWORK(IRVT) to complex matrix VT
 *              Overwrite VT by right singular vectors of A
-*              (CWorkspace: need 3*N, prefer 2*N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   2*N [tauq, taup] + N    [work]
+*              CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT]
 *
                CALL CLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
                CALL CUNMBR( 'P', 'R', 'C', N, N, N, A, LDA,
      $                      LWORK-NWORK+1, IERR )
             ELSE
 *
+*              Path 6a (M >= N, JOBZ='A')
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT] + BDSPAC
 *
                IRU = NRWORK
                IRVT = IRU + N*N
 *
 *              Copy real matrix RWORK(IRU) to complex matrix U
 *              Overwrite U by left singular vectors of A
-*              (CWorkspace: need 2*N+M, prefer 2*N+M*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   2*N [tauq, taup] + M    [work]
+*              CWorkspace: prefer 2*N [tauq, taup] + M*NB [work]
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT]
 *
                CALL CLACP2( 'F', N, N, RWORK( IRU ), N, U, LDU )
                CALL CUNMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
 *
 *              Copy real matrix RWORK(IRVT) to complex matrix VT
 *              Overwrite VT by right singular vectors of A
-*              (CWorkspace: need 3*N, prefer 2*N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   2*N [tauq, taup] + N    [work]
+*              CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT]
 *
                CALL CLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
                CALL CUNMBR( 'P', 'R', 'C', N, N, N, A, LDA,
 *
             IF( WNTQN ) THEN
 *
-*              Path 1t (N much larger than M, JOBZ='N')
+*              Path 1t (N >> M, JOBZ='N')
 *              No singular vectors to be computed
 *
                ITAU = 1
                NWORK = ITAU + M
 *
 *              Compute A=L*Q
-*              (CWorkspace: need 2*M, prefer M+M*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   M [tau] + M    [work]
+*              CWorkspace: prefer M [tau] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL CGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
      $                      LWORK-NWORK+1, IERR )
                NWORK = ITAUP + M
 *
 *              Bidiagonalize L in A
-*              (CWorkspace: need 3*M, prefer 2*M+2*M*NB)
-*              (RWorkspace: need M)
+*              CWorkspace: need   2*M [tauq, taup] + M      [work]
+*              CWorkspace: prefer 2*M [tauq, taup] + 2*M*NB [work]
+*              RWorkspace: need   M [e]
 *
                CALL CGEBRD( M, M, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
      $                      WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
                NRWORK = IE + M
 *
 *              Perform bidiagonal SVD, compute singular values only
-*              (CWorkspace: 0)
-*              (RWorkspace: need BDSPAN)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + BDSPAC
 *
-               CALL SBDSDC( 'U', 'N', M, S, RWORK( IE ), DUM, 1, DUM, 1,
+               CALL SBDSDC( 'U', 'N', M, S, RWORK( IE ), DUM,1,DUM,1,
      $                      DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
 *
             ELSE IF( WNTQO ) THEN
 *
-*              Path 2t (N much larger than M, JOBZ='O')
+*              Path 2t (N >> M, JOBZ='O')
 *              M right singular vectors to be overwritten on A and
 *              M left singular vectors to be computed in U
 *
 *              WORK(IVT) is M by M
 *
                IL = IVT + LDWKVT*M
-               IF( LWORK.GE.M*N+M*M+3*M ) THEN
+               IF( LWORK .GE. M*N + M*M + 3*M ) THEN
 *
 *                 WORK(IL) M by N
 *
 *                 WORK(IL) is M by CHUNK
 *
                   LDWRKL = M
-                  CHUNK = ( LWORK-M*M-3*M ) / M
+                  CHUNK = ( LWORK - M*M - 3*M ) / M
                END IF
                ITAU = IL + LDWRKL*CHUNK
                NWORK = ITAU + M
 *
 *              Compute A=L*Q
-*              (CWorkspace: need 2*M, prefer M+M*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   M*M [VT] + M*M [L] + M [tau] + M    [work]
+*              CWorkspace: prefer M*M [VT] + M*M [L] + M [tau] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL CGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
      $                      LWORK-NWORK+1, IERR )
      $                      WORK( IL+LDWRKL ), LDWRKL )
 *
 *              Generate Q in A
-*              (CWorkspace: need M*M+2*M, prefer M*M+M+M*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   M*M [VT] + M*M [L] + M [tau] + M    [work]
+*              CWorkspace: prefer M*M [VT] + M*M [L] + M [tau] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL CUNGLQ( M, N, M, A, LDA, WORK( ITAU ),
      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                NWORK = ITAUP + M
 *
 *              Bidiagonalize L in WORK(IL)
-*              (CWorkspace: need M*M+3*M, prefer M*M+2*M+2*M*NB)
-*              (RWorkspace: need M)
+*              CWorkspace: need   M*M [VT] + M*M [L] + 2*M [tauq, taup] + M      [work]
+*              CWorkspace: prefer M*M [VT] + M*M [L] + 2*M [tauq, taup] + 2*M*NB [work]
+*              RWorkspace: need   M [e]
 *
                CALL CGEBRD( M, M, WORK( IL ), LDWRKL, S, RWORK( IE ),
      $                      WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + M*M [RU] + M*M [RVT] + BDSPAC
 *
                IRU = IE + M
                IRVT = IRU + M*M
 *
 *              Copy real matrix RWORK(IRU) to complex matrix WORK(IU)
 *              Overwrite WORK(IU) by the left singular vectors of L
-*              (CWorkspace: need N*N+3*N, prefer M*N+2*N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   M*M [VT] + M*M [L] + 2*M [tauq, taup] + M    [work]
+*              CWorkspace: prefer M*M [VT] + M*M [L] + 2*M [tauq, taup] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL CLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
                CALL CUNMBR( 'Q', 'L', 'N', M, M, M, WORK( IL ), LDWRKL,
 *
 *              Copy real matrix RWORK(IRVT) to complex matrix WORK(IVT)
 *              Overwrite WORK(IVT) by the right singular vectors of L
-*              (CWorkspace: need N*N+3*N, prefer M*N+2*N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   M*M [VT] + M*M [L] + 2*M [tauq, taup] + M    [work]
+*              CWorkspace: prefer M*M [VT] + M*M [L] + 2*M [tauq, taup] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL CLACP2( 'F', M, M, RWORK( IRVT ), M, WORK( IVT ),
      $                      LDWKVT )
 *
 *              Multiply right singular vectors of L in WORK(IL) by Q
 *              in A, storing result in WORK(IL) and copying to A
-*              (CWorkspace: need 2*M*M, prefer M*M+M*N))
-*              (RWorkspace: 0)
+*              CWorkspace: need   M*M [VT] + M*M [L]
+*              CWorkspace: prefer M*M [VT] + M*N [L]
+*              RWorkspace: need   0
 *
                DO 40 I = 1, N, CHUNK
                   BLK = MIN( N-I+1, CHUNK )
 *
             ELSE IF( WNTQS ) THEN
 *
-*             Path 3t (N much larger than M, JOBZ='S')
-*             M right singular vectors to be computed in VT and
-*             M left singular vectors to be computed in U
+*              Path 3t (N >> M, JOBZ='S')
+*              M right singular vectors to be computed in VT and
+*              M left singular vectors to be computed in U
 *
                IL = 1
 *
                NWORK = ITAU + M
 *
 *              Compute A=L*Q
-*              (CWorkspace: need 2*M, prefer M+M*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   M*M [L] + M [tau] + M    [work]
+*              CWorkspace: prefer M*M [L] + M [tau] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL CGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
      $                      LWORK-NWORK+1, IERR )
      $                      WORK( IL+LDWRKL ), LDWRKL )
 *
 *              Generate Q in A
-*              (CWorkspace: need M*M+2*M, prefer M*M+M+M*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   M*M [L] + M [tau] + M    [work]
+*              CWorkspace: prefer M*M [L] + M [tau] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL CUNGLQ( M, N, M, A, LDA, WORK( ITAU ),
      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                NWORK = ITAUP + M
 *
 *              Bidiagonalize L in WORK(IL)
-*              (CWorkspace: need M*M+3*M, prefer M*M+2*M+2*M*NB)
-*              (RWorkspace: need M)
+*              CWorkspace: need   M*M [L] + 2*M [tauq, taup] + M      [work]
+*              CWorkspace: prefer M*M [L] + 2*M [tauq, taup] + 2*M*NB [work]
+*              RWorkspace: need   M [e]
 *
                CALL CGEBRD( M, M, WORK( IL ), LDWRKL, S, RWORK( IE ),
      $                      WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + M*M [RU] + M*M [RVT] + BDSPAC
 *
                IRU = IE + M
                IRVT = IRU + M*M
 *
 *              Copy real matrix RWORK(IRU) to complex matrix U
 *              Overwrite U by left singular vectors of L
-*              (CWorkspace: need M*M+3*M, prefer M*M+2*M+M*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   M*M [L] + 2*M [tauq, taup] + M    [work]
+*              CWorkspace: prefer M*M [L] + 2*M [tauq, taup] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL CLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
                CALL CUNMBR( 'Q', 'L', 'N', M, M, M, WORK( IL ), LDWRKL,
 *
 *              Copy real matrix RWORK(IRVT) to complex matrix VT
 *              Overwrite VT by left singular vectors of L
-*              (CWorkspace: need M*M+3*M, prefer M*M+2*M+M*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   M*M [L] + 2*M [tauq, taup] + M    [work]
+*              CWorkspace: prefer M*M [L] + 2*M [tauq, taup] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL CLACP2( 'F', M, M, RWORK( IRVT ), M, VT, LDVT )
                CALL CUNMBR( 'P', 'R', 'C', M, M, M, WORK( IL ), LDWRKL,
 *
 *              Copy VT to WORK(IL), multiply right singular vectors of L
 *              in WORK(IL) by Q in A, storing result in VT
-*              (CWorkspace: need M*M)
-*              (RWorkspace: 0)
+*              CWorkspace: need   M*M [L]
+*              RWorkspace: need   0
 *
                CALL CLACPY( 'F', M, M, VT, LDVT, WORK( IL ), LDWRKL )
                CALL CGEMM( 'N', 'N', M, N, M, CONE, WORK( IL ), LDWRKL,
 *
             ELSE IF( WNTQA ) THEN
 *
-*              Path 9t (N much larger than M, JOBZ='A')
+*              Path 4t (N >> M, JOBZ='A')
 *              N right singular vectors to be computed in VT and
 *              M left singular vectors to be computed in U
 *
                NWORK = ITAU + M
 *
 *              Compute A=L*Q, copying result to VT
-*              (CWorkspace: need 2*M, prefer M+M*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   M*M [VT] + M [tau] + M    [work]
+*              CWorkspace: prefer M*M [VT] + M [tau] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL CGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
      $                      LWORK-NWORK+1, IERR )
                CALL CLACPY( 'U', M, N, A, LDA, VT, LDVT )
 *
 *              Generate Q in VT
-*              (CWorkspace: need M+N, prefer M+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   M*M [VT] + M [tau] + N    [work]
+*              CWorkspace: prefer M*M [VT] + M [tau] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL CUNGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                NWORK = ITAUP + M
 *
 *              Bidiagonalize L in A
-*              (CWorkspace: need M*M+3*M, prefer M*M+2*M+2*M*NB)
-*              (RWorkspace: need M)
+*              CWorkspace: need   M*M [VT] + 2*M [tauq, taup] + M      [work]
+*              CWorkspace: prefer M*M [VT] + 2*M [tauq, taup] + 2*M*NB [work]
+*              RWorkspace: need   M [e]
 *
                CALL CGEBRD( M, M, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
      $                      WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + M*M [RU] + M*M [RVT] + BDSPAC
 *
                IRU = IE + M
                IRVT = IRU + M*M
 *
 *              Copy real matrix RWORK(IRU) to complex matrix U
 *              Overwrite U by left singular vectors of L
-*              (CWorkspace: need 3*M, prefer 2*M+M*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   M*M [VT] + 2*M [tauq, taup] + M    [work]
+*              CWorkspace: prefer M*M [VT] + 2*M [tauq, taup] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL CLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
                CALL CUNMBR( 'Q', 'L', 'N', M, M, M, A, LDA,
 *
 *              Copy real matrix RWORK(IRVT) to complex matrix WORK(IVT)
 *              Overwrite WORK(IVT) by right singular vectors of L
-*              (CWorkspace: need M*M+3*M, prefer M*M+2*M+M*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   M*M [VT] + 2*M [tauq, taup] + M    [work]
+*              CWorkspace: prefer M*M [VT] + 2*M [tauq, taup] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL CLACP2( 'F', M, M, RWORK( IRVT ), M, WORK( IVT ),
      $                      LDWKVT )
 *
 *              Multiply right singular vectors of L in WORK(IVT) by
 *              Q in VT, storing result in A
-*              (CWorkspace: need M*M)
-*              (RWorkspace: 0)
+*              CWorkspace: need   M*M [VT]
+*              RWorkspace: need   0
 *
-               CALL CGEMM( 'N', 'N', M, N, M, CONE, WORK( IVT ),
-     $                     LDWKVT, VT, LDVT, CZERO, A, LDA )
+               CALL CGEMM( 'N', 'N', M, N, M, CONE, WORK( IVT ), LDWKVT,
+     $                     VT, LDVT, CZERO, A, LDA )
 *
 *              Copy right singular vectors of A from A to VT
 *
 *
 *           MNTHR2 <= N < MNTHR1
 *
-*           Path 5t (N much larger than M, but not as much as MNTHR1)
+*           Path 5t (N >> M, but not as much as MNTHR1)
 *           Reduce to bidiagonal form without QR decomposition, use
 *           CUNGBR and matrix multiplication to compute singular vectors
-*
 *
             IE = 1
             NRWORK = IE + M
             NWORK = ITAUP + M
 *
 *           Bidiagonalize A
-*           (CWorkspace: need 2*M+N, prefer 2*M+(M+N)*NB)
-*           (RWorkspace: M)
+*           CWorkspace: need   2*M [tauq, taup] + N        [work]
+*           CWorkspace: prefer 2*M [tauq, taup] + (M+N)*NB [work]
+*           RWorkspace: need   M [e]
 *
             CALL CGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
      $                   WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
 *
             IF( WNTQN ) THEN
 *
+*              Path 5tn (N >> M, JOBZ='N')
 *              Compute singular values only
-*              (Cworkspace: 0)
-*              (Rworkspace: need BDSPAN)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + BDSPAC
 *
-               CALL SBDSDC( 'L', 'N', M, S, RWORK( IE ), DUM, 1, DUM, 1,
+               CALL SBDSDC( 'L', 'N', M, S, RWORK( IE ), DUM,1,DUM,1,
      $                      DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
             ELSE IF( WNTQO ) THEN
                IRVT = NRWORK
                NRWORK = IRU + M*M
                IVT = NWORK
 *
+*              Path 5to (N >> M, JOBZ='O')
 *              Copy A to U, generate Q
-*              (Cworkspace: need 2*M, prefer M+M*NB)
-*              (Rworkspace: 0)
+*              CWorkspace: need   2*M [tauq, taup] + M    [work]
+*              CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL CLACPY( 'L', M, M, A, LDA, U, LDU )
                CALL CUNGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
 *
 *              Generate P**H in A
-*              (Cworkspace: need 2*M, prefer M+M*NB)
-*              (Rworkspace: 0)
+*              CWorkspace: need   2*M [tauq, taup] + M    [work]
+*              CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL CUNGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
 *
                LDWKVT = M
-               IF( LWORK.GE.M*N+3*M ) THEN
+               IF( LWORK .GE. M*N + 3*M ) THEN
 *
 *                 WORK( IVT ) is M by N
 *
 *
 *                 WORK( IVT ) is M by CHUNK
 *
-                  CHUNK = ( LWORK-3*M ) / M
+                  CHUNK = ( LWORK - 3*M ) / M
                   NWORK = IVT + LDWKVT*CHUNK
                END IF
 *
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + M*M [RVT] + M*M [RU] + BDSPAC
 *
                CALL SBDSDC( 'L', 'I', M, S, RWORK( IE ), RWORK( IRU ),
      $                      M, RWORK( IRVT ), M, DUM, IDUM,
 *
 *              Multiply Q in U by real matrix RWORK(IRVT)
 *              storing the result in WORK(IVT), copying to U
-*              (Cworkspace: need 0)
-*              (Rworkspace: need 2*M*M)
+*              CWorkspace: need   2*M [tauq, taup] + M*M [VT]
+*              RWorkspace: need   M [e] + M*M [RVT] + M*M [RU] + 2*M*M [rwork]
 *
                CALL CLACRM( M, M, U, LDU, RWORK( IRU ), M, WORK( IVT ),
      $                      LDWKVT, RWORK( NRWORK ) )
 *
 *              Multiply RWORK(IRVT) by P**H in A, storing the
 *              result in WORK(IVT), copying to A
-*              (CWorkspace: need M*M, prefer M*N)
-*              (Rworkspace: need 2*M*M, prefer 2*M*N)
+*              CWorkspace: need   2*M [tauq, taup] + M*M [VT]
+*              CWorkspace: prefer 2*M [tauq, taup] + M*N [VT]
+*              RWorkspace: need   M [e] + M*M [RVT] + 2*M*M [rwork]
+*              RWorkspace: prefer M [e] + M*M [RVT] + 2*M*N [rwork] < M + 5*M*M since N < 2*M here
 *
                NRWORK = IRU
                DO 50 I = 1, N, CHUNK
    50          CONTINUE
             ELSE IF( WNTQS ) THEN
 *
+*              Path 5ts (N >> M, JOBZ='S')
 *              Copy A to U, generate Q
-*              (Cworkspace: need 2*M, prefer M+M*NB)
-*              (Rworkspace: 0)
+*              CWorkspace: need   2*M [tauq, taup] + M    [work]
+*              CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL CLACPY( 'L', M, M, A, LDA, U, LDU )
                CALL CUNGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
 *
 *              Copy A to VT, generate P**H
-*              (Cworkspace: need 2*M, prefer M+M*NB)
-*              (Rworkspace: 0)
+*              CWorkspace: need   2*M [tauq, taup] + M    [work]
+*              CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL CLACPY( 'U', M, N, A, LDA, VT, LDVT )
                CALL CUNGBR( 'P', M, N, M, VT, LDVT, WORK( ITAUP ),
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + M*M [RVT] + M*M [RU] + BDSPAC
 *
                IRVT = NRWORK
                IRU = IRVT + M*M
 *
 *              Multiply Q in U by real matrix RWORK(IRU), storing the
 *              result in A, copying to U
-*              (CWorkspace: need 0)
-*              (Rworkspace: need 3*M*M)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + M*M [RVT] + M*M [RU] + 2*M*M [rwork]
 *
                CALL CLACRM( M, M, U, LDU, RWORK( IRU ), M, A, LDA,
      $                      RWORK( NRWORK ) )
 *
 *              Multiply real matrix RWORK(IRVT) by P**H in VT,
 *              storing the result in A, copying to VT
-*              (Cworkspace: need 0)
-*              (Rworkspace: need M*M+2*M*N)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + M*M [RVT] + 2*M*N [rwork] < M + 5*M*M since N < 2*M here
 *
                NRWORK = IRU
                CALL CLARCM( M, N, RWORK( IRVT ), M, VT, LDVT, A, LDA,
                CALL CLACPY( 'F', M, N, A, LDA, VT, LDVT )
             ELSE
 *
+*              Path 5ta (N >> M, JOBZ='A')
 *              Copy A to U, generate Q
-*              (Cworkspace: need 2*M, prefer M+M*NB)
-*              (Rworkspace: 0)
+*              CWorkspace: need   2*M [tauq, taup] + M    [work]
+*              CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL CLACPY( 'L', M, M, A, LDA, U, LDU )
                CALL CUNGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
 *
 *              Copy A to VT, generate P**H
-*              (Cworkspace: need 2*M, prefer M+M*NB)
-*              (Rworkspace: 0)
+*              CWorkspace: need   2*M [tauq, taup] + N    [work]
+*              CWorkspace: prefer 2*M [tauq, taup] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL CLACPY( 'U', M, N, A, LDA, VT, LDVT )
                CALL CUNGBR( 'P', N, N, M, VT, LDVT, WORK( ITAUP ),
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + M*M [RVT] + M*M [RU] + BDSPAC
 *
                IRVT = NRWORK
                IRU = IRVT + M*M
 *
 *              Multiply Q in U by real matrix RWORK(IRU), storing the
 *              result in A, copying to U
-*              (CWorkspace: need 0)
-*              (Rworkspace: need 3*M*M)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + M*M [RVT] + M*M [RU] + 2*M*M [rwork]
 *
                CALL CLACRM( M, M, U, LDU, RWORK( IRU ), M, A, LDA,
      $                      RWORK( NRWORK ) )
 *
 *              Multiply real matrix RWORK(IRVT) by P**H in VT,
 *              storing the result in A, copying to VT
-*              (Cworkspace: need 0)
-*              (Rworkspace: need M*M+2*M*N)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + M*M [RVT] + 2*M*N [rwork] < M + 5*M*M since N < 2*M here
 *
+               NRWORK = IRU
                CALL CLARCM( M, N, RWORK( IRVT ), M, VT, LDVT, A, LDA,
      $                      RWORK( NRWORK ) )
                CALL CLACPY( 'F', M, N, A, LDA, VT, LDVT )
 *
 *           N .LT. MNTHR2
 *
-*           Path 6t (N greater than M, but not much larger)
+*           Path 6t (N > M, but not much larger)
 *           Reduce to bidiagonal form without LQ decomposition
 *           Use CUNMBR to compute singular vectors
 *
             NWORK = ITAUP + M
 *
 *           Bidiagonalize A
-*           (CWorkspace: need 2*M+N, prefer 2*M+(M+N)*NB)
-*           (RWorkspace: M)
+*           CWorkspace: need   2*M [tauq, taup] + N        [work]
+*           CWorkspace: prefer 2*M [tauq, taup] + (M+N)*NB [work]
+*           RWorkspace: need   M [e]
 *
             CALL CGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
      $                   WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
      $                   IERR )
             IF( WNTQN ) THEN
 *
+*              Path 6tn (N > M, JOBZ='N')
 *              Compute singular values only
-*              (Cworkspace: 0)
-*              (Rworkspace: need BDSPAN)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + BDSPAC
 *
-               CALL SBDSDC( 'L', 'N', M, S, RWORK( IE ), DUM, 1, DUM, 1,
+               CALL SBDSDC( 'L', 'N', M, S, RWORK( IE ), DUM,1,DUM,1,
      $                      DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
             ELSE IF( WNTQO ) THEN
+*              Path 6to (N > M, JOBZ='O')
                LDWKVT = M
                IVT = NWORK
-               IF( LWORK.GE.M*N+3*M ) THEN
+               IF( LWORK .GE. M*N + 3*M ) THEN
 *
 *                 WORK( IVT ) is M by N
 *
 *
 *                 WORK( IVT ) is M by CHUNK
 *
-                  CHUNK = ( LWORK-3*M ) / M
+                  CHUNK = ( LWORK - 3*M ) / M
                   NWORK = IVT + LDWKVT*CHUNK
                END IF
 *
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + M*M [RVT] + M*M [RU] + BDSPAC
 *
                IRVT = NRWORK
                IRU = IRVT + M*M
 *
 *              Copy real matrix RWORK(IRU) to complex matrix U
 *              Overwrite U by left singular vectors of A
-*              (Cworkspace: need 2*M, prefer M+M*NB)
-*              (Rworkspace: need 0)
+*              CWorkspace: need   2*M [tauq, taup] + M*M [VT] + M    [work]
+*              CWorkspace: prefer 2*M [tauq, taup] + M*M [VT] + M*NB [work]
+*              RWorkspace: need   M [e] + M*M [RVT] + M*M [RU]
 *
                CALL CLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
                CALL CUNMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
      $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),
      $                      LWORK-NWORK+1, IERR )
 *
-               IF( LWORK.GE.M*N+3*M ) THEN
+               IF( LWORK .GE. M*N + 3*M ) THEN
 *
-*              Copy real matrix RWORK(IRVT) to complex matrix WORK(IVT)
-*              Overwrite WORK(IVT) by right singular vectors of A,
-*              copying to A
-*              (Cworkspace: need M*N+2*M, prefer M*N+M+M*NB)
-*              (Rworkspace: need 0)
+*                 Path 6to-fast
+*                 Copy real matrix RWORK(IRVT) to complex matrix WORK(IVT)
+*                 Overwrite WORK(IVT) by right singular vectors of A,
+*                 copying to A
+*                 CWorkspace: need   2*M [tauq, taup] + M*N [VT] + M    [work]
+*                 CWorkspace: prefer 2*M [tauq, taup] + M*N [VT] + M*NB [work]
+*                 RWorkspace: need   M [e] + M*M [RVT]
 *
                   CALL CLACP2( 'F', M, M, RWORK( IRVT ), M, WORK( IVT ),
      $                         LDWKVT )
                   CALL CLACPY( 'F', M, N, WORK( IVT ), LDWKVT, A, LDA )
                ELSE
 *
+*                 Path 6to-slow
 *                 Generate P**H in A
-*                 (Cworkspace: need 2*M, prefer M+M*NB)
-*                 (Rworkspace: need 0)
+*                 CWorkspace: need   2*M [tauq, taup] + M*M [VT] + M    [work]
+*                 CWorkspace: prefer 2*M [tauq, taup] + M*M [VT] + M*NB [work]
+*                 RWorkspace: need   0
 *
                   CALL CUNGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
      $                         WORK( NWORK ), LWORK-NWORK+1, IERR )
 *
 *                 Multiply Q in A by real matrix RWORK(IRU), storing the
 *                 result in WORK(IU), copying to A
-*                 (CWorkspace: need M*M, prefer M*N)
-*                 (Rworkspace: need 3*M*M, prefer M*M+2*M*N)
+*                 CWorkspace: need   2*M [tauq, taup] + M*M [VT]
+*                 CWorkspace: prefer 2*M [tauq, taup] + M*N [VT]
+*                 RWorkspace: need   M [e] + M*M [RVT] + 2*M*M [rwork]
+*                 RWorkspace: prefer M [e] + M*M [RVT] + 2*M*N [rwork] < M + 5*M*M since N < 2*M here
 *
                   NRWORK = IRU
                   DO 60 I = 1, N, CHUNK
                END IF
             ELSE IF( WNTQS ) THEN
 *
+*              Path 6ts (N > M, JOBZ='S')
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + M*M [RVT] + M*M [RU] + BDSPAC
 *
                IRVT = NRWORK
                IRU = IRVT + M*M
 *
 *              Copy real matrix RWORK(IRU) to complex matrix U
 *              Overwrite U by left singular vectors of A
-*              (CWorkspace: need 3*M, prefer 2*M+M*NB)
-*              (RWorkspace: M*M)
+*              CWorkspace: need   2*M [tauq, taup] + M    [work]
+*              CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
+*              RWorkspace: need   M [e] + M*M [RVT] + M*M [RU]
 *
                CALL CLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
                CALL CUNMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
 *
 *              Copy real matrix RWORK(IRVT) to complex matrix VT
 *              Overwrite VT by right singular vectors of A
-*              (CWorkspace: need 3*M, prefer 2*M+M*NB)
-*              (RWorkspace: M*M)
+*              CWorkspace: need   2*M [tauq, taup] + M    [work]
+*              CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
+*              RWorkspace: need   M [e] + M*M [RVT]
 *
                CALL CLASET( 'F', M, N, CZERO, CZERO, VT, LDVT )
                CALL CLACP2( 'F', M, M, RWORK( IRVT ), M, VT, LDVT )
      $                      LWORK-NWORK+1, IERR )
             ELSE
 *
+*              Path 6ta (N > M, JOBZ='A')
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + M*M [RVT] + M*M [RU] + BDSPAC
 *
                IRVT = NRWORK
                IRU = IRVT + M*M
 *
 *              Copy real matrix RWORK(IRU) to complex matrix U
 *              Overwrite U by left singular vectors of A
-*              (CWorkspace: need 3*M, prefer 2*M+M*NB)
-*              (RWorkspace: M*M)
+*              CWorkspace: need   2*M [tauq, taup] + M    [work]
+*              CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
+*              RWorkspace: need   M [e] + M*M [RVT] + M*M [RU]
 *
                CALL CLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
                CALL CUNMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
 *
 *              Copy real matrix RWORK(IRVT) to complex matrix VT
 *              Overwrite VT by right singular vectors of A
-*              (CWorkspace: need 2*M+N, prefer 2*M+N*NB)
-*              (RWorkspace: M*M)
+*              CWorkspace: need   2*M [tauq, taup] + N    [work]
+*              CWorkspace: prefer 2*M [tauq, taup] + N*NB [work]
+*              RWorkspace: need   M [e] + M*M [RVT]
 *
                CALL CLACP2( 'F', M, M, RWORK( IRVT ), M, VT, LDVT )
                CALL CUNMBR( 'P', 'R', 'C', N, N, M, A, LDA,
index 3c1f825db828f4d18253b049345a78aa8ed67714..d147dee5329e46cc525c2bc638925054acd66075 100644 (file)
       SUBROUTINE CGESVD( JOBU, JOBVT, M, N, A, LDA, S, U, LDU, VT, LDVT,
      $                   WORK, LWORK, RWORK, INFO )
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     April 2012
             MNTHR = ILAENV( 6, 'CGESVD', JOBU // JOBVT, M, N, 0, 0 )
 *           Compute space needed for CGEQRF
             CALL CGEQRF( M, N, A, LDA, CDUM(1), CDUM(1), -1, IERR )
-            LWORK_CGEQRF=CDUM(1)
+            LWORK_CGEQRF = INT( CDUM(1) )
 *           Compute space needed for CUNGQR
             CALL CUNGQR( M, N, N, A, LDA, CDUM(1), CDUM(1), -1, IERR )
-            LWORK_CUNGQR_N=CDUM(1)
+            LWORK_CUNGQR_N = INT( CDUM(1) )
             CALL CUNGQR( M, M, N, A, LDA, CDUM(1), CDUM(1), -1, IERR )
-            LWORK_CUNGQR_M=CDUM(1)
+            LWORK_CUNGQR_M = INT( CDUM(1) )
 *           Compute space needed for CGEBRD
             CALL CGEBRD( N, N, A, LDA, S, DUM(1), CDUM(1),
      $                   CDUM(1), CDUM(1), -1, IERR )
-            LWORK_CGEBRD=CDUM(1)
+            LWORK_CGEBRD = INT( CDUM(1) )
 *           Compute space needed for CUNGBR
             CALL CUNGBR( 'P', N, N, N, A, LDA, CDUM(1),
      $                   CDUM(1), -1, IERR )
-            LWORK_CUNGBR_P=CDUM(1)
+            LWORK_CUNGBR_P = INT( CDUM(1) )
             CALL CUNGBR( 'Q', N, N, N, A, LDA, CDUM(1),
      $                   CDUM(1), -1, IERR )
-            LWORK_CUNGBR_Q=CDUM(1)
+            LWORK_CUNGBR_Q = INT( CDUM(1) )
 *
             MNTHR = ILAENV( 6, 'CGESVD', JOBU // JOBVT, M, N, 0, 0 )
             IF( M.GE.MNTHR ) THEN
 *
                CALL CGEBRD( M, N, A, LDA, S, DUM(1), CDUM(1),
      $                   CDUM(1), CDUM(1), -1, IERR )
-               LWORK_CGEBRD=CDUM(1)
+               LWORK_CGEBRD = INT( CDUM(1) )
                MAXWRK = 2*N + LWORK_CGEBRD
                IF( WNTUS .OR. WNTUO ) THEN
                   CALL CUNGBR( 'Q', M, N, N, A, LDA, CDUM(1),
      $                   CDUM(1), -1, IERR )
-                  LWORK_CUNGBR_Q=CDUM(1)
+                  LWORK_CUNGBR_Q = INT( CDUM(1) )
                   MAXWRK = MAX( MAXWRK, 2*N+LWORK_CUNGBR_Q )
                END IF
                IF( WNTUA ) THEN
                   CALL CUNGBR( 'Q', M, M, N, A, LDA, CDUM(1),
      $                   CDUM(1), -1, IERR )
-                  LWORK_CUNGBR_Q=CDUM(1)
+                  LWORK_CUNGBR_Q = INT( CDUM(1) )
                   MAXWRK = MAX( MAXWRK, 2*N+LWORK_CUNGBR_Q )
                END IF
                IF( .NOT.WNTVN ) THEN
                   MAXWRK = MAX( MAXWRK, 2*N+LWORK_CUNGBR_P )
-               MINWRK = 2*N + M
                END IF
+               MINWRK = 2*N + M
             END IF
          ELSE IF( MINMN.GT.0 ) THEN
 *
             MNTHR = ILAENV( 6, 'CGESVD', JOBU // JOBVT, M, N, 0, 0 )
 *           Compute space needed for CGELQF
             CALL CGELQF( M, N, A, LDA, CDUM(1), CDUM(1), -1, IERR )
-            LWORK_CGELQF=CDUM(1)
+            LWORK_CGELQF = INT( CDUM(1) )
 *           Compute space needed for CUNGLQ
             CALL CUNGLQ( N, N, M, CDUM(1), N, CDUM(1), CDUM(1), -1,
      $                   IERR )
-            LWORK_CUNGLQ_N=CDUM(1)
+            LWORK_CUNGLQ_N = INT( CDUM(1) )
             CALL CUNGLQ( M, N, M, A, LDA, CDUM(1), CDUM(1), -1, IERR )
-            LWORK_CUNGLQ_M=CDUM(1)
+            LWORK_CUNGLQ_M = INT( CDUM(1) )
 *           Compute space needed for CGEBRD
             CALL CGEBRD( M, M, A, LDA, S, DUM(1), CDUM(1),
      $                   CDUM(1), CDUM(1), -1, IERR )
-            LWORK_CGEBRD=CDUM(1)
+            LWORK_CGEBRD = INT( CDUM(1) )
 *            Compute space needed for CUNGBR P
             CALL CUNGBR( 'P', M, M, M, A, N, CDUM(1),
      $                   CDUM(1), -1, IERR )
-            LWORK_CUNGBR_P=CDUM(1)
+            LWORK_CUNGBR_P = INT( CDUM(1) )
 *           Compute space needed for CUNGBR Q
             CALL CUNGBR( 'Q', M, M, M, A, N, CDUM(1),
      $                   CDUM(1), -1, IERR )
-            LWORK_CUNGBR_Q=CDUM(1)
+            LWORK_CUNGBR_Q = INT( CDUM(1) )
             IF( N.GE.MNTHR ) THEN
                IF( WNTVN ) THEN
 *
 *
                CALL CGEBRD( M, N, A, LDA, S, DUM(1), CDUM(1),
      $                   CDUM(1), CDUM(1), -1, IERR )
-               LWORK_CGEBRD=CDUM(1)
+               LWORK_CGEBRD = INT( CDUM(1) )
                MAXWRK = 2*M + LWORK_CGEBRD
                IF( WNTVS .OR. WNTVO ) THEN
 *                Compute space needed for CUNGBR P
                  CALL CUNGBR( 'P', M, N, M, A, N, CDUM(1),
      $                   CDUM(1), -1, IERR )
-                 LWORK_CUNGBR_P=CDUM(1)
+                 LWORK_CUNGBR_P = INT( CDUM(1) )
                  MAXWRK = MAX( MAXWRK, 2*M+LWORK_CUNGBR_P )
                END IF
                IF( WNTVA ) THEN
                  CALL CUNGBR( 'P', N,  N, M, A, N, CDUM(1),
      $                   CDUM(1), -1, IERR )
-                 LWORK_CUNGBR_P=CDUM(1)
+                 LWORK_CUNGBR_P = INT( CDUM(1) )
                  MAXWRK = MAX( MAXWRK, 2*M+LWORK_CUNGBR_P )
                END IF
                IF( .NOT.WNTUN ) THEN
                   MAXWRK = MAX( MAXWRK, 2*M+LWORK_CUNGBR_Q )
-               MINWRK = 2*M + N
                END IF
+               MINWRK = 2*M + N
             END IF
          END IF
          MAXWRK = MAX( MINWRK, MAXWRK )
 *
 *              Zero out below R
 *
-               CALL CLASET( 'L', N-1, N-1, CZERO, CZERO, A( 2, 1 ),
-     $                      LDA )
+               IF( N .GT. 1 ) THEN
+                  CALL CLASET( 'L', N-1, N-1, CZERO, CZERO, A( 2, 1 ),
+     $                         LDA )
+               END IF
                IE = 1
                ITAUQ = 1
                ITAUP = ITAUQ + N
 *
 *                    Zero out below R in A
 *
-                     CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
-     $                            A( 2, 1 ), LDA )
+                     IF( N .GT. 1 ) THEN
+                        CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                               A( 2, 1 ), LDA )
+                     END IF
 *
 *                    Bidiagonalize R in A
 *                    (CWorkspace: need 3*N, prefer 2*N+2*N*NB)
 *
 *                    Zero out below R in A
 *
-                     CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
-     $                            A( 2, 1 ), LDA )
+                     IF( N .GT. 1 ) THEN
+                        CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                               A( 2, 1 ), LDA )
+                     END IF
 *
 *                    Bidiagonalize R in A
 *                    (CWorkspace: need 3*N, prefer 2*N+2*N*NB)
 *
 *                    Zero out below R in A
 *
-                     CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
-     $                            A( 2, 1 ), LDA )
+                     IF( N .GT. 1 ) THEN
+                        CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                               A( 2, 1 ), LDA )
+                     END IF
 *
 *                    Bidiagonalize R in A
 *                    (CWorkspace: need 3*N, prefer 2*N+2*N*NB)
 *
 *                    Zero out below R in A
 *
-                     CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
-     $                            A( 2, 1 ), LDA )
+                     IF( N .GT. 1 ) THEN
+                        CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                               A( 2, 1 ), LDA )
+                     END IF
 *
 *                    Bidiagonalize R in A
 *                    (CWorkspace: need 3*N, prefer 2*N+2*N*NB)
index 235426ad4895839a4e036d32d6f572db3af04d6d..1e32637c6d64658b351c58f7ee052166b9010076 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is REAL
-*>          VL >=0.
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for singular values. VU > VL.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is REAL
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for singular values. VU > VL.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest singular value to be returned.
+*>          1 <= IL <= IU <= min(M,N), if min(M,N) > 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest singular values to be returned.
+*>          If RANGE='I', the index of the
+*>          largest singular value to be returned.
 *>          1 <= IL <= IU <= min(M,N), if min(M,N) > 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>          vectors, stored columnwise) as specified by RANGE; if 
 *>          JOBU = 'N', U is not referenced.
 *>          Note: The user must ensure that UCOL >= NS; if RANGE = 'V', 
-*>          the exact value of NS is not known ILQFin advance and an upper 
+*>          the exact value of NS is not known in advance and an upper
 *>          bound must be used.
 *> \endverbatim
 *>
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complexGEsing
 *
      $                    IL, IU, NS, S, U, LDU, VT, LDVT, WORK, 
      $                    LWORK, RWORK, IWORK, INFO )
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBU, JOBVT, RANGE
       CHARACTER          JOBZ, RNGTGK
       LOGICAL            ALLS, INDS, LQUERY, VALS, WANTU, WANTVT
       INTEGER            I, ID, IE, IERR, ILQF, ILTGK, IQRF, ISCL,
-     $                   ITAU, ITAUP, ITAUQ, ITEMP, ITGKZ, IUTGK,
-     $                   J, K, MAXWRK, MINMN, MINWRK, MNTHR
+     $                   ITAU, ITAUP, ITAUQ, ITEMP, ITEMPR, ITGKZ, 
+     $                   IUTGK, J, K, MAXWRK, MINMN, MINWRK, MNTHR
       REAL               ABSTOL, ANRM, BIGNUM, EPS, SMLNUM
 *     ..
 *     .. Local Arrays ..
          IF( INFO.EQ.0 ) THEN
             IF( WANTU .AND. LDU.LT.M ) THEN
                INFO = -15
-            ELSE IF( WANTVT .AND. LDVT.LT.MINMN ) THEN
-               INFO = -16
+            ELSE IF( WANTVT ) THEN
+               IF( INDS ) THEN
+                   IF( LDVT.LT.IU-IL+1 ) THEN
+                       INFO = -17
+                   END IF
+               ELSE IF( LDVT.LT.MINMN ) THEN
+                   INFO = -17
+               END IF
             END IF
          END IF
       END IF
 *
 *                 Path 1 (M much larger than N)
 *
-                  MAXWRK = N + N*
-     $                     ILAENV( 1, 'SGEQRF', ' ', M, N, -1, -1 )
-                  MAXWRK = MAX( MAXWRK, N*N + N + 2*N*
-     $                     ILAENV( 1, 'SGEBRD', ' ', N, N, -1, -1 ) )
-                  MINWRK = N*(N+4)
+                  MINWRK = N*(N+5)
+                  MAXWRK = N + N*ILAENV(1,'CGEQRF',' ',M,N,-1,-1)
+                  MAXWRK = MAX(MAXWRK,
+     $                     N*N+2*N+2*N*ILAENV(1,'CGEBRD',' ',N,N,-1,-1))
+                  IF (WANTU .OR. WANTVT) THEN
+                     MAXWRK = MAX(MAXWRK,
+     $                       N*N+2*N+N*ILAENV(1,'CUNMQR','LN',N,N,N,-1))
+                  END IF
                ELSE
 *
 *                 Path 2 (M at least N, but not much larger)
 *
-                  MAXWRK = 2*N + ( M+N )*
-     $                     ILAENV( 1, 'CGEBRD', ' ', M, N, -1, -1 )
-                  MINWRK = 2*N + M
+                  MINWRK = 3*N + M
+                  MAXWRK = 2*N + (M+N)*ILAENV(1,'CGEBRD',' ',M,N,-1,-1)
+                  IF (WANTU .OR. WANTVT) THEN
+                     MAXWRK = MAX(MAXWRK,
+     $                        2*N+N*ILAENV(1,'CUNMQR','LN',N,N,N,-1))
+                  END IF
                END IF
             ELSE
                MNTHR = ILAENV( 6, 'CGESVD', JOBU // JOBVT, M, N, 0, 0 )
 *
 *                 Path 1t (N much larger than M)
 *
-                  MAXWRK = M + M*
-     $                     ILAENV( 1, 'CGELQF', ' ', M, N, -1, -1 )
-                  MAXWRK = MAX( MAXWRK, M*M + M + 2*M*
-     $                     ILAENV( 1, 'CGEBRD', ' ', M, M, -1, -1 ) )
-                  MINWRK = M*(M+4)
+                  MINWRK = M*(M+5)
+                  MAXWRK = M + M*ILAENV(1,'CGELQF',' ',M,N,-1,-1)
+                  MAXWRK = MAX(MAXWRK,
+     $                     M*M+2*M+2*M*ILAENV(1,'CGEBRD',' ',M,M,-1,-1))
+                  IF (WANTU .OR. WANTVT) THEN
+                     MAXWRK = MAX(MAXWRK,
+     $                       M*M+2*M+M*ILAENV(1,'CUNMQR','LN',M,M,M,-1))
+                  END IF
                ELSE
 *
 *                 Path 2t (N greater than M, but not much larger)
 *
-                  MAXWRK = M*(M*2+19) + ( M+N )*
-     $                     ILAENV( 1, 'CGEBRD', ' ', M, N, -1, -1 )
-                  MINWRK = 2*M + N
+*
+                  MINWRK = 3*M + N
+                  MAXWRK = 2*M + (M+N)*ILAENV(1,'CGEBRD',' ',M,N,-1,-1)
+                  IF (WANTU .OR. WANTVT) THEN
+                     MAXWRK = MAX(MAXWRK,
+     $                        2*M+M*ILAENV(1,'CUNMQR','LN',M,M,M,-1))
+                  END IF
                END IF
             END IF
          END IF
 *
 *     Set singular values indices accord to RANGE='A'.
 *
-      ALLS = LSAME( RANGE, 'A' )
-      INDS = LSAME( RANGE, 'I' )
       IF( ALLS ) THEN
          RNGTGK = 'I'
          ILTGK = 1
             CALL CGEBRD( N, N, WORK( IQRF ), N, RWORK( ID ), 
      $                   RWORK( IE ), WORK( ITAUQ ), WORK( ITAUP ),
      $                   WORK( ITEMP ), LWORK-ITEMP+1, INFO )
-            ITEMP = ITGKZ + N*(N*2+1)
+            ITEMPR = ITGKZ + N*(N*2+1)
 *
 *           Solve eigenvalue problem TGK*Z=Z*S.
 *           (Workspace: need 2*N*N+14*N)          
 *                   
             CALL SBDSVDX( 'U', JOBZ, RNGTGK, N, RWORK( ID ),
      $                    RWORK( IE ), VL, VU, ILTGK, IUTGK, NS, S,
-     $                    RWORK( ITGKZ ), N*2, RWORK( ITEMP ),
+     $                    RWORK( ITGKZ ), N*2, RWORK( ITEMPR ),
      $                    IWORK, INFO)
 *
 *           If needed, compute left singular vectors.
                   END DO
                   K = K + N
                END DO
-               CALL CLASET( 'A', M-N, N, CZERO, CZERO, U( N+1,1 ), LDU )
+               CALL CLASET( 'A', M-N, NS, CZERO, CZERO, U( N+1,1 ), LDU)
 *
 *              Call CUNMBR to compute QB*UB.
 *              (Workspace in WORK( ITEMP ): need N, prefer N*NB)
             CALL CGEBRD( M, N, A, LDA, RWORK( ID ), RWORK( IE ), 
      $                   WORK( ITAUQ ), WORK( ITAUP ), WORK( ITEMP ),
      $                   LWORK-ITEMP+1, INFO )
-            ITEMP = ITGKZ + N*(N*2+1)
+            ITEMPR = ITGKZ + N*(N*2+1)
 *
 *           Solve eigenvalue problem TGK*Z=Z*S.
 *           (Workspace: need 2*N*N+14*N)          
 *                     
             CALL SBDSVDX( 'U', JOBZ, RNGTGK, N, RWORK( ID ),
      $                    RWORK( IE ), VL, VU, ILTGK, IUTGK, NS, S, 
-     $                    RWORK( ITGKZ ), N*2, RWORK( ITEMP ), 
+     $                    RWORK( ITGKZ ), N*2, RWORK( ITEMPR ), 
      $                    IWORK, INFO)
 *
 *           If needed, compute left singular vectors.
                   END DO
                   K = K + N
                END DO
-               CALL CLASET( 'A', M-N, N, CZERO, CZERO, U( N+1,1 ), LDU )
+               CALL CLASET( 'A', M-N, NS, CZERO, CZERO, U( N+1,1 ), LDU)
 *
 *              Call CUNMBR to compute QB*UB.
 *              (Workspace in WORK( ITEMP ): need N, prefer N*NB)
             CALL CGEBRD( M, M, WORK( ILQF ), M, RWORK( ID ),
      $                   RWORK( IE ), WORK( ITAUQ ), WORK( ITAUP ), 
      $                   WORK( ITEMP ), LWORK-ITEMP+1, INFO )
-            ITEMP = ITGKZ + M*(M*2+1)
+            ITEMPR = ITGKZ + M*(M*2+1)
 *
 *           Solve eigenvalue problem TGK*Z=Z*S.
 *           (Workspace: need 2*M*M+14*M)          
 *
             CALL SBDSVDX( 'U', JOBZ, RNGTGK, M, RWORK( ID ),
      $                    RWORK( IE ), VL, VU, ILTGK, IUTGK, NS, S, 
-     $                    RWORK( ITGKZ ), M*2, RWORK( ITEMP ), 
+     $                    RWORK( ITGKZ ), M*2, RWORK( ITEMPR ), 
      $                    IWORK, INFO)
 *
 *           If needed, compute left singular vectors.
                   END DO
                   K = K + M
                END DO
-               CALL CLASET( 'A', M, N-M, CZERO, CZERO, 
+               CALL CLASET( 'A', NS, N-M, CZERO, CZERO,
      $                      VT( 1,M+1 ), LDVT )
 *
 *              Call CUNMBR to compute (VB**T)*(PB**T)
             CALL CGEBRD( M, N, A, LDA, RWORK( ID ), RWORK( IE ), 
      $                   WORK( ITAUQ ), WORK( ITAUP ), WORK( ITEMP ),
      $                   LWORK-ITEMP+1, INFO )
-            ITEMP = ITGKZ + M*(M*2+1)
+            ITEMPR = ITGKZ + M*(M*2+1)
 *
 *           Solve eigenvalue problem TGK*Z=Z*S.
 *           (Workspace: need 2*M*M+14*M)          
 *          
             CALL SBDSVDX( 'L', JOBZ, RNGTGK, M, RWORK( ID ), 
      $                    RWORK( IE ), VL, VU, ILTGK, IUTGK, NS, S, 
-     $                    RWORK( ITGKZ ), M*2, RWORK( ITEMP ), 
+     $                    RWORK( ITGKZ ), M*2, RWORK( ITEMPR ), 
      $                    IWORK, INFO)
 * 
 *           If needed, compute left singular vectors.
                   END DO
                   K = K + M
                END DO
-               CALL CLASET( 'A', M, N-M, CZERO, CZERO, 
+               CALL CLASET( 'A', NS, N-M, CZERO, CZERO,
      $                      VT( 1,M+1 ), LDVT )
 *
 *              Call CUNMBR to compute VB**T * PB**T
index 69d77048b41a5fe9d4a472dd3e8638ad881c9e13..28f3eb305beb4a6756d9bd8c13f238342e0c523c 100644 (file)
 *> \endverbatim
 *>
 *> \param[in,out] CWORK
+*> \verbatim
 *>          CWORK is COMPLEX array, dimension M+N.
 *>          Used as work space.
 *> \endverbatim
 *> \verbatim
 *>          LWORK is INTEGER
 *>          Length of CWORK, LWORK >= M+N.
+*> \endverbatim
 *>
 *> \param[in,out] RWORK
+*> \verbatim
 *>          RWORK is REAL array, dimension max(6,M+N).
 *>          On entry,
 *>          If JOBU .EQ. 'C' :
 *> \endverbatim
 *>
 *> \param[in] LRWORK
+*> \verbatim
 *>          LRWORK is INTEGER
 *>         Length of RWORK, LRWORK >= MAX(6,N).
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complexGEcomputational
 *
       SUBROUTINE CGESVJ( JOBA, JOBU, JOBV, M, N, A, LDA, SVA, MV, V, 
      $                   LDV, CWORK, LWORK, RWORK, LRWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
       IMPLICIT NONE 
 *     .. Scalar Arguments ..
 *     from BLAS
       EXTERNAL           CCOPY, CROT, CSSCAL, CSWAP
 *     from LAPACK
-      EXTERNAL           CLASCL, CLASET, CLASSQ, XERBLA
+      EXTERNAL           CLASCL, CLASET, CLASSQ, SLASCL, XERBLA
       EXTERNAL           CGSVJ0, CGSVJ1
 *     ..
 *     .. Executable Statements ..
                               END IF
                            END IF
 *
-                           OMPQ = AAPQ / ABS(AAPQ) 
 *                           AAPQ = AAPQ * CONJG( CWORK(p) ) * CWORK(q) 
                            AAPQ1  = -ABS(AAPQ) 
                            MXAAPQ = AMAX1( MXAAPQ, -AAPQ1 )
 *
                               IF( ROTOK ) THEN
 *
+                                 OMPQ = AAPQ / ABS(AAPQ) 
                                  AQOAP = AAQQ / AAPP
                                  APOAQ = AAPP / AAQQ
                                  THETA = -HALF*ABS( AQOAP-APOAQ )/AAPQ1
                               END IF
                            END IF
 *
-                           OMPQ = AAPQ / ABS(AAPQ) 
 *                           AAPQ = AAPQ * CONJG(CWORK(p))*CWORK(q)   
                            AAPQ1  = -ABS(AAPQ)
                            MXAAPQ = AMAX1( MXAAPQ, -AAPQ1 )
 *
                               IF( ROTOK ) THEN
 *
+                                 OMPQ = AAPQ / ABS(AAPQ) 
                                  AQOAP = AAQQ / AAPP
                                  APOAQ = AAPP / AAQQ
                                  THETA = -HALF*ABS( AQOAP-APOAQ )/ AAPQ1
index 99eb69d92aa71ea5f258efab5953ab2608a6fdf7..021ec6724ff9518d3f5592a74e9caf69f0f9333f 100644 (file)
@@ -98,7 +98,7 @@
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2013
+*> \date June 2016
 *
 *> \ingroup complexGEauxiliary
 *
 *  =====================================================================
       SUBROUTINE CGETC2( N, A, LDA, IPIV, JPIV, INFO )
 *
-*  -- LAPACK auxiliary routine (version 3.5.0) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2013
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            INFO, LDA, N
index 9e985d0e23834d6e494a05b4e6e16f7a31bcaaeb..d761806ebc69d432dac06c8d4a08afa16c038129 100644 (file)
@@ -37,7 +37,7 @@
 *> 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)
+*>    A = [ -----|----- ]  with n1 = min(m,n)/2
 *>        [  A21 | A22  ]       n2 = n-n1
 *>            
 *>                                       [ A11 ]
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complexGEcomputational
 *
 *  =====================================================================
       RECURSIVE SUBROUTINE CGETRF2( M, N, A, LDA, IPIV, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            INFO, LDA, M, N
index 9103ccf1c6ff177677587217709204170f69a6ae..876a26df967284aaa5657ec92b4b440e755f97ee 100644 (file)
      $                   LDB, SDIM, ALPHA, BETA, VSL, LDVSL, VSR, LDVSR,
      $                   WORK, LWORK, RWORK, BWORK, INFO )
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     January 2015
          LWKOPT = MAX( LWKOPT, N + INT ( WORK( 1 ) ) )
          CALL CHGEQZ( 'S', JOBVSL, JOBVSR, N, 1, N, A, LDA, B, LDB,
      $                ALPHA, BETA, VSL, LDVSL, VSR, LDVSR, WORK, -1,
-     $                WORK, IERR )
+     $                RWORK, IERR )
          LWKOPT = MAX( LWKOPT, INT ( WORK( 1 ) ) )
          IF( WANTST ) THEN
             CALL CTGSEN( 0, ILVSL, ILVSR, BWORK, N, A, LDA, B, LDB,
index decdae509fcb8ba30c382da52c255c11d345006a..f34b8f2c4144d97fa68f7475f77b2c128b240f1f 100644 (file)
       SUBROUTINE CGGEV3( JOBVL, JOBVR, N, A, LDA, B, LDB, ALPHA, BETA,
      $                   VL, LDVL, VR, LDVR, WORK, LWORK, RWORK, INFO )
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     January 2015
index 112b41a1790390daeb9f272600c9a3b5b063dd3d..a9468a24b36817928a73f5a67ef07796baa6076c 100644 (file)
       SUBROUTINE CGGHD3( COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB, Q,
      $                   LDQ, Z, LDZ, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     January 2015
 *
       INFO = 0
       NB = ILAENV( 1, 'CGGHD3', ' ', N, ILO, IHI, -1 )
-      LWKOPT = 6*N*NB
+      LWKOPT = MAX( 6*N*NB, 1 )
       WORK( 1 ) = CMPLX( LWKOPT )
       INITQ = LSAME( COMPQ, 'I' )
       WANTQ = INITQ .OR. LSAME( COMPQ, 'V' )
index 36fe9913be88dd852809f9965e22fb19cacec445..feee3644f9964657f4fbc91afff13168beedca0b 100644 (file)
      $                    TOLA, TOLB, K, L, U, LDU, V, LDV, Q, LDQ,
      $                    IWORK, RWORK, TAU, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     August 2015
 *     .. Local Scalars ..
       LOGICAL            FORWRD, WANTQ, WANTU, WANTV, LQUERY
       INTEGER            I, J, LWKOPT
-      COMPLEX            T
 *     ..
 *     .. External Functions ..
       LOGICAL            LSAME
index 79ffde6233d91c49143b41bca4c92eb075610437..66074bdb163675063d47d655ce58734379c5967d 100644 (file)
@@ -1,4 +1,4 @@
-*> \brief \b CGSVJ0 pre-processor for the routine sgesvj.
+*> \brief \b CGSVJ0 pre-processor for the routine cgesvj.
 *
 *  =========== DOCUMENTATION ===========
 *
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complexOTHERcomputational
 *
       SUBROUTINE CGSVJ0( JOBV, M, N, A, LDA, D, SVA, MV, V, LDV, EPS,
      $                   SFMIN, TOL, NSWEEP, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
       IMPLICIT NONE
 *     .. Scalar Arguments ..
index f4b1fc156ef12fa437d638c47ac93fc73899d32c..ca71a4eaef05ab4a0cae45f369130ea84b75d4a2 100644 (file)
@@ -1,4 +1,4 @@
-*> \brief \b CGSVJ1 pre-processor for the routine sgesvj, applies Jacobi rotations targeting only particular pivots.
+*> \brief \b CGSVJ1 pre-processor for the routine cgesvj, applies Jacobi rotations targeting only particular pivots.
 *
 *  =========== DOCUMENTATION ===========
 *
 *>
 *> \param[in,out] A
 *> \verbatim
-*>          A is REAL array, dimension (LDA,N)
+*>          A is COMPLEX array, dimension (LDA,N)
 *>          On entry, M-by-N matrix A, such that A*diag(D) represents
 *>          the input matrix.
 *>          On exit,
 *>
 *> \param[in,out] D
 *> \verbatim
-*>          D is REAL array, dimension (N)
+*>          D is COMPLEX array, dimension (N)
 *>          The array D accumulates the scaling factors from the fast scaled
 *>          Jacobi rotations.
 *>          On entry, A*diag(D) represents the input matrix.
 *>
 *> \param[in,out] V
 *> \verbatim
-*>          V is REAL array, dimension (LDV,N)
+*>          V is COMPLEX array, dimension (LDV,N)
 *>          If JOBV .EQ. 'V' then N rows of V are post-multipled by a
 *>                           sequence of Jacobi rotations.
 *>          If JOBV .EQ. 'A' then MV rows of V are post-multipled by a
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complexOTHERcomputational
 *
       SUBROUTINE CGSVJ1( JOBV, M, N, N1, A, LDA, D, SVA, MV, V, LDV,
      $                   EPS, SFMIN, TOL, NSWEEP, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       REAL               EPS, SFMIN, TOL
index d9a22e3504f1e5b5f95310bd956ce66885f5f04b..47dd8069eb04d2add6fa9eaed2d958f985b2873b 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is REAL
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is REAL
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup complexOTHEReigen
 *
      $                   VU, IL, IU, ABSTOL, M, W, Z, LDZ, WORK, RWORK,
      $                   IWORK, IFAIL, INFO )
 *
-*  -- LAPACK driver routine (version 3.4.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE, UPLO
index e57bd937521370eaa318b604e5a7391c76d20d80..64dd1f6de85ba9a1e67ebd81685311681a9865a8 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complexOTHEReigen
 *
      $                   Z, LDZ, WORK, LWORK, RWORK, LRWORK, IWORK,
      $                   LIWORK, INFO )
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, UPLO
       LLWK2 = LWORK - INDWK2 + 2
       LLRWK = LRWORK - INDWRK + 2
       CALL CHBGST( JOBZ, UPLO, N, KA, KB, AB, LDAB, BB, LDBB, Z, LDZ,
-     $             WORK, RWORK( INDWRK ), IINFO )
+     $             WORK, RWORK, IINFO )
 *
 *     Reduce Hermitian band matrix to tridiagonal form.
 *
index 5e28cc88fd00550af3237e92eedce052ea8f1be3..43ae794d522f3418ac038014db298622e5a3b407 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is REAL
+*>
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is REAL
 *>
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
 *>
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complexOTHEReigen
 *
      $                   LDBB, Q, LDQ, VL, VU, IL, IU, ABSTOL, M, W, Z,
      $                   LDZ, WORK, RWORK, IWORK, IFAIL, INFO )
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE, UPLO
index 18dfe4313af203316efab5f608d12d4c72b87f13..9b8ffb4e3b2f18b7228af7d2aab26094bff21bb0 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is REAL
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is REAL
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup complexHEeigen
 *
      $                   ABSTOL, M, W, Z, LDZ, ISUPPZ, WORK, LWORK,
      $                   RWORK, LRWORK, IWORK, LIWORK, INFO )
 *
-*  -- LAPACK driver routine (version 3.4.2) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE, UPLO
index 12f69ccc92c70d08b3eda062ffbc78dcbb9e1805..f41479bd11c03f3920d8fd64e79e17142805fdca 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is REAL
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is REAL
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup complexHEeigen
 *
      $                   ABSTOL, M, W, Z, LDZ, WORK, LWORK, RWORK,
      $                   IWORK, IFAIL, INFO )
 *
-*  -- LAPACK driver routine (version 3.4.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE, UPLO
index 33a4e5f4a800b42d32ec9e239668fe8de5d05611..52fb983d2fdef13ca22f9a5f0dccc1043fa312b3 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is REAL
+*>
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is REAL
 *>
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
 *>
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complexHEeigen
 *
      $                   VL, VU, IL, IU, ABSTOL, M, W, Z, LDZ, WORK,
      $                   LWORK, RWORK, IWORK, IFAIL, INFO )
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE, UPLO
index 98c8dbd267198f98239e4105a7874ab3eada8725..0217150d184d19bff115cb7723c0c4521e6596eb 100644 (file)
 *> \author Univ. of Colorado Denver
 *> \author NAG Ltd.
 *
-*> \date November 2013
+*> \date June 2016
 *
 *> \ingroup complexHEcomputational
 *
 *>
 *> \verbatim
 *>
-*>  November 2013,  Igor Kozachenko,
+*>  June 2016,  Igor Kozachenko,
 *>                  Computer Science Division,
 *>                  University of California, Berkeley
 *>
 *  =====================================================================
       SUBROUTINE CHETRF_ROOK( UPLO, N, A, LDA, IPIV, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.5.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2013
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          UPLO
 *        Determine the block size
 *
          NB = ILAENV( 1, 'CHETRF_ROOK', UPLO, N, -1, -1, -1 )
-         LWKOPT = N*NB
+         LWKOPT = MAX( 1, N*NB )
          WORK( 1 ) = LWKOPT
       END IF
 *
index 024354e66bcf18741178c02d0281011b395a6547..15aaaa44d6f01b8a40ba7302164981c9db3b2afe 100644 (file)
 *> \param[in,out] Q
 *> \verbatim
 *>          Q is COMPLEX array, dimension (LDQ, N)
-*>          On entry, if COMPZ = 'V', the unitary matrix Q1 used in the
+*>          On entry, if COMPQ = 'V', the unitary matrix Q1 used in the
 *>          reduction of (A,B) to generalized Hessenberg form.
-*>          On exit, if COMPZ = 'I', the unitary matrix of left Schur
-*>          vectors of (H,T), and if COMPZ = 'V', the unitary matrix of
+*>          On exit, if COMPQ = 'I', the unitary matrix of left Schur
+*>          vectors of (H,T), and if COMPQ = 'V', the unitary matrix of
 *>          left Schur vectors of (A,B).
-*>          Not referenced if COMPZ = 'N'.
+*>          Not referenced if COMPQ = 'N'.
 *> \endverbatim
 *>
 *> \param[in] LDQ
      $                   ALPHA, BETA, Q, LDQ, Z, LDZ, WORK, LWORK,
      $                   RWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     April 2012
index e7bd2c4f4d5c50192ed7dac9bec60b9912286bac..e6bf245e034145932ace35d4545450f1c6cabc23 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is REAL
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is REAL
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup complexOTHEReigen
 *
      $                   ABSTOL, M, W, Z, LDZ, WORK, RWORK, IWORK,
      $                   IFAIL, INFO )
 *
-*  -- LAPACK driver routine (version 3.4.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE, UPLO
index ee100984c7c9d40487fbdc583db8d939507bc744..cc4b296bcde4242fbf3f9e835bd4ee70323666e2 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is REAL
+*>
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is REAL
 *>
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
 *>
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complexOTHEReigen
 *
      $                   IL, IU, ABSTOL, M, W, Z, LDZ, WORK, RWORK,
      $                   IWORK, IFAIL, INFO )
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE, UPLO
index b74156dbc5382ea81afc67bae062b020cdb553d3..074ca90a3331eddc8d9d7384e21a07450c4c4c1e 100644 (file)
 *>
 *> \param[in] AB
 *> \verbatim
-*>          AB is REAL array, dimension (LDAB,n)
+*>          AB is COMPLEX array, dimension (LDAB,n)
 *>           Before entry, the leading m by n part of the array AB must
 *>           contain the matrix of coefficients.
 *>           Unchanged on exit.
 *>
 *> \param[in] X
 *> \verbatim
-*>          X is REAL array, dimension
+*>          X is COMPLEX array, dimension
 *>           ( 1 + ( n - 1 )*abs( INCX ) ) when TRANS = 'N' or 'n'
 *>           and at least
 *>           ( 1 + ( m - 1 )*abs( INCX ) ) otherwise.
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup complexGBcomputational
 *
       SUBROUTINE CLA_GBAMV( TRANS, M, N, KL, KU, ALPHA, AB, LDAB, X,
      $                      INCX, BETA, Y, INCY )
 *
-*  -- LAPACK computational routine (version 3.4.2) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       REAL               ALPHA, BETA
index dc05aedc9cc84578c80e2b65e9aaca75273ba226..9326299c7970fa340f82e500db64a092c9248cfe 100644 (file)
 *>
 *> \param[in] WORK
 *> \verbatim
-*>          WORK is COMPLEX array, dimension (2*N)
+*>          WORK is REAL array, dimension (2*N)
 *> \endverbatim
 *
 *  Authors:
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup complexHEcomputational
 *
       REAL FUNCTION CLA_HERPVGRW( UPLO, N, INFO, A, LDA, AF, LDAF, IPIV,
      $                            WORK )
 *
-*  -- LAPACK computational routine (version 3.4.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER*1        UPLO
index 94db81439dc6ca72580ccf96e32e9fc008f538d0..4ac5abec8fbf142e9e4735166ecbed6b92164f33 100644 (file)
@@ -67,7 +67,7 @@
 *>
 *> \param[in] RES
 *> \verbatim
-*>          RES is REAL array, dimension (N,NRHS)
+*>          RES is COMPLEX array, dimension (N,NRHS)
 *>     The residual matrix, i.e., the matrix R in the relative backward
 *>     error formula above.
 *> \endverbatim
@@ -82,7 +82,7 @@
 *>     
 *> \param[out] BERR
 *> \verbatim
-*>          BERR is COMPLEX array, dimension (NRHS)
+*>          BERR is REAL array, dimension (NRHS)
 *>     The componentwise relative backward error from the formula above.
 *> \endverbatim
 *
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2013
+*> \date June 2016
 *
 *> \ingroup complexOTHERcomputational
 *
 *  =====================================================================
       SUBROUTINE CLA_LIN_BERR ( N, NZ, NRHS, RES, AYB, BERR )
 *
-*  -- LAPACK computational routine (version 3.5.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2013
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            N, NZ, NRHS
index 8e2b98371362490ca1df31084ada68e574a8cf7d..01e07a14889b606c4620b06d86d524b45462f06b 100644 (file)
@@ -38,7 +38,7 @@
 *> \verbatim
 *>
 *>    CLA_PORCOND_C Computes the infinity norm condition number of
-*>    op(A) * inv(diag(C)) where C is a DOUBLE PRECISION vector
+*>    op(A) * inv(diag(C)) where C is a REAL vector
 *> \endverbatim
 *
 *  Arguments:
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup complexPOcomputational
 *
       REAL FUNCTION CLA_PORCOND_C( UPLO, N, A, LDA, AF, LDAF, C, CAPPLY,
      $                             INFO, WORK, RWORK )
 *
-*  -- LAPACK computational routine (version 3.4.2) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          UPLO
index 607752adabb08e4e70d8035de27d2649209bd4c4..d60cfe622af82f3299e07f3c1f1a4fdcdbf839f2 100644 (file)
@@ -87,7 +87,7 @@
 *>
 *> \param[in] WORK
 *> \verbatim
-*>          WORK is COMPLEX array, dimension (2*N)
+*>          WORK is REAL array, dimension (2*N)
 *> \endverbatim
 *
 *  Authors:
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup complexPOcomputational
 *
 *  =====================================================================
       REAL FUNCTION CLA_PORPVGRW( UPLO, NCOLS, A, LDA, AF, LDAF, WORK )
 *
-*  -- LAPACK computational routine (version 3.4.2) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER*1        UPLO
index c1441393cf27c4ca577be2c5812a60fa373eeba8..a42ee681709d8e29ea432bafb8f0276171c8c546 100644 (file)
@@ -57,7 +57,7 @@
 *>
 *>       The first stage consists of deflating the size of the problem
 *>       when there are multiple eigenvalues or if there is a zero in
-*>       the Z vector.  For each such occurence the dimension of the
+*>       the Z vector.  For each such occurrence the dimension of the
 *>       secular equation problem is reduced by one.  This stage is
 *>       performed by the routine SLAED2.
 *>
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup complexOTHERcomputational
 *
      $                   GIVPTR, GIVCOL, GIVNUM, WORK, RWORK, IWORK,
      $                   INFO )
 *
-*  -- LAPACK computational routine (version 3.4.2) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            CURLVL, CURPBM, CUTPNT, INFO, LDQ, N, QSIZ,
index 53e0e3c42f535e41499b651c2921ec51bfbf7b45..f3ee410bad5c7b9868d8148dc4fa1398325b9993 100644 (file)
 *>          Z is COMPLEX array, dimension (LDZ,N)
 *>          IF WANTZ is .TRUE., then on output, the unitary
 *>          similarity transformation mentioned above has been
-*>          accumulated into Z(ILOZ:IHIZ,ILO:IHI) from the right.
+*>          accumulated into Z(ILOZ:IHIZ,ILOZ:IHIZ) from the right.
 *>          If WANTZ is .FALSE., then Z is unreferenced.
 *> \endverbatim
 *>
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup complexOTHERauxiliary
 *
      $                   IHIZ, Z, LDZ, NS, ND, SH, V, LDV, NH, T, LDT,
      $                   NV, WV, LDWV, WORK, LWORK )
 *
-*  -- LAPACK auxiliary routine (version 3.4.2) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            IHIZ, ILOZ, KBOT, KTOP, LDH, LDT, LDV, LDWV,
index fc412c4dad622449eb745fc43ce744483f0648c3..22e55def5f40bf1578bdf40987588025354c373b 100644 (file)
 *>
 *> \param[in,out] Z
 *> \verbatim
-*>          Z is COMPLEX array of size (LDZ,IHI)
+*>          Z is COMPLEX array of size (LDZ,IHIZ)
 *>             If WANTZ = .TRUE., then the QR Sweep unitary
 *>             similarity transformation is accumulated into
-*>             Z(ILOZ:IHIZ,ILO:IHI) from the right.
+*>             Z(ILOZ:IHIZ,ILOZ:IHIZ) from the right.
 *>             If WANTZ = .FALSE., then Z is unreferenced.
 *> \endverbatim
 *>
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup complexOTHERauxiliary
 *
      $                   H, LDH, ILOZ, IHIZ, Z, LDZ, V, LDV, U, LDU, NV,
      $                   WV, LDWV, NH, WH, LDWH )
 *
-*  -- LAPACK auxiliary routine (version 3.4.2) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            IHIZ, ILOZ, KACC22, KBOT, KTOP, LDH, LDU, LDV,
index 30a920437781e56cae50a3cf4000bf201d1507b8..63038ec2da30940ebfb2ed08ec0e4dd5550ba277 100644 (file)
@@ -72,7 +72,7 @@
 *>
 *> \param[in] B
 *> \verbatim
-*>          B is REAL array, dimension (LDB, N)
+*>          B is COMPLEX array, dimension (LDB, N)
 *>          B contains the M by N matrix B.
 *> \endverbatim
 *>
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup complexOTHERauxiliary
 *
 *  =====================================================================
       SUBROUTINE CLARCM( M, N, A, LDA, B, LDB, C, LDC, RWORK )
 *
-*  -- LAPACK auxiliary routine (version 3.4.2) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            LDA, LDB, LDC, M, N
index ecedfa4d24492baa39f1affca18998043d03588d..31f374cb8d9af810f1ff7d603b2441f6f2e8b3ba 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is REAL
+*>          Lower bound of the interval that contains the desired
+*>          eigenvalues. VL < VU. Needed to compute gaps on the left or right
+*>          end of the extremal eigenvalues in the desired RANGE.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is REAL
-*>          Lower and upper bounds of the interval that contains the desired
+*>          Upper bound of the interval that contains the desired
 *>          eigenvalues. VL < VU. Needed to compute gaps on the left or right
 *>          end of the extremal eigenvalues in the desired RANGE.
 *> \endverbatim
@@ -81,7 +84,7 @@
 *>          L is REAL array, dimension (N)
 *>          On entry, the (N-1) subdiagonal elements of the unit
 *>          bidiagonal matrix L are in elements 1 to N-1 of L
-*>          (if the matrix is not splitted.) At the end of each block
+*>          (if the matrix is not split.) At the end of each block
 *>          is stored the corresponding shift as given by SLARRE.
 *>          On exit, L is overwritten.
 *> \endverbatim
 *>          INFO is INTEGER
 *>          = 0:  successful exit
 *>
-*>          > 0:  A problem occured in CLARRV.
+*>          > 0:  A problem occurred in CLARRV.
 *>          < 0:  One of the called subroutines signaled an internal problem.
 *>                Needs inspection of the corresponding parameter IINFO
 *>                for further information.
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complexOTHERauxiliary
 *
      $                   IBLOCK, INDEXW, GERS, Z, LDZ, ISUPPZ,
      $                   WORK, IWORK, INFO )
 *
-*  -- LAPACK auxiliary routine (version 3.6.0) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            DOL, DOU, INFO, LDZ, M, N
index ada9535c338ff4d4a913fe0598e11e4d7a4066be..77876771f8b9664bcd49e58749478f24016aa765 100644 (file)
@@ -73,7 +73,7 @@
 *> \param[in] LDX
 *> \verbatim
 *>          LDX is INTEGER
-*>     The leading dimension of the vector X. LDX >= 0.
+*>     The leading dimension of the vector X. LDX >= M.
 *> \endverbatim
 *
 *  Authors:
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complexOTHERcomputational
 *
 *  =====================================================================
       SUBROUTINE CLARSCL2 ( M, N, D, X, LDX )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            M, N, LDX
index a5ab897ba3845f02f943a87aa8f8415308d44960..776d6cd32fbcdc0949b7807695f41d3fb1375d38 100644 (file)
 *> \param[in] LDA
 *> \verbatim
 *>          LDA is INTEGER
-*>          The leading dimension of the array A.  LDA >= max(1,M).
+*>          The leading dimension of the array A.
+*>          If TYPE = 'G', 'L', 'U', 'H', LDA >= max(1,M);
+*>             TYPE = 'B', LDA >= KL+1;
+*>             TYPE = 'Q', LDA >= KU+1;
+*>             TYPE = 'Z', LDA >= 2*KL+KU+1.
 *> \endverbatim
 *>
 *> \param[out] INFO
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup complexOTHERauxiliary
 *
 *  =====================================================================
       SUBROUTINE CLASCL( TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO )
 *
-*  -- LAPACK auxiliary routine (version 3.4.2) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          TYPE
index f45f85e183b306e7811a921e69efa89935c6e05d..01fbe6980a22d44aee9f91f354f1044c59175549 100644 (file)
@@ -73,7 +73,7 @@
 *> \param[in] LDX
 *> \verbatim
 *>          LDX is INTEGER
-*>     The leading dimension of the vector X. LDX >= 0.
+*>     The leading dimension of the vector X. LDX >= M.
 *> \endverbatim
 *
 *  Authors:
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complexOTHERcomputational
 *
 *  =====================================================================
       SUBROUTINE CLASCL2 ( M, N, D, X, LDX )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            M, N, LDX
index 11f0dfd9b0b207b1d1624e1ca5fcf27c04f5df75..ff56cdeb85e69b01f5c2519a7e3a53ac5287532f 100644 (file)
@@ -58,7 +58,7 @@
 *>              Zx = +-e - f with the sign giving the greater value of
 *>              2-norm(x).  About 5 times as expensive as Default.
 *>          IJOB .ne. 2: Local look ahead strategy where
-*>              all entries of the r.h.s. b is choosen as either +1 or
+*>              all entries of the r.h.s. b is chosen as either +1 or
 *>              -1.  Default.
 *> \endverbatim
 *>
@@ -70,7 +70,7 @@
 *>
 *> \param[in] Z
 *> \verbatim
-*>          Z is REAL array, dimension (LDZ, N)
+*>          Z is COMPLEX array, dimension (LDZ, N)
 *>          On entry, the LU part of the factorization of the n-by-n
 *>          matrix Z computed by CGETC2:  Z = P * L * U * Q
 *> \endverbatim
@@ -83,7 +83,7 @@
 *>
 *> \param[in,out] RHS
 *> \verbatim
-*>          RHS is REAL array, dimension (N).
+*>          RHS is COMPLEX array, dimension (N).
 *>          On entry, RHS contains contributions from other subsystems.
 *>          On exit, RHS contains the solution of the subsystem with
 *>          entries according to the value of IJOB (see above).
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup complexOTHERauxiliary
 *
       SUBROUTINE CLATDF( IJOB, N, Z, LDZ, RHS, RDSUM, RDSCAL, IPIV,
      $                   JPIV )
 *
-*  -- LAPACK auxiliary routine (version 3.4.2) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            IJOB, LDZ, N
index 6ab06a637de9cb1053673254f4734338fe78ba2b..dfd06fa9ed45156961901756cff1ebced244632e 100644 (file)
@@ -62,7 +62,7 @@
 *>
 *> \param[in,out] A
 *> \verbatim
-*>          A is DOUBLE PRECISION array, dimension (LDA,N)
+*>          A is COMPLEX array, dimension (LDA,N)
 *>          On entry, the symmetric matrix A.  If UPLO = 'U', the leading
 *>          N-by-N upper triangular part of A contains the upper
 *>          triangular part of the matrix A, and the strictly lower
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complexPOcomputational
 *
 *  =====================================================================
       RECURSIVE SUBROUTINE CPOTRF2( UPLO, N, A, LDA, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          UPLO
index 4214dd11deec3c48d02f022d53a998501e870889..68f650e029e9b1119d8dccce24f8ad9686ed4a08 100644 (file)
@@ -87,7 +87,7 @@
 *>
 *> \param[in,out] B
 *> \verbatim
-*>          B is REAL array, dimension (LDB,NRHS)
+*>          B is COMPLEX array, dimension (LDB,NRHS)
 *>          On entry, the right hand side vectors B for the system of
 *>          linear equations.
 *>          On exit, the solution vectors, X.
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup complexPTcomputational
 *
 *  =====================================================================
       SUBROUTINE CPTTRS( UPLO, N, NRHS, D, E, B, LDB, INFO )
 *
-*  -- LAPACK computational routine (version 3.4.2) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          UPLO
index 379ca4956de5079ef57f3f88f5da525f08775cce..c545b8fec504c86d07bd4b49f75baf1c4bee4f4c 100644 (file)
@@ -86,7 +86,7 @@
 *>
 *> \param[in,out] B
 *> \verbatim
-*>          B is REAL array, dimension (LDB,NRHS)
+*>          B is COMPLEX array, dimension (LDB,NRHS)
 *>          On entry, the right hand side vectors B for the system of
 *>          linear equations.
 *>          On exit, the solution vectors, X.
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup complexPTcomputational
 *
 *  =====================================================================
       SUBROUTINE CPTTS2( IUPLO, N, NRHS, D, E, B, LDB )
 *
-*  -- LAPACK computational routine (version 3.4.2) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            IUPLO, LDB, N, NRHS
index 6e1eae055306ff56acff02aec2a758068592bca4..aaecf36dd2142838f367499fb774d24d0f389160 100644 (file)
@@ -48,7 +48,7 @@
 *> either an interval (VL,VU] or a range of indices IL:IU for the desired
 *> eigenvalues.
 *>
-*> CSTEGR is a compatability wrapper around the improved CSTEMR routine.
+*> CSTEGR is a compatibility wrapper around the improved CSTEMR routine.
 *> See SSTEMR for further details.
 *>
 *> One important change is that the ABSTOL parameter no longer provides any
 *> \param[in] VL
 *> \verbatim
 *>          VL is REAL
+*>
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is REAL
 *>
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
 *>
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup complexOTHERcomputational
 *
      $           ABSTOL, M, W, Z, LDZ, ISUPPZ, WORK, LWORK, IWORK,
      $           LIWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.4.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE
index 29734964b5d8b1daacbb1f0f9f377fc7c791c2ff..90f050ad74a03fb372f6b8eef37791c9a945833d 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is REAL
+*>
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is REAL
 *>
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
 *>
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complexOTHERcomputational
 *
      $                   M, W, Z, LDZ, NZC, ISUPPZ, TRYRAC, WORK, LWORK,
      $                   IWORK, LIWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE
index fab048162c272e1756a22de4d5010ae6c75b66e1..139569f9b89a0492d33d91e74b72cfa5961af24f 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complexSYcomputational
 *
 *>
 *> \verbatim
 *>
-*>   November 2015, Igor Kozachenko,
+*>   June 2016, Igor Kozachenko,
 *>                  Computer Science Division,
 *>                  University of California, Berkeley
 *>
 *  =====================================================================
       SUBROUTINE CSYTRF_ROOK( UPLO, N, A, LDA, IPIV, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          UPLO
 *        Determine the block size
 *
          NB = ILAENV( 1, 'CSYTRF_ROOK', UPLO, N, -1, -1, -1 )
-         LWKOPT = N*NB
+         LWKOPT = MAX( 1, N*NB )
          WORK( 1 ) = LWKOPT
       END IF
 *
index d2ba8de8a64fd695e72e7c298fb7d75c0a905694..3de430bf1d00d0cacb94f1b153102500e594b083 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup complexOTHERcomputational
 *
      $                   ALPHA, BETA, Q, LDQ, Z, LDZ, M, PL, PR, DIF,
      $                   WORK, LWORK, IWORK, LIWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.4.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       LOGICAL            WANTQ, WANTZ
 *     subspaces.
 *
       M = 0
+      IF( .NOT.LQUERY .OR. IJOB.NE.0 ) THEN
       DO 10 K = 1, N
          ALPHA( K ) = A( K, K )
          BETA( K ) = B( K, K )
      $         M = M + 1
          END IF
    10 CONTINUE
+      END IF
 *
       IF( IJOB.EQ.1 .OR. IJOB.EQ.2 .OR. IJOB.EQ.4 ) THEN
          LWMIN = MAX( 1, 2*M*(N-M) )
diff --git a/lapack-netlib/SRC/ctrevc3.f b/lapack-netlib/SRC/ctrevc3.f
new file mode 100644 (file)
index 0000000..00d3b94
--- /dev/null
@@ -0,0 +1,630 @@
+*> \brief \b CTREVC3
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at 
+*            http://www.netlib.org/lapack/explore-html/ 
+*
+*> \htmlonly
+*> Download CTREVC3 + dependencies 
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ctrevc3.f"> 
+*> [TGZ]</a> 
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ctrevc3.f"> 
+*> [ZIP]</a> 
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ctrevc3.f"> 
+*> [TXT]</a>
+*> \endhtmlonly 
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CTREVC3( SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL,
+*                           VR, LDVR, MM, M, WORK, LWORK, RWORK, INFO )
+*
+*       .. Scalar Arguments ..
+*       CHARACTER          HOWMNY, SIDE
+*       INTEGER            INFO, LDT, LDVL, LDVR, LWORK, M, MM, N
+*       ..
+*       .. Array Arguments ..
+*       LOGICAL            SELECT( * )
+*       REAL   RWORK( * )
+*       COMPLEX         T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ),
+*      $                   WORK( * )
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> CTREVC3 computes some or all of the right and/or left eigenvectors of
+*> a complex upper triangular matrix T.
+*> Matrices of this type are produced by the Schur factorization of
+*> a complex general matrix:  A = Q*T*Q**H, as computed by CHSEQR.
+*>
+*> The right eigenvector x and the left eigenvector y of T corresponding
+*> to an eigenvalue w are defined by:
+*>
+*>              T*x = w*x,     (y**H)*T = w*(y**H)
+*>
+*> where y**H denotes the conjugate transpose of the vector y.
+*> The eigenvalues are not input to this routine, but are read directly
+*> from the diagonal of T.
+*>
+*> This routine returns the matrices X and/or Y of right and left
+*> eigenvectors of T, or the products Q*X and/or Q*Y, where Q is an
+*> input matrix. If Q is the unitary factor that reduces a matrix A to
+*> Schur form T, then Q*X and Q*Y are the matrices of right and left
+*> eigenvectors of A.
+*>
+*> This uses a Level 3 BLAS version of the back transformation.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] SIDE
+*> \verbatim
+*>          SIDE is CHARACTER*1
+*>          = 'R':  compute right eigenvectors only;
+*>          = 'L':  compute left eigenvectors only;
+*>          = 'B':  compute both right and left eigenvectors.
+*> \endverbatim
+*>
+*> \param[in] HOWMNY
+*> \verbatim
+*>          HOWMNY is CHARACTER*1
+*>          = 'A':  compute all right and/or left eigenvectors;
+*>          = 'B':  compute all right and/or left eigenvectors,
+*>                  backtransformed using the matrices supplied in
+*>                  VR and/or VL;
+*>          = 'S':  compute selected right and/or left eigenvectors,
+*>                  as indicated by the logical array SELECT.
+*> \endverbatim
+*>
+*> \param[in] SELECT
+*> \verbatim
+*>          SELECT is LOGICAL array, dimension (N)
+*>          If HOWMNY = 'S', SELECT specifies the eigenvectors to be
+*>          computed.
+*>          The eigenvector corresponding to the j-th eigenvalue is
+*>          computed if SELECT(j) = .TRUE..
+*>          Not referenced if HOWMNY = 'A' or 'B'.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>          The order of the matrix T. N >= 0.
+*> \endverbatim
+*>
+*> \param[in,out] T
+*> \verbatim
+*>          T is COMPLEX array, dimension (LDT,N)
+*>          The upper triangular matrix T.  T is modified, but restored
+*>          on exit.
+*> \endverbatim
+*>
+*> \param[in] LDT
+*> \verbatim
+*>          LDT is INTEGER
+*>          The leading dimension of the array T. LDT >= max(1,N).
+*> \endverbatim
+*>
+*> \param[in,out] VL
+*> \verbatim
+*>          VL is COMPLEX array, dimension (LDVL,MM)
+*>          On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL must
+*>          contain an N-by-N matrix Q (usually the unitary matrix Q of
+*>          Schur vectors returned by CHSEQR).
+*>          On exit, if SIDE = 'L' or 'B', VL contains:
+*>          if HOWMNY = 'A', the matrix Y of left eigenvectors of T;
+*>          if HOWMNY = 'B', the matrix Q*Y;
+*>          if HOWMNY = 'S', the left eigenvectors of T specified by
+*>                           SELECT, stored consecutively in the columns
+*>                           of VL, in the same order as their
+*>                           eigenvalues.
+*>          Not referenced if SIDE = 'R'.
+*> \endverbatim
+*>
+*> \param[in] LDVL
+*> \verbatim
+*>          LDVL is INTEGER
+*>          The leading dimension of the array VL.
+*>          LDVL >= 1, and if SIDE = 'L' or 'B', LDVL >= N.
+*> \endverbatim
+*>
+*> \param[in,out] VR
+*> \verbatim
+*>          VR is COMPLEX array, dimension (LDVR,MM)
+*>          On entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', VR must
+*>          contain an N-by-N matrix Q (usually the unitary matrix Q of
+*>          Schur vectors returned by CHSEQR).
+*>          On exit, if SIDE = 'R' or 'B', VR contains:
+*>          if HOWMNY = 'A', the matrix X of right eigenvectors of T;
+*>          if HOWMNY = 'B', the matrix Q*X;
+*>          if HOWMNY = 'S', the right eigenvectors of T specified by
+*>                           SELECT, stored consecutively in the columns
+*>                           of VR, in the same order as their
+*>                           eigenvalues.
+*>          Not referenced if SIDE = 'L'.
+*> \endverbatim
+*>
+*> \param[in] LDVR
+*> \verbatim
+*>          LDVR is INTEGER
+*>          The leading dimension of the array VR.
+*>          LDVR >= 1, and if SIDE = 'R' or 'B', LDVR >= N.
+*> \endverbatim
+*>
+*> \param[in] MM
+*> \verbatim
+*>          MM is INTEGER
+*>          The number of columns in the arrays VL and/or VR. MM >= M.
+*> \endverbatim
+*>
+*> \param[out] M
+*> \verbatim
+*>          M is INTEGER
+*>          The number of columns in the arrays VL and/or VR actually
+*>          used to store the eigenvectors.
+*>          If HOWMNY = 'A' or 'B', M is set to N.
+*>          Each selected eigenvector occupies one column.
+*> \endverbatim
+*>
+*> \param[out] WORK
+*> \verbatim
+*>          WORK is COMPLEX array, dimension (MAX(1,LWORK))
+*> \endverbatim
+*>
+*> \param[in] LWORK
+*> \verbatim
+*>          LWORK is INTEGER
+*>          The dimension of array WORK. LWORK >= max(1,2*N).
+*>          For optimum performance, LWORK >= N + 2*N*NB, where NB is
+*>          the optimal blocksize.
+*>
+*>          If LWORK = -1, then a workspace query is assumed; the routine
+*>          only calculates the optimal size of the WORK array, returns
+*>          this value as the first entry of the WORK array, and no error
+*>          message related to LWORK is issued by XERBLA.
+*> \endverbatim
+*>
+*> \param[out] RWORK
+*> \verbatim
+*>          RWORK is REAL array, dimension (LRWORK)
+*> \endverbatim
+*>
+*> \param[in] LRWORK
+*> \verbatim
+*>          LRWORK is INTEGER
+*>          The dimension of array RWORK. LRWORK >= max(1,N).
+*>
+*>          If LRWORK = -1, then a workspace query is assumed; the routine
+*>          only calculates the optimal size of the RWORK array, returns
+*>          this value as the first entry of the RWORK array, and no error
+*>          message related to LRWORK is issued by XERBLA.
+*> \endverbatim
+*>
+*> \param[out] INFO
+*> \verbatim
+*>          INFO is INTEGER
+*>          = 0:  successful exit
+*>          < 0:  if INFO = -i, the i-th argument had an illegal value
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date November 2011
+*
+*  @generated from ztrevc3.f, fortran z -> c, Tue Apr 19 01:47:44 2016
+*
+*> \ingroup complexOTHERcomputational
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  The algorithm used in this program is basically backward (forward)
+*>  substitution, with scaling to make the the code robust against
+*>  possible overflow.
+*>
+*>  Each eigenvector is normalized so that the element of largest
+*>  magnitude has magnitude 1; here the magnitude of a complex number
+*>  (x,y) is taken to be |x| + |y|.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CTREVC3( SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR,
+     $                    LDVR, MM, M, WORK, LWORK, RWORK, LRWORK, INFO)
+      IMPLICIT NONE
+*
+*  -- LAPACK computational routine (version 3.4.0) --
+*  -- LAPACK is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     November 2011
+*
+*     .. Scalar Arguments ..
+      CHARACTER          HOWMNY, SIDE
+      INTEGER            INFO, LDT, LDVL, LDVR, LWORK, LRWORK, M, MM, N
+*     ..
+*     .. Array Arguments ..
+      LOGICAL            SELECT( * )
+      REAL   RWORK( * )
+      COMPLEX         T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ),
+     $                   WORK( * )
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+      COMPLEX         CZERO, CONE
+      PARAMETER          ( CZERO = ( 0.0E+0, 0.0E+0 ),
+     $                     CONE  = ( 1.0E+0, 0.0E+0 ) )
+      INTEGER            NBMIN, NBMAX
+      PARAMETER          ( NBMIN = 8, NBMAX = 128 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            ALLV, BOTHV, LEFTV, LQUERY, OVER, RIGHTV, SOMEV
+      INTEGER            I, II, IS, J, K, KI, IV, MAXWRK, NB
+      REAL   OVFL, REMAX, SCALE, SMIN, SMLNUM, ULP, UNFL
+      COMPLEX         CDUM
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV, ICAMAX
+      REAL   SLAMCH, SCASUM
+      EXTERNAL           LSAME, ILAENV, ICAMAX, SLAMCH, SCASUM
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, CCOPY, CSSCAL, CGEMV, CLATRS
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, REAL, CMPLX, CONJG, AIMAG, MAX
+*     ..
+*     .. Statement Functions ..
+      REAL   CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( CDUM ) = ABS( REAL( CDUM ) ) + ABS( AIMAG( CDUM ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode and test the input parameters
+*
+      BOTHV  = LSAME( SIDE, 'B' )
+      RIGHTV = LSAME( SIDE, 'R' ) .OR. BOTHV
+      LEFTV  = LSAME( SIDE, 'L' ) .OR. BOTHV
+*
+      ALLV  = LSAME( HOWMNY, 'A' )
+      OVER  = LSAME( HOWMNY, 'B' )
+      SOMEV = LSAME( HOWMNY, 'S' )
+*
+*     Set M to the number of columns required to store the selected
+*     eigenvectors.
+*
+      IF( SOMEV ) THEN
+         M = 0
+         DO 10 J = 1, N
+            IF( SELECT( J ) )
+     $         M = M + 1
+   10    CONTINUE
+      ELSE
+         M = N
+      END IF
+*
+      INFO = 0
+      NB = ILAENV( 1, 'CTREVC', SIDE // HOWMNY, N, -1, -1, -1 )
+      MAXWRK = N + 2*N*NB
+      WORK(1) = MAXWRK
+      RWORK(1) = N
+      LQUERY = ( LWORK.EQ.-1 .OR. LRWORK.EQ.-1 )
+      IF( .NOT.RIGHTV .AND. .NOT.LEFTV ) THEN
+         INFO = -1
+      ELSE IF( .NOT.ALLV .AND. .NOT.OVER .AND. .NOT.SOMEV ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDT.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      ELSE IF( LDVL.LT.1 .OR. ( LEFTV .AND. LDVL.LT.N ) ) THEN
+         INFO = -8
+      ELSE IF( LDVR.LT.1 .OR. ( RIGHTV .AND. LDVR.LT.N ) ) THEN
+         INFO = -10
+      ELSE IF( MM.LT.M ) THEN
+         INFO = -11
+      ELSE IF( LWORK.LT.MAX( 1, 2*N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -14
+      ELSE IF ( LRWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -16
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'CTREVC3', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Use blocked version of back-transformation if sufficient workspace.
+*     Zero-out the workspace to avoid potential NaN propagation.
+*
+      IF( OVER .AND. LWORK .GE. N + 2*N*NBMIN ) THEN
+         NB = (LWORK - N) / (2*N)
+         NB = MIN( NB, NBMAX )
+         CALL CLASET( 'F', N, 1+2*NB, CZERO, CZERO, WORK, N )
+      ELSE
+         NB = 1
+      END IF
+*
+*     Set the constants to control overflow.
+*
+      UNFL = SLAMCH( 'Safe minimum' )
+      OVFL = ONE / UNFL
+      CALL SLABAD( UNFL, OVFL )
+      ULP = SLAMCH( 'Precision' )
+      SMLNUM = UNFL*( N / ULP )
+*
+*     Store the diagonal elements of T in working array WORK.
+*
+      DO 20 I = 1, N
+         WORK( I ) = T( I, I )
+   20 CONTINUE
+*
+*     Compute 1-norm of each column of strictly upper triangular
+*     part of T to control overflow in triangular solver.
+*
+      RWORK( 1 ) = ZERO
+      DO 30 J = 2, N
+         RWORK( J ) = SCASUM( J-1, T( 1, J ), 1 )
+   30 CONTINUE
+*
+      IF( RIGHTV ) THEN
+*
+*        ============================================================
+*        Compute right eigenvectors.
+*
+*        IV is index of column in current block.
+*        Non-blocked version always uses IV=NB=1;
+*        blocked     version starts with IV=NB, goes down to 1.
+*        (Note the "0-th" column is used to store the original diagonal.)
+         IV = NB
+         IS = M
+         DO 80 KI = N, 1, -1
+            IF( SOMEV ) THEN
+               IF( .NOT.SELECT( KI ) )
+     $            GO TO 80
+            END IF
+            SMIN = MAX( ULP*( CABS1( T( KI, KI ) ) ), SMLNUM )
+*
+*           --------------------------------------------------------
+*           Complex right eigenvector
+*
+            WORK( KI + IV*N ) = CONE
+*
+*           Form right-hand side.
+*
+            DO 40 K = 1, KI - 1
+               WORK( K + IV*N ) = -T( K, KI )
+   40       CONTINUE
+*
+*           Solve upper triangular system:
+*           [ T(1:KI-1,1:KI-1) - T(KI,KI) ]*X = SCALE*WORK.
+*
+            DO 50 K = 1, KI - 1
+               T( K, K ) = T( K, K ) - T( KI, KI )
+               IF( CABS1( T( K, K ) ).LT.SMIN )
+     $            T( K, K ) = SMIN
+   50       CONTINUE
+*
+            IF( KI.GT.1 ) THEN
+               CALL CLATRS( 'Upper', 'No transpose', 'Non-unit', 'Y',
+     $                      KI-1, T, LDT, WORK( 1 + IV*N ), SCALE,
+     $                      RWORK, INFO )
+               WORK( KI + IV*N ) = SCALE
+            END IF
+*
+*           Copy the vector x or Q*x to VR and normalize.
+*
+            IF( .NOT.OVER ) THEN
+*              ------------------------------
+*              no back-transform: copy x to VR and normalize.
+               CALL CCOPY( KI, WORK( 1 + IV*N ), 1, VR( 1, IS ), 1 )
+*
+               II = ICAMAX( KI, VR( 1, IS ), 1 )
+               REMAX = ONE / CABS1( VR( II, IS ) )
+               CALL CSSCAL( KI, REMAX, VR( 1, IS ), 1 )
+*
+               DO 60 K = KI + 1, N
+                  VR( K, IS ) = CZERO
+   60          CONTINUE
+*
+            ELSE IF( NB.EQ.1 ) THEN
+*              ------------------------------
+*              version 1: back-transform each vector with GEMV, Q*x.
+               IF( KI.GT.1 )
+     $            CALL CGEMV( 'N', N, KI-1, CONE, VR, LDVR,
+     $                        WORK( 1 + IV*N ), 1, CMPLX( SCALE ),
+     $                        VR( 1, KI ), 1 )
+*
+               II = ICAMAX( N, VR( 1, KI ), 1 )
+               REMAX = ONE / CABS1( VR( II, KI ) )
+               CALL CSSCAL( N, REMAX, VR( 1, KI ), 1 )
+*
+            ELSE
+*              ------------------------------
+*              version 2: back-transform block of vectors with GEMM
+*              zero out below vector
+               DO K = KI + 1, N
+                  WORK( K + IV*N ) = CZERO
+               END DO
+*
+*              Columns IV:NB of work are valid vectors.
+*              When the number of vectors stored reaches NB,
+*              or if this was last vector, do the GEMM
+               IF( (IV.EQ.1) .OR. (KI.EQ.1) ) THEN
+                  CALL CGEMM( 'N', 'N', N, NB-IV+1, KI+NB-IV, CONE,
+     $                        VR, LDVR,
+     $                        WORK( 1 + (IV)*N    ), N,
+     $                        CZERO,
+     $                        WORK( 1 + (NB+IV)*N ), N )
+*                 normalize vectors
+                  DO K = IV, NB
+                     II = ICAMAX( N, WORK( 1 + (NB+K)*N ), 1 )
+                     REMAX = ONE / CABS1( WORK( II + (NB+K)*N ) )
+                     CALL CSSCAL( N, REMAX, WORK( 1 + (NB+K)*N ), 1 )
+                  END DO
+                  CALL CLACPY( 'F', N, NB-IV+1,
+     $                         WORK( 1 + (NB+IV)*N ), N,
+     $                         VR( 1, KI ), LDVR )
+                  IV = NB
+               ELSE
+                  IV = IV - 1
+               END IF
+            END IF
+*
+*           Restore the original diagonal elements of T.
+*
+            DO 70 K = 1, KI - 1
+               T( K, K ) = WORK( K )
+   70       CONTINUE
+*
+            IS = IS - 1
+   80    CONTINUE
+      END IF
+*
+      IF( LEFTV ) THEN
+*
+*        ============================================================
+*        Compute left eigenvectors.
+*
+*        IV is index of column in current block.
+*        Non-blocked version always uses IV=1;
+*        blocked     version starts with IV=1, goes up to NB.
+*        (Note the "0-th" column is used to store the original diagonal.)
+         IV = 1
+         IS = 1
+         DO 130 KI = 1, N
+*
+            IF( SOMEV ) THEN
+               IF( .NOT.SELECT( KI ) )
+     $            GO TO 130
+            END IF
+            SMIN = MAX( ULP*( CABS1( T( KI, KI ) ) ), SMLNUM )
+*
+*           --------------------------------------------------------
+*           Complex left eigenvector
+*
+            WORK( KI + IV*N ) = CONE
+*
+*           Form right-hand side.
+*
+            DO 90 K = KI + 1, N
+               WORK( K + IV*N ) = -CONJG( T( KI, K ) )
+   90       CONTINUE
+*
+*           Solve conjugate-transposed triangular system:
+*           [ T(KI+1:N,KI+1:N) - T(KI,KI) ]**H * X = SCALE*WORK.
+*
+            DO 100 K = KI + 1, N
+               T( K, K ) = T( K, K ) - T( KI, KI )
+               IF( CABS1( T( K, K ) ).LT.SMIN )
+     $            T( K, K ) = SMIN
+  100       CONTINUE
+*
+            IF( KI.LT.N ) THEN
+               CALL CLATRS( 'Upper', 'Conjugate transpose', 'Non-unit',
+     $                      'Y', N-KI, T( KI+1, KI+1 ), LDT,
+     $                      WORK( KI+1 + IV*N ), SCALE, RWORK, INFO )
+               WORK( KI + IV*N ) = SCALE
+            END IF
+*
+*           Copy the vector x or Q*x to VL and normalize.
+*
+            IF( .NOT.OVER ) THEN
+*              ------------------------------
+*              no back-transform: copy x to VL and normalize.
+               CALL CCOPY( N-KI+1, WORK( KI + IV*N ), 1, VL(KI,IS), 1 )
+*
+               II = ICAMAX( N-KI+1, VL( KI, IS ), 1 ) + KI - 1
+               REMAX = ONE / CABS1( VL( II, IS ) )
+               CALL CSSCAL( N-KI+1, REMAX, VL( KI, IS ), 1 )
+*
+               DO 110 K = 1, KI - 1
+                  VL( K, IS ) = CZERO
+  110          CONTINUE
+*
+            ELSE IF( NB.EQ.1 ) THEN
+*              ------------------------------
+*              version 1: back-transform each vector with GEMV, Q*x.
+               IF( KI.LT.N )
+     $            CALL CGEMV( 'N', N, N-KI, CONE, VL( 1, KI+1 ), LDVL,
+     $                        WORK( KI+1 + IV*N ), 1, CMPLX( SCALE ),
+     $                        VL( 1, KI ), 1 )
+*
+               II = ICAMAX( N, VL( 1, KI ), 1 )
+               REMAX = ONE / CABS1( VL( II, KI ) )
+               CALL CSSCAL( N, REMAX, VL( 1, KI ), 1 )
+*
+            ELSE
+*              ------------------------------
+*              version 2: back-transform block of vectors with GEMM
+*              zero out above vector
+*              could go from KI-NV+1 to KI-1
+               DO K = 1, KI - 1
+                  WORK( K + IV*N ) = CZERO
+               END DO
+*
+*              Columns 1:IV of work are valid vectors.
+*              When the number of vectors stored reaches NB,
+*              or if this was last vector, do the GEMM
+               IF( (IV.EQ.NB) .OR. (KI.EQ.N) ) THEN
+                  CALL CGEMM( 'N', 'N', N, IV, N-KI+IV, ONE,
+     $                        VL( 1, KI-IV+1 ), LDVL,
+     $                        WORK( KI-IV+1 + (1)*N ), N,
+     $                        CZERO,
+     $                        WORK( 1 + (NB+1)*N ), N )
+*                 normalize vectors
+                  DO K = 1, IV
+                     II = ICAMAX( N, WORK( 1 + (NB+K)*N ), 1 )
+                     REMAX = ONE / CABS1( WORK( II + (NB+K)*N ) )
+                     CALL CSSCAL( N, REMAX, WORK( 1 + (NB+K)*N ), 1 )
+                  END DO
+                  CALL CLACPY( 'F', N, IV,
+     $                         WORK( 1 + (NB+1)*N ), N,
+     $                         VL( 1, KI-IV+1 ), LDVL )
+                  IV = 1
+               ELSE
+                  IV = IV + 1
+               END IF
+            END IF
+*
+*           Restore the original diagonal elements of T.
+*
+            DO 120 K = KI + 1, N
+               T( K, K ) = WORK( K )
+  120       CONTINUE
+*
+            IS = IS + 1
+  130    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of CTREVC3
+*
+      END
index b1086b6fe1e3eed6c668691f577e488c09eb6cbd..95a24ea68208feef7f1ae1b29f3328c7ff3746e2 100644 (file)
@@ -81,7 +81,7 @@
 *>
 *> \param[out] ARF
 *> \verbatim
-*>          ARF is COMPLEX*16 array, dimension ( N*(N+1)/2 ),
+*>          ARF is COMPLEX array, dimension ( N*(N+1)/2 ),
 *>          On exit, the upper or lower triangular matrix A stored in
 *>          RFP format. For a further discussion see Notes below.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup complexOTHERcomputational
 *
 *  =====================================================================
       SUBROUTINE CTRTTF( TRANSR, UPLO, N, A, LDA, ARF, INFO )
 *
-*  -- LAPACK computational routine (version 3.4.2) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          TRANSR, UPLO
index fea26b21a84a2e361c0c837da8f98a36b3a91b0c..7d36547da92918d27fb7f2bc47f1dc83ebe8133c 100644 (file)
       SUBROUTINE CUNBDB1( M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI,
      $                    TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.5.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     July 2012
             CALL CLARF( 'R', M-P-I, Q-I, X21(I,I+1), LDX21, TAUQ1(I),
      $                  X21(I+1,I+1), LDX21, WORK(ILARF) )
             CALL CLACGV( Q-I, X21(I,I+1), LDX21 )
-            C = SQRT( SCNRM2( P-I, X11(I+1,I+1), 1, X11(I+1,I+1),
-     $          1 )**2 + SCNRM2( M-P-I, X21(I+1,I+1), 1, X21(I+1,I+1),
-     $          1 )**2 )
+            C = SQRT( SCNRM2( P-I, X11(I+1,I+1), 1 )**2 
+     $              + SCNRM2( M-P-I, X21(I+1,I+1), 1 )**2 )
             PHI(I) = ATAN2( S, C )
             CALL CUNBDB5( P-I, M-P-I, Q-I-1, X11(I+1,I+1), 1,
      $                    X21(I+1,I+1), 1, X11(I+1,I+2), LDX11,
index cec00f93cd7ce2cbc36123023af13318591bea5b..6571befdeec0ee3c7581c31bd6cb63b8663714ef 100644 (file)
       SUBROUTINE CUNBDB2( M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI,
      $                    TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.4.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     July 2012
          CALL CLARF( 'R', M-P-I+1, Q-I+1, X11(I,I), LDX11, TAUQ1(I),
      $               X21(I,I), LDX21, WORK(ILARF) )
          CALL CLACGV( Q-I+1, X11(I,I), LDX11 )
-         S = SQRT( SCNRM2( P-I, X11(I+1,I), 1, X11(I+1,I),
-     $       1 )**2 + SCNRM2( M-P-I+1, X21(I,I), 1, X21(I,I), 1 )**2 )
+         S = SQRT( SCNRM2( P-I, X11(I+1,I), 1 )**2
+     $           + SCNRM2( M-P-I+1, X21(I,I), 1 )**2 )
          THETA(I) = ATAN2( S, C )
 *
          CALL CUNBDB5( P-I, M-P-I+1, Q-I, X11(I+1,I), 1, X21(I,I), 1,
index 5451ef0031c0418fdc2ab9b410e346275ce8459e..05eab91bec2f24d40f6a43179b29c230dc5faa1b 100644 (file)
       SUBROUTINE CUNBDB3( M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI,
      $                    TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.5.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     July 2012
          CALL CLARF( 'R', M-P-I, Q-I+1, X21(I,I), LDX21, TAUQ1(I),
      $               X21(I+1,I), LDX21, WORK(ILARF) )
          CALL CLACGV( Q-I+1, X21(I,I), LDX21 )
-         C = SQRT( SCNRM2( P-I+1, X11(I,I), 1, X11(I,I),
-     $       1 )**2 + SCNRM2( M-P-I, X21(I+1,I), 1, X21(I+1,I), 1 )**2 )
+         C = SQRT( SCNRM2( P-I+1, X11(I,I), 1 )**2
+     $           + SCNRM2( M-P-I, X21(I+1,I), 1 )**2 )
          THETA(I) = ATAN2( S, C )
 *
          CALL CUNBDB5( P-I+1, M-P-I, Q-I, X11(I,I), 1, X21(I+1,I), 1,
index bc948a30f5d34e1a81adaa681fc92d296839c988..ce3a86605594ab97399a09063d4e711800fde40f 100644 (file)
      $                    TAUP1, TAUP2, TAUQ1, PHANTOM, WORK, LWORK,
      $                    INFO )
 *
-*  -- LAPACK computational routine (version 3.4.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     July 2012
      $               X21(I+1,I), LDX21, WORK(ILARF) )
          CALL CLACGV( Q-I+1, X21(I,I), LDX21 )
          IF( I .LT. M-Q ) THEN
-            S = SQRT( SCNRM2( P-I, X11(I+1,I), 1, X11(I+1,I),
-     $          1 )**2 + SCNRM2( M-P-I, X21(I+1,I), 1, X21(I+1,I),
-     $          1 )**2 )
+            S = SQRT( SCNRM2( P-I, X11(I+1,I), 1 )**2
+     $              + SCNRM2( M-P-I, X21(I+1,I), 1 )**2 )
             PHI(I) = ATAN2( S, C )
          END IF
 *
index ca3922da4a038e0cdf26cd0220d539f2566971bb..09c9b305ad9d4010192feb37c98916283d8e425e 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2013
+*> \date June 2016
 *
 *> \ingroup complexOTHERcomputational
 *
      $                             LDV2T, WORK, LWORK, RWORK, LRWORK,
      $                             IWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.5.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2013
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBU1, JOBU2, JOBV1T, JOBV2T, SIGNS, TRANS
       EXTERNAL           LSAME
 *     ..
 *     .. Intrinsic Functions
-      INTRINSIC          COS, INT, MAX, MIN, SIN
+      INTRINSIC          INT, MAX, MIN
 *     ..
 *     .. Executable Statements ..
 *
          ITAUQ1 = ITAUP2 + MAX( 1, M - P )
          ITAUQ2 = ITAUQ1 + MAX( 1, Q )
          IORGQR = ITAUQ2 + MAX( 1, M - Q )
-         CALL CUNGQR( M-Q, M-Q, M-Q, 0, MAX(1,M-Q), U1, WORK, -1,
+         CALL CUNGQR( M-Q, M-Q, M-Q, U1, MAX(1,M-Q), U1, WORK, -1,
      $                CHILDINFO )
          LORGQRWORKOPT = INT( WORK(1) )
          LORGQRWORKMIN = MAX( 1, M - Q )
          IORGLQ = ITAUQ2 + MAX( 1, M - Q )
-         CALL CUNGLQ( M-Q, M-Q, M-Q, 0, MAX(1,M-Q), U1, WORK, -1,
+         CALL CUNGLQ( M-Q, M-Q, M-Q, U1, MAX(1,M-Q), U1, WORK, -1,
      $                CHILDINFO )
          LORGLQWORKOPT = INT( WORK(1) )
          LORGLQWORKMIN = MAX( 1, M - Q )
index 1b2b0fb2accbefc6c46e2047ef77eb075ccb9f00..54b774b88491baecbad78988d8ef1c78fa5311d0 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date July 2012
+*> \date June 2016
 *
 *> \ingroup complexOTHERcomputational
 *
      $                       LDV1T, WORK, LWORK, RWORK, LRWORK, IWORK,
      $                       INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     July 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBU1, JOBU2, JOBV1T
      $                   LWORKMIN, LWORKOPT, R
       LOGICAL            LQUERY, WANTU1, WANTU2, WANTV1T
 *     ..
+*     .. Local Arrays ..
+      REAL               DUM( 1 )
+      COMPLEX            CDUM( 1, 1 )
+*     ..
 *     .. External Subroutines ..
       EXTERNAL           CBBCSD, CCOPY, CLACPY, CLAPMR, CLAPMT, CUNBDB1,
      $                   CUNBDB2, CUNBDB3, CUNBDB4, CUNGLQ, CUNGQR,
          INFO = -8
       ELSE IF( LDX21 .LT. MAX( 1, M-P ) ) THEN
          INFO = -10
-      ELSE IF( WANTU1 .AND. LDU1 .LT. P ) THEN
+      ELSE IF( WANTU1 .AND. LDU1 .LT. MAX( 1, P ) ) THEN
          INFO = -13
-      ELSE IF( WANTU2 .AND. LDU2 .LT. M - P ) THEN
+      ELSE IF( WANTU2 .AND. LDU2 .LT. MAX( 1, M - P ) ) THEN
          INFO = -15
-      ELSE IF( WANTV1T .AND. LDV1T .LT. Q ) THEN
+      ELSE IF( WANTV1T .AND. LDV1T .LT. MAX( 1, Q ) ) THEN
          INFO = -17
       END IF
 *
          IORBDB = ITAUQ1 + MAX( 1, Q )
          IORGQR = ITAUQ1 + MAX( 1, Q )
          IORGLQ = ITAUQ1 + MAX( 1, Q )
+         LORGQRMIN = 1
+         LORGQROPT = 1
+         LORGLQMIN = 1
+         LORGLQOPT = 1
          IF( R .EQ. Q ) THEN
-            CALL CUNBDB1( M, P, Q, X11, LDX11, X21, LDX21, THETA, 0, 0,
-     $                    0, 0, WORK, -1, CHILDINFO )
+            CALL CUNBDB1( M, P, Q, X11, LDX11, X21, LDX21, THETA,
+     $                    DUM, CDUM, CDUM, CDUM, WORK, -1,
+     $                    CHILDINFO )
             LORBDB = INT( WORK(1) )
-            IF( P .GE. M-P ) THEN
-               CALL CUNGQR( P, P, Q, U1, LDU1, 0, WORK(1), -1,
+            IF( WANTU1 .AND. P .GT. 0 ) THEN
+               CALL CUNGQR( P, P, Q, U1, LDU1, CDUM, WORK(1), -1,
      $                      CHILDINFO )
-               LORGQRMIN = MAX( 1, P )
-               LORGQROPT = INT( WORK(1) )
-            ELSE
-               CALL CUNGQR( M-P, M-P, Q, U2, LDU2, 0, WORK(1), -1,
+               LORGQRMIN = MAX( LORGQRMIN, P )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            ENDIF
+            IF( WANTU2 .AND. M-P .GT. 0 ) THEN
+               CALL CUNGQR( M-P, M-P, Q, U2, LDU2, CDUM, WORK(1), -1,
      $                      CHILDINFO )
-               LORGQRMIN = MAX( 1, M-P )
-               LORGQROPT = INT( WORK(1) )
+               LORGQRMIN = MAX( LORGQRMIN, M-P )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            END IF
+            IF( WANTV1T .AND. Q .GT. 0 ) THEN
+               CALL CUNGLQ( Q-1, Q-1, Q-1, V1T, LDV1T,
+     $                      CDUM, WORK(1), -1, CHILDINFO )
+               LORGLQMIN = MAX( LORGLQMIN, Q-1 )
+               LORGLQOPT = MAX( LORGLQOPT, INT( WORK(1) ) )
             END IF
-            CALL CUNGLQ( MAX(0,Q-1), MAX(0,Q-1), MAX(0,Q-1), V1T, LDV1T,
-     $                   0, WORK(1), -1, CHILDINFO )
-            LORGLQMIN = MAX( 1, Q-1 )
-            LORGLQOPT = INT( WORK(1) )
             CALL CBBCSD( JOBU1, JOBU2, JOBV1T, 'N', 'N', M, P, Q, THETA,
-     $                   0, U1, LDU1, U2, LDU2, V1T, LDV1T, 0, 1, 0, 0,
-     $                   0, 0, 0, 0, 0, 0, RWORK(1), -1, CHILDINFO )
+     $                   DUM(1), U1, LDU1, U2, LDU2, V1T, LDV1T, CDUM,
+     $                   1, DUM, DUM, DUM, DUM, DUM, DUM, DUM, DUM,
+     $                   RWORK(1), -1, CHILDINFO )
             LBBCSD = INT( RWORK(1) )
          ELSE IF( R .EQ. P ) THEN
-            CALL CUNBDB2( M, P, Q, X11, LDX11, X21, LDX21, THETA, 0, 0,
-     $                    0, 0, WORK(1), -1, CHILDINFO )
+            CALL CUNBDB2( M, P, Q, X11, LDX11, X21, LDX21, THETA, DUM,
+     $                    CDUM, CDUM, CDUM, WORK(1), -1, CHILDINFO )
             LORBDB = INT( WORK(1) )
-            IF( P-1 .GE. M-P ) THEN
-               CALL CUNGQR( P-1, P-1, P-1, U1(2,2), LDU1, 0, WORK(1),
+            IF( WANTU1 .AND. P .GT. 0 ) THEN
+               CALL CUNGQR( P-1, P-1, P-1, U1(2,2), LDU1, CDUM, WORK(1),
      $                      -1, CHILDINFO )
-               LORGQRMIN = MAX( 1, P-1 )
-               LORGQROPT = INT( WORK(1) )
-            ELSE
-               CALL CUNGQR( M-P, M-P, Q, U2, LDU2, 0, WORK(1), -1,
+               LORGQRMIN = MAX( LORGQRMIN, P-1 )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            END IF
+            IF( WANTU2 .AND. M-P .GT. 0 ) THEN
+               CALL CUNGQR( M-P, M-P, Q, U2, LDU2, CDUM, WORK(1), -1,
+     $                      CHILDINFO )
+               LORGQRMIN = MAX( LORGQRMIN, M-P )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            END IF
+            IF( WANTV1T .AND. Q .GT. 0 ) THEN
+               CALL CUNGLQ( Q, Q, R, V1T, LDV1T, CDUM, WORK(1), -1,
      $                      CHILDINFO )
-               LORGQRMIN = MAX( 1, M-P )
-               LORGQROPT = INT( WORK(1) )
+               LORGLQMIN = MAX( LORGLQMIN, Q )
+               LORGLQOPT = MAX( LORGLQOPT, INT( WORK(1) ) )
             END IF
-            CALL CUNGLQ( Q, Q, R, V1T, LDV1T, 0, WORK(1), -1,
-     $                   CHILDINFO )
-            LORGLQMIN = MAX( 1, Q )
-            LORGLQOPT = INT( WORK(1) )
             CALL CBBCSD( JOBV1T, 'N', JOBU1, JOBU2, 'T', M, Q, P, THETA,
-     $                   0, V1T, LDV1T, 0, 1, U1, LDU1, U2, LDU2, 0, 0,
-     $                   0, 0, 0, 0, 0, 0, RWORK(1), -1, CHILDINFO )
+     $                   DUM, V1T, LDV1T, CDUM, 1, U1, LDU1, U2, LDU2,
+     $                   DUM, DUM, DUM, DUM, DUM, DUM, DUM, DUM,
+     $                   RWORK(1), -1, CHILDINFO )
             LBBCSD = INT( RWORK(1) )
          ELSE IF( R .EQ. M-P ) THEN
-            CALL CUNBDB3( M, P, Q, X11, LDX11, X21, LDX21, THETA, 0, 0,
-     $                    0, 0, WORK(1), -1, CHILDINFO )
+            CALL CUNBDB3( M, P, Q, X11, LDX11, X21, LDX21, THETA, DUM,
+     $                    CDUM, CDUM, CDUM, WORK(1), -1, CHILDINFO )
             LORBDB = INT( WORK(1) )
-            IF( P .GE. M-P-1 ) THEN
-               CALL CUNGQR( P, P, Q, U1, LDU1, 0, WORK(1), -1,
+            IF( WANTU1 .AND. P .GT. 0 ) THEN
+               CALL CUNGQR( P, P, Q, U1, LDU1, CDUM, WORK(1), -1,
      $                      CHILDINFO )
-               LORGQRMIN = MAX( 1, P )
-               LORGQROPT = INT( WORK(1) )
-            ELSE
-               CALL CUNGQR( M-P-1, M-P-1, M-P-1, U2(2,2), LDU2, 0,
+               LORGQRMIN = MAX( LORGQRMIN, P )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            END IF
+            IF( WANTU2 .AND. M-P .GT. 0 ) THEN
+               CALL CUNGQR( M-P-1, M-P-1, M-P-1, U2(2,2), LDU2, CDUM,
      $                      WORK(1), -1, CHILDINFO )
-               LORGQRMIN = MAX( 1, M-P-1 )
-               LORGQROPT = INT( WORK(1) )
+               LORGQRMIN = MAX( LORGQRMIN, M-P-1 )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            END IF
+            IF( WANTV1T .AND. Q .GT. 0 ) THEN
+               CALL CUNGLQ( Q, Q, R, V1T, LDV1T, CDUM, WORK(1), -1,
+     $                      CHILDINFO )
+               LORGLQMIN = MAX( LORGLQMIN, Q )
+               LORGLQOPT = MAX( LORGLQOPT, INT( WORK(1) ) )
             END IF
-            CALL CUNGLQ( Q, Q, R, V1T, LDV1T, 0, WORK(1), -1,
-     $                   CHILDINFO )
-            LORGLQMIN = MAX( 1, Q )
-            LORGLQOPT = INT( WORK(1) )
             CALL CBBCSD( 'N', JOBV1T, JOBU2, JOBU1, 'T', M, M-Q, M-P,
-     $                   THETA, 0, 0, 1, V1T, LDV1T, U2, LDU2, U1, LDU1,
-     $                   0, 0, 0, 0, 0, 0, 0, 0, RWORK(1), -1,
-     $                   CHILDINFO )
+     $                   THETA, DUM, CDUM, 1, V1T, LDV1T, U2, LDU2, U1,
+     $                   LDU1, DUM, DUM, DUM, DUM, DUM, DUM, DUM, DUM,
+     $                   RWORK(1), -1, CHILDINFO )
             LBBCSD = INT( RWORK(1) )
          ELSE
-            CALL CUNBDB4( M, P, Q, X11, LDX11, X21, LDX21, THETA, 0, 0,
-     $                    0, 0, 0, WORK(1), -1, CHILDINFO )
+            CALL CUNBDB4( M, P, Q, X11, LDX11, X21, LDX21, THETA, DUM,
+     $                    CDUM, CDUM, CDUM, CDUM, WORK(1), -1, CHILDINFO
+     $                  )
             LORBDB = M + INT( WORK(1) )
-            IF( P .GE. M-P ) THEN
-               CALL CUNGQR( P, P, M-Q, U1, LDU1, 0, WORK(1), -1,
+            IF( WANTU1 .AND. P .GT. 0 ) THEN
+               CALL CUNGQR( P, P, M-Q, U1, LDU1, CDUM, WORK(1), -1,
      $                      CHILDINFO )
-               LORGQRMIN = MAX( 1, P )
-               LORGQROPT = INT( WORK(1) )
-            ELSE
-               CALL CUNGQR( M-P, M-P, M-Q, U2, LDU2, 0, WORK(1), -1,
+               LORGQRMIN = MAX( LORGQRMIN, P )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            END IF
+            IF( WANTU2 .AND. M-P .GT. 0 ) THEN
+               CALL CUNGQR( M-P, M-P, M-Q, U2, LDU2, CDUM, WORK(1), -1,
      $                      CHILDINFO )
-               LORGQRMIN = MAX( 1, M-P )
-               LORGQROPT = INT( WORK(1) )
+               LORGQRMIN = MAX( LORGQRMIN, M-P )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            END IF
+            IF( WANTV1T .AND. Q .GT. 0 ) THEN
+               CALL CUNGLQ( Q, Q, Q, V1T, LDV1T, CDUM, WORK(1), -1,
+     $                      CHILDINFO )
+               LORGLQMIN = MAX( LORGLQMIN, Q )
+               LORGLQOPT = MAX( LORGLQOPT, INT( WORK(1) ) )
             END IF
-            CALL CUNGLQ( Q, Q, Q, V1T, LDV1T, 0, WORK(1), -1,
-     $                   CHILDINFO )
-            LORGLQMIN = MAX( 1, Q )
-            LORGLQOPT = INT( WORK(1) )
             CALL CBBCSD( JOBU2, JOBU1, 'N', JOBV1T, 'N', M, M-P, M-Q,
-     $                   THETA, 0, U2, LDU2, U1, LDU1, 0, 1, V1T, LDV1T,
-     $                   0, 0, 0, 0, 0, 0, 0, 0, RWORK(1), -1,
-     $                   CHILDINFO )
+     $                   THETA, DUM, U2, LDU2, U1, LDU1, CDUM, 1, V1T,
+     $                   LDV1T, DUM, DUM, DUM, DUM, DUM, DUM, DUM, DUM,
+     $                   RWORK(1), -1, CHILDINFO )
             LBBCSD = INT( RWORK(1) )
          END IF
          LRWORKMIN = IBBCSD+LBBCSD-1
 *        Simultaneously diagonalize X11 and X21.
 *   
          CALL CBBCSD( JOBU1, JOBU2, JOBV1T, 'N', 'N', M, P, Q, THETA,
-     $                RWORK(IPHI), U1, LDU1, U2, LDU2, V1T, LDV1T, 0, 1,
-     $                RWORK(IB11D), RWORK(IB11E), RWORK(IB12D),
+     $                RWORK(IPHI), U1, LDU1, U2, LDU2, V1T, LDV1T, CDUM,
+     $                1, RWORK(IB11D), RWORK(IB11E), RWORK(IB12D),
      $                RWORK(IB12E), RWORK(IB21D), RWORK(IB21E),
      $                RWORK(IB22D), RWORK(IB22E), RWORK(IBBCSD), LBBCSD,
      $                CHILDINFO )
 *        Simultaneously diagonalize X11 and X21.
 *   
          CALL CBBCSD( JOBV1T, 'N', JOBU1, JOBU2, 'T', M, Q, P, THETA,
-     $                RWORK(IPHI), V1T, LDV1T, 0, 1, U1, LDU1, U2, LDU2,
-     $                RWORK(IB11D), RWORK(IB11E), RWORK(IB12D),
+     $                RWORK(IPHI), V1T, LDV1T, CDUM, 1, U1, LDU1, U2,
+     $                LDU2, RWORK(IB11D), RWORK(IB11E), RWORK(IB12D),
      $                RWORK(IB12E), RWORK(IB21D), RWORK(IB21E),
      $                RWORK(IB22D), RWORK(IB22E), RWORK(IBBCSD), LBBCSD,
      $                CHILDINFO )
 *        Simultaneously diagonalize X11 and X21.
 *   
          CALL CBBCSD( 'N', JOBV1T, JOBU2, JOBU1, 'T', M, M-Q, M-P,
-     $                THETA, RWORK(IPHI), 0, 1, V1T, LDV1T, U2, LDU2,
+     $                THETA, RWORK(IPHI), CDUM, 1, V1T, LDV1T, U2, LDU2,
      $                U1, LDU1, RWORK(IB11D), RWORK(IB11E),
      $                RWORK(IB12D), RWORK(IB12E), RWORK(IB21D),
      $                RWORK(IB21E), RWORK(IB22D), RWORK(IB22E),
 *        Simultaneously diagonalize X11 and X21.
 *   
          CALL CBBCSD( JOBU2, JOBU1, 'N', JOBV1T, 'N', M, M-P, M-Q,
-     $                THETA, RWORK(IPHI), U2, LDU2, U1, LDU1, 0, 1, V1T,
-     $                LDV1T, RWORK(IB11D), RWORK(IB11E), RWORK(IB12D),
-     $                RWORK(IB12E), RWORK(IB21D), RWORK(IB21E),
-     $                RWORK(IB22D), RWORK(IB22E), RWORK(IBBCSD), LBBCSD,
-     $                CHILDINFO )
+     $                THETA, RWORK(IPHI), U2, LDU2, U1, LDU1, CDUM, 1,
+     $                V1T, LDV1T, RWORK(IB11D), RWORK(IB11E),
+     $                RWORK(IB12D), RWORK(IB12E), RWORK(IB21D),
+     $                RWORK(IB21E), RWORK(IB22D), RWORK(IB22E),
+     $                RWORK(IBBCSD), LBBCSD, CHILDINFO )
 *   
 *        Permute rows and columns to place identity submatrices in
 *        preferred positions
index 2c54d1c5d290c6af7baa16397181843bd0b28bf8..962071cf76fce6d3abf95ff36e2bdb0de9aafe62 100644 (file)
 *> \param[in,out] U1
 *> \verbatim
 *>          U1 is DOUBLE PRECISION array, dimension (LDU1,P)
-*>          On entry, an LDU1-by-P matrix. On exit, U1 is postmultiplied
+*>          On entry, a P-by-P matrix. On exit, U1 is postmultiplied
 *>          by the left singular vector matrix common to [ B11 ; 0 ] and
 *>          [ B12 0 0 ; 0 -I 0 0 ].
 *> \endverbatim
 *> \param[in] LDU1
 *> \verbatim
 *>          LDU1 is INTEGER
-*>          The leading dimension of the array U1.
+*>          The leading dimension of the array U1, LDU1 >= MAX(1,P).
 *> \endverbatim
 *>
 *> \param[in,out] U2
 *> \verbatim
 *>          U2 is DOUBLE PRECISION array, dimension (LDU2,M-P)
-*>          On entry, an LDU2-by-(M-P) matrix. On exit, U2 is
+*>          On entry, an (M-P)-by-(M-P) matrix. On exit, U2 is
 *>          postmultiplied by the left singular vector matrix common to
 *>          [ B21 ; 0 ] and [ B22 0 0 ; 0 0 I ].
 *> \endverbatim
 *> \param[in] LDU2
 *> \verbatim
 *>          LDU2 is INTEGER
-*>          The leading dimension of the array U2.
+*>          The leading dimension of the array U2, LDU2 >= MAX(1,M-P).
 *> \endverbatim
 *>
 *> \param[in,out] V1T
 *> \verbatim
 *>          V1T is DOUBLE PRECISION array, dimension (LDV1T,Q)
-*>          On entry, a LDV1T-by-Q matrix. On exit, V1T is premultiplied
+*>          On entry, a Q-by-Q matrix. On exit, V1T is premultiplied
 *>          by the transpose of the right singular vector
 *>          matrix common to [ B11 ; 0 ] and [ B21 ; 0 ].
 *> \endverbatim
 *> \param[in] LDV1T
 *> \verbatim
 *>          LDV1T is INTEGER
-*>          The leading dimension of the array V1T.
+*>          The leading dimension of the array V1T, LDV1T >= MAX(1,Q).
 *> \endverbatim
 *>
 *> \param[in,out] V2T
 *> \verbatim
 *>          V2T is DOUBLE PRECISION array, dimenison (LDV2T,M-Q)
-*>          On entry, a LDV2T-by-(M-Q) matrix. On exit, V2T is
+*>          On entry, an (M-Q)-by-(M-Q) matrix. On exit, V2T is
 *>          premultiplied by the transpose of the right
 *>          singular vector matrix common to [ B12 0 0 ; 0 -I 0 ] and
 *>          [ B22 0 0 ; 0 0 I ].
 *> \param[in] LDV2T
 *> \verbatim
 *>          LDV2T is INTEGER
-*>          The leading dimension of the array V2T.
+*>          The leading dimension of the array V2T, LDV2T >= MAX(1,M-Q).
 *> \endverbatim
 *>
 *> \param[out] B11D
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup doubleOTHERcomputational
 *
      $                   V2T, LDV2T, B11D, B11E, B12D, B12E, B21D, B21E,
      $                   B22D, B22E, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBU1, JOBU2, JOBV1T, JOBV2T, TRANS
index 2c572f12cef0d70d2595647236e0c6734ad7ca58..a5af1b0fa64c8a533898d62dd76985dcd82da74c 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup auxOTHERcomputational
 *
       SUBROUTINE DBDSDC( UPLO, COMPQ, N, D, E, U, LDU, VT, LDVT, Q, IQ,
      $                   WORK, IWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.4.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          COMPQ, UPLO
       WSTART = 1
       QSTART = 3
       IF( ICOMPQ.EQ.1 ) THEN
-         CALL DCOPY( N, D, 1, Q( 1 ), 1 )
+         CALL DCOPY( N,   D, 1, Q( 1 ),   1 )
          CALL DCOPY( N-1, E, 1, Q( N+1 ), 1 )
       END IF
       IF( IUPLO.EQ.2 ) THEN
 *     If ICOMPQ = 0, use DLASDQ to compute the singular values.
 *
       IF( ICOMPQ.EQ.0 ) THEN
+*        Ignore WSTART, instead using WORK( 1 ), since the two vectors
+*        for CS and -SN above are added only if ICOMPQ == 2,
+*        and adding them exceeds documented WORK size of 4*n.
          CALL DLASDQ( 'U', 0, N, 0, 0, 0, D, E, VT, LDVT, U, LDU, U,
-     $                LDU, WORK( WSTART ), INFO )
+     $                LDU, WORK( 1 ), INFO )
          GO TO 40
       END IF
 *
       DO 30 I = 1, NM1
          IF( ( ABS( E( I ) ).LT.EPS ) .OR. ( I.EQ.NM1 ) ) THEN
 *
-*        Subproblem found. First determine its size and then
-*        apply divide and conquer on it.
+*           Subproblem found. First determine its size and then
+*           apply divide and conquer on it.
 *
             IF( I.LT.NM1 ) THEN
 *
-*        A subproblem with E(I) small for I < NM1.
+*              A subproblem with E(I) small for I < NM1.
 *
                NSIZE = I - START + 1
             ELSE IF( ABS( E( I ) ).GE.EPS ) THEN
 *
-*        A subproblem with E(NM1) not too small but I = NM1.
+*              A subproblem with E(NM1) not too small but I = NM1.
 *
                NSIZE = N - START + 1
             ELSE
 *
-*        A subproblem with E(NM1) small. This implies an
-*        1-by-1 subproblem at D(N). Solve this 1-by-1 problem
-*        first.
+*              A subproblem with E(NM1) small. This implies an
+*              1-by-1 subproblem at D(N). Solve this 1-by-1 problem
+*              first.
 *
                NSIZE = I - START + 1
                IF( ICOMPQ.EQ.2 ) THEN
index 7ceb9392c3ca49c182eda74d23f0ca03a0cd7559..89a8aab41aceedf17da04da2249b0f18e72f27c1 100644 (file)
@@ -80,7 +80,7 @@
 *>          = 'L':  B is lower bidiagonal.
 *> \endverbatim
 *>
-*> \param[in] JOBXZ
+*> \param[in] JOBZ
 *> \verbatim
 *>          JOBZ is CHARACTER*1
 *>          = 'N':  Compute singular values only;
 *>
 *> \param[in] VL
 *> \verbatim
-*>          VL is DOUBLE PRECISION
-*>          VL >=0.
+*>         VL is DOUBLE PRECISION
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for singular values. VU > VL.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>         VU is DOUBLE PRECISION
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for singular values. VU > VL.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest singular value to be returned.
+*>          1 <= IL <= IU <= min(M,N), if min(M,N) > 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest singular values to be returned.
+*>          If RANGE='I', the index of the
+*>          largest singular value to be returned.
 *>          1 <= IL <= IU <= min(M,N), if min(M,N) > 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>          If JOBZ = 'V', then if INFO = 0, the first NS elements of
 *>          IWORK are zero. If INFO > 0, then IWORK contains the indices 
 *>          of the eigenvectors that failed to converge in DSTEVX.
+*> \endverbatim
 *>
+*> \param[out] INFO
+*> \verbatim
 *>          INFO is INTEGER
 *>          = 0:  successful exit
 *>          < 0:  if INFO = -i, the i-th argument had an illegal value
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup doubleOTHEReigen
 *
       SUBROUTINE DBDSVDX( UPLO, JOBZ, RANGE, N, D, E, VL, VU, IL, IU, 
      $                    NS, S, Z, LDZ, WORK, IWORK, INFO)
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     November 2016
          IF( ABS( E( I ) ).LE.THRESH ) E( I ) = ZERO
       END DO
       IF( ABS( D( N ) ).LE.THRESH ) D( N ) = ZERO
-      E( N ) = ZERO
 *
 *     Pointers for arrays used by DSTEVX.
 *
 *        of the active submatrix.
 *
          RNGVX = 'I'
-         CALL DLASET( 'F', N*2, N+1, ZERO, ZERO, Z, LDZ )
+         IF( WANTZ ) CALL DLASET( 'F', N*2, N+1, ZERO, ZERO, Z, LDZ )
       ELSE IF( VALSV ) THEN
 *
 *        Find singular values in a half-open interval. We aim
          IF( NS.EQ.0 ) THEN
             RETURN
          ELSE
-            CALL DLASET( 'F', N*2, NS, ZERO, ZERO, Z, LDZ )
+            IF( WANTZ ) CALL DLASET( 'F', N*2, NS, ZERO, ZERO, Z, LDZ )
          END IF
       ELSE IF( INDSV ) THEN
 *
 *
          IF( VLTGK.EQ.VUTGK ) VLTGK = VLTGK - TOL
 *
-         CALL DLASET( 'F', N*2, IU-IL+1, ZERO, ZERO, Z, LDZ )
+         IF( WANTZ ) CALL DLASET( 'F', N*2, IU-IL+1, ZERO, ZERO, Z, LDZ)
       END IF             
 *
 *     Initialize variables and pointers for S, Z, and WORK.
                   NRU = 0
                   NRV = 0       
                END IF !** NTGK.GT.0 **! 
-               IF( IROWZ.LT.N*2 )  Z( 1:IROWZ-1, ICOLZ ) = ZERO           
+               IF( IROWZ.LT.N*2 .AND. WANTZ ) THEN
+                  Z( 1:IROWZ-1, ICOLZ ) = ZERO
+               END IF
             END DO !** IDPTR loop **!
-            IF( SPLIT ) THEN
+            IF( SPLIT .AND. WANTZ ) THEN
 *
 *              Bring back eigenvector corresponding
 *              to eigenvalue equal to zero.
          IF( K.NE.NS+1-I ) THEN
             S( K ) = S( NS+1-I )
             S( NS+1-I ) = SMIN
-            CALL DSWAP( N*2, Z( 1,K ), 1, Z( 1,NS+1-I ), 1 )
+            IF( WANTZ ) CALL DSWAP( N*2, Z( 1,K ), 1, Z( 1,NS+1-I ), 1 )
          END IF
       END DO
 *   
          K = IU - IL + 1
          IF( K.LT.NS ) THEN
             S( K+1:NS ) = ZERO
-            Z( 1:N*2,K+1:NS ) = ZERO
+            IF( WANTZ ) Z( 1:N*2,K+1:NS ) = ZERO
             NS = K
          END IF
       END IF 
 *     Reorder Z: U = Z( 1:N,1:NS ), V = Z( N+1:N*2,1:NS ).
 *     If B is a lower diagonal, swap U and V.
 *
+      IF( WANTZ ) THEN
       DO I = 1, NS
          CALL DCOPY( N*2, Z( 1,I ), 1, WORK, 1 )
          IF( LOWER ) THEN
             CALL DCOPY( N, WORK( 1 ), 2, Z( N+1,I ), 1 )
          END IF
       END DO
+      END IF
 *
       RETURN
 *
index c96c6233886ba98145d40b2df03df7980501a3db..e50ef67b2d8dc34947f5a82e048d05df6b55f1cb 100644 (file)
      $                    ERR_BNDS_COMP, NPARAMS, PARAMS, WORK, IWORK,
      $                    INFO )
 *
-*  -- LAPACK computational routine (version 3.4.1) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     April 2012
 *
 *     Perform refinement on each right-hand side
 *
-      IF (REF_TYPE .NE. 0) THEN
+      IF ( REF_TYPE .NE. 0 .AND. INFO .EQ. 0 ) THEN
 
          PREC_TYPE = ILAPREC( 'E' )
 
index 2a3e963fdc807ebc8e9d57448d4d1023924795be..67e084877d79b92b98f26222b1013a065f2faeab 100644 (file)
@@ -90,7 +90,7 @@
 *>
 *> \param[in] SELECT
 *> \verbatim
-*>          SELECT is procedure) LOGICAL FUNCTION of two DOUBLE PRECISION arguments
+*>          SELECT is a LOGICAL FUNCTION of two DOUBLE PRECISION arguments
 *>          SELECT must be declared EXTERNAL in the calling subroutine.
 *>          If SORT = 'S', SELECT is used to select eigenvalues to sort
 *>          to the top left of the Schur form.
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup doubleGEeigen
 *
      $                   WR, WI, VS, LDVS, RCONDE, RCONDV, WORK, LWORK,
      $                   IWORK, LIWORK, BWORK, INFO )
 *
-*  -- LAPACK driver routine (version 3.4.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBVS, SENSE, SORT
index 328eaa39c3b3a8d5f04adacfb3f78feb7767cbf3..eb043d95a715fd04c5269974f8082c2792e865c6 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
+*
+*  @precisions fortran d -> s
 *
 *> \ingroup doubleGEeigen
 *
 *  =====================================================================
       SUBROUTINE DGEEV( JOBVL, JOBVR, N, A, LDA, WR, WI, VL, LDVL, VR,
      $                  LDVR, WORK, LWORK, INFO )
+      implicit none
 *
-*  -- LAPACK driver routine (version 3.4.2) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBVL, JOBVR
       LOGICAL            LQUERY, SCALEA, WANTVL, WANTVR
       CHARACTER          SIDE
       INTEGER            HSWORK, I, IBAL, IERR, IHI, ILO, ITAU, IWRK, K,
-     $                   MAXWRK, MINWRK, NOUT
+     $                   LWORK_TREVC, MAXWRK, MINWRK, NOUT
       DOUBLE PRECISION   ANRM, BIGNUM, CS, CSCALE, EPS, R, SCL, SMLNUM,
      $                   SN
 *     ..
 *     ..
 *     .. External Subroutines ..
       EXTERNAL           DGEBAK, DGEBAL, DGEHRD, DHSEQR, DLABAD, DLACPY,
-     $                   DLARTG, DLASCL, DORGHR, DROT, DSCAL, DTREVC,
+     $                   DLARTG, DLASCL, DORGHR, DROT, DSCAL, DTREVC3,
      $                   XERBLA
 *     ..
 *     .. External Functions ..
                MAXWRK = MAX( MAXWRK, 2*N + ( N - 1 )*ILAENV( 1,
      $                       'DORGHR', ' ', N, 1, N, -1 ) )
                CALL DHSEQR( 'S', 'V', N, 1, N, A, LDA, WR, WI, VL, LDVL,
-     $                WORK, -1, INFO )
-               HSWORK = WORK( 1 )
+     $                      WORK, -1, INFO )
+               HSWORK = INT( WORK(1) )
                MAXWRK = MAX( MAXWRK, N + 1, N + HSWORK )
+               CALL DTREVC3( 'L', 'B', SELECT, N, A, LDA,
+     $                       VL, LDVL, VR, LDVR, N, NOUT,
+     $                       WORK, -1, IERR )
+               LWORK_TREVC = INT( WORK(1) )
+               MAXWRK = MAX( MAXWRK, N + LWORK_TREVC )
                MAXWRK = MAX( MAXWRK, 4*N )
             ELSE IF( WANTVR ) THEN
                MINWRK = 4*N
                MAXWRK = MAX( MAXWRK, 2*N + ( N - 1 )*ILAENV( 1,
      $                       'DORGHR', ' ', N, 1, N, -1 ) )
                CALL DHSEQR( 'S', 'V', N, 1, N, A, LDA, WR, WI, VR, LDVR,
-     $                WORK, -1, INFO )
-               HSWORK = WORK( 1 )
+     $                      WORK, -1, INFO )
+               HSWORK = INT( WORK(1) )
                MAXWRK = MAX( MAXWRK, N + 1, N + HSWORK )
+               CALL DTREVC3( 'R', 'B', SELECT, N, A, LDA,
+     $                       VL, LDVL, VR, LDVR, N, NOUT,
+     $                       WORK, -1, IERR )
+               LWORK_TREVC = INT( WORK(1) )
+               MAXWRK = MAX( MAXWRK, N + LWORK_TREVC )
                MAXWRK = MAX( MAXWRK, 4*N )
             ELSE 
                MINWRK = 3*N
                CALL DHSEQR( 'E', 'N', N, 1, N, A, LDA, WR, WI, VR, LDVR,
-     $                WORK, -1, INFO )
-               HSWORK = WORK( 1 )
+     $                      WORK, -1, INFO )
+               HSWORK = INT( WORK(1) )
                MAXWRK = MAX( MAXWRK, N + 1, N + HSWORK )
             END IF
             MAXWRK = MAX( MAXWRK, MINWRK )
       IF( WANTVL .OR. WANTVR ) THEN
 *
 *        Compute left and/or right eigenvectors
-*        (Workspace: need 4*N)
+*        (Workspace: need 4*N, prefer N + N + 2*N*NB)
 *
-         CALL DTREVC( SIDE, 'B', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,
-     $                N, NOUT, WORK( IWRK ), IERR )
+         CALL DTREVC3( SIDE, 'B', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,
+     $                 N, NOUT, WORK( IWRK ), LWORK-IWRK+1, IERR )
       END IF
 *
       IF( WANTVL ) THEN
index 81f30f9367dd9921e86a7efb9cb1cabd0c96fa55..3067f346d86d27e196a25ace16dc983d7471c937 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
+*
+*  @precisions fortran d -> s
 *
 *> \ingroup doubleGEeigen
 *
       SUBROUTINE DGEEVX( BALANC, JOBVL, JOBVR, SENSE, N, A, LDA, WR, WI,
      $                   VL, LDVL, VR, LDVR, ILO, IHI, SCALE, ABNRM,
      $                   RCONDE, RCONDV, WORK, LWORK, IWORK, INFO )
+      implicit none
 *
-*  -- LAPACK driver routine (version 3.4.2) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          BALANC, JOBVL, JOBVR, SENSE
       LOGICAL            LQUERY, SCALEA, WANTVL, WANTVR, WNTSNB, WNTSNE,
      $                   WNTSNN, WNTSNV
       CHARACTER          JOB, SIDE
-      INTEGER            HSWORK, I, ICOND, IERR, ITAU, IWRK, K, MAXWRK,
-     $                   MINWRK, NOUT
+      INTEGER            HSWORK, I, ICOND, IERR, ITAU, IWRK, K,
+     $                   LWORK_TREVC, MAXWRK, MINWRK, NOUT
       DOUBLE PRECISION   ANRM, BIGNUM, CS, CSCALE, EPS, R, SCL, SMLNUM,
      $                   SN
 *     ..
 *     ..
 *     .. External Subroutines ..
       EXTERNAL           DGEBAK, DGEBAL, DGEHRD, DHSEQR, DLABAD, DLACPY,
-     $                   DLARTG, DLASCL, DORGHR, DROT, DSCAL, DTREVC,
+     $                   DLARTG, DLASCL, DORGHR, DROT, DSCAL, DTREVC3,
      $                   DTRSNA, XERBLA
 *     ..
 *     .. External Functions ..
       WNTSNE = LSAME( SENSE, 'E' )
       WNTSNV = LSAME( SENSE, 'V' )
       WNTSNB = LSAME( SENSE, 'B' )
-      IF( .NOT.( LSAME( BALANC, 'N' ) .OR. LSAME( BALANC,
-     $    'S' ) .OR. LSAME( BALANC, 'P' ) .OR. LSAME( BALANC, 'B' ) ) )
+      IF( .NOT.( LSAME( BALANC, 'N' ) .OR. LSAME( BALANC, 'S' )
+     $      .OR. LSAME( BALANC, 'P' ) .OR. LSAME( BALANC, 'B' ) ) )
      $     THEN
          INFO = -1
       ELSE IF( ( .NOT.WANTVL ) .AND. ( .NOT.LSAME( JOBVL, 'N' ) ) ) THEN
             MAXWRK = N + N*ILAENV( 1, 'DGEHRD', ' ', N, 1, N, 0 )
 *
             IF( WANTVL ) THEN
+               CALL DTREVC3( 'L', 'B', SELECT, N, A, LDA,
+     $                       VL, LDVL, VR, LDVR,
+     $                       N, NOUT, WORK, -1, IERR )
+               LWORK_TREVC = INT( WORK(1) )
+               MAXWRK = MAX( MAXWRK, N + LWORK_TREVC )
                CALL DHSEQR( 'S', 'V', N, 1, N, A, LDA, WR, WI, VL, LDVL,
      $                WORK, -1, INFO )
             ELSE IF( WANTVR ) THEN
+               CALL DTREVC3( 'R', 'B', SELECT, N, A, LDA,
+     $                       VL, LDVL, VR, LDVR,
+     $                       N, NOUT, WORK, -1, IERR )
+               LWORK_TREVC = INT( WORK(1) )
+               MAXWRK = MAX( MAXWRK, N + LWORK_TREVC )
                CALL DHSEQR( 'S', 'V', N, 1, N, A, LDA, WR, WI, VR, LDVR,
      $                WORK, -1, INFO )
             ELSE
      $                LDVR, WORK, -1, INFO )
                END IF
             END IF
-            HSWORK = WORK( 1 )
+            HSWORK = INT( WORK(1) )
 *
             IF( ( .NOT.WANTVL ) .AND. ( .NOT.WANTVR ) ) THEN
                MINWRK = 2*N
      $                WORK( IWRK ), LWORK-IWRK+1, INFO )
       END IF
 *
-*     If INFO > 0 from DHSEQR, then quit
+*     If INFO .NE. 0 from DHSEQR, then quit
 *
-      IF( INFO.GT.0 )
+      IF( INFO.NE.0 )
      $   GO TO 50
 *
       IF( WANTVL .OR. WANTVR ) THEN
 *
 *        Compute left and/or right eigenvectors
-*        (Workspace: need 3*N)
+*        (Workspace: need 3*N, prefer N + 2*N*NB)
 *
-         CALL DTREVC( SIDE, 'B', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,
-     $                N, NOUT, WORK( IWRK ), IERR )
+         CALL DTREVC3( SIDE, 'B', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,
+     $                 N, NOUT, WORK( IWRK ), LWORK-IWRK+1, IERR )
       END IF
 *
 *     Compute condition numbers if desired
index 4b26a1d6834b739320a800d6d1cc8e7e63f07eb8..fc91ab51d0b29b2a4980853456cba8476dfb4f52 100644 (file)
@@ -52,7 +52,8 @@
 *> are computed and stored in the arrays U and V, respectively. The diagonal
 *> of [SIGMA] is computed and stored in the array SVA.
 *> DGEJSV can sometimes compute tiny singular values and their singular vectors much
-*> more accurately than other SVD routines, see below under Further Details.*> \endverbatim
+*> more accurately than other SVD routines, see below under Further Details.
+*> \endverbatim
 *
 *  Arguments:
 *  ==========
 *>                         copied back to the V array. This 'W' option is just
 *>                         a reminder to the caller that in this case U is
 *>                         reserved as workspace of length N*N.
-*>          If JOBU = 'N'  U is not referenced.
+*>          If JOBU = 'N'  U is not referenced, unless JOBT='T'.
 *> \endverbatim
 *>
 *> \param[in] LDU
 *>                         copied back to the U array. This 'W' option is just
 *>                         a reminder to the caller that in this case V is
 *>                         reserved as workspace of length N*N.
-*>          If JOBV = 'N'  V is not referenced.
+*>          If JOBV = 'N'  V is not referenced, unless JOBT='T'.
 *> \endverbatim
 *>
 *> \param[in] LDV
 *>          If SIGMA and the right singular vectors are needed (JOBV.EQ.'V'),
 *>            -> the minimal requirement is LWORK >= max(2*M+N,4*N+1,7).
 *>            -> For optimal performance, LWORK >= max(2*M+N,3*N+(N+1)*NB,7),
-*>               where NB is the optimal block size for DGEQP3, DGEQRF, DGELQ,
+*>               where NB is the optimal block size for DGEQP3, DGEQRF, DGELQF,
 *>               DORMLQ. In general, the optimal length LWORK is computed as
 *>               LWORK >= max(2*M+N,N+LWORK(DGEQP3), N+LWORK(DPOCON), 
-*>                       N+LWORK(DGELQ), 2*N+LWORK(DGEQRF), N+LWORK(DORMLQ)).
+*>                       N+LWORK(DGELQF), 2*N+LWORK(DGEQRF), N+LWORK(DORMLQ)).
 *>
 *>          If SIGMA and the left singular vectors are needed
 *>            -> the minimal requirement is LWORK >= max(2*M+N,4*N+1,7).
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup doubleGEsing
 *
      $                   M, N, A, LDA, SVA, U, LDU, V, LDV,
      $                   WORK, LWORK, IWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       IMPLICIT    NONE
 *
 *     Quick return for void matrix (Y3K safe)
 * #:)
-      IF ( ( M .EQ. 0 ) .OR. ( N .EQ. 0 ) ) RETURN
+      IF ( ( M .EQ. 0 ) .OR. ( N .EQ. 0 ) ) THEN
+         IWORK(1:3) = 0
+         WORK(1:7) = 0
+         RETURN
+      ENDIF
 *
 *     Determine whether the matrix U should be M x N or M x M
 *
             IWORK(1) = 0
             IWORK(2) = 0
          END IF
+         IWORK(3) = 0
          IF ( ERREST ) WORK(3) = ONE
          IF ( LSVEC .AND. RSVEC ) THEN
             WORK(4) = ONE
index c5f57a29f4183c5422c136aea5fff2a9ed4f5485..42453dbf1cca769ff536af363594cfb8e6b94f93 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup doubleGEcomputational
 *
 *  =====================================================================
       RECURSIVE SUBROUTINE DGEQRT3( M, N, A, LDA, T, LDT, INFO )
 *
-*  -- LAPACK computational routine (version 3.4.2) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER   INFO, LDA, M, N, LDT
 *
 *        Compute Householder transform when N=1
 *
-         CALL DLARFG( M, A, A( MIN( 2, M ), 1 ), 1, T )
+         CALL DLARFG( M, A(1,1), A( MIN( 2, M ), 1 ), 1, T(1,1) )
 *         
       ELSE
 *
index 54e2652e441a635135f08654571c0a10057ac3d4..02beb3be5cc20c78d36199bc3a4f9074673a5c59 100644 (file)
@@ -18,8 +18,8 @@
 *  Definition:
 *  ===========
 *
-*       SUBROUTINE DGESDD( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK,
-*                          LWORK, IWORK, INFO )
+*       SUBROUTINE DGESDD( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT,
+*                          WORK, LWORK, IWORK, INFO )
 * 
 *       .. Scalar Arguments ..
 *       CHARACTER          JOBZ
 *> \param[in] LDVT
 *> \verbatim
 *>          LDVT is INTEGER
-*>          The leading dimension of the array VT.  LDVT >= 1; if
-*>          JOBZ = 'A' or JOBZ = 'O' and M >= N, LDVT >= N;
+*>          The leading dimension of the array VT.  LDVT >= 1;
+*>          if JOBZ = 'A' or JOBZ = 'O' and M >= N, LDVT >= N;
 *>          if JOBZ = 'S', LDVT >= min(M,N).
 *> \endverbatim
 *>
 *> \verbatim
 *>          LWORK is INTEGER
 *>          The dimension of the array WORK. LWORK >= 1.
-*>          If JOBZ = 'N',
-*>            LWORK >= 3*min(M,N) + max(max(M,N),7*min(M,N)).
-*>          If JOBZ = 'O',
-*>            LWORK >= 3*min(M,N) + 
-*>                     max(max(M,N),5*min(M,N)*min(M,N)+4*min(M,N)).
-*>          If JOBZ = 'S' or 'A'
-*>            LWORK >= min(M,N)*(7+4*min(M,N))
-*>          For good performance, LWORK should generally be larger.
-*>          If LWORK = -1 but other input arguments are legal, WORK(1)
-*>          returns the optimal LWORK.
+*>          If LWORK = -1, a workspace query is assumed.  The optimal
+*>          size for the WORK array is calculated and stored in WORK(1),
+*>          and no other work except argument checking is performed.
+*>
+*>          Let mx = max(M,N) and mn = min(M,N).
+*>          If JOBZ = 'N', LWORK >= 3*mn + max( mx, 7*mn ).
+*>          If JOBZ = 'O', LWORK >= 3*mn + max( mx, 5*mn*mn + 4*mn ).
+*>          If JOBZ = 'S', LWORK >= 4*mn*mn + 7*mn.
+*>          If JOBZ = 'A', LWORK >= 4*mn*mn + 6*mn + mx.
+*>          These are not tight minimums in all cases; see comments inside code.
+*>          For good performance, LWORK should generally be larger;
+*>          a query is recommended.
 *> \endverbatim
 *>
 *> \param[out] IWORK
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup doubleGEsing
 *
 *>     Ming Gu and Huan Ren, Computer Science Division, University of
 *>     California at Berkeley, USA
 *>
+*> @precisions fortran d -> s
 *  =====================================================================
-      SUBROUTINE DGESDD( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK,
-     $                   LWORK, IWORK, INFO )
+      SUBROUTINE DGESDD( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT,
+     $                   WORK, LWORK, IWORK, INFO )
+      implicit none
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ
      $                   IR, ISCL, ITAU, ITAUP, ITAUQ, IU, IVT, LDWKVT,
      $                   LDWRKL, LDWRKR, LDWRKU, MAXWRK, MINMN, MINWRK,
      $                   MNTHR, NWORK, WRKBL
+      INTEGER            LWORK_DGEBRD_MN, LWORK_DGEBRD_MM,  
+     $                   LWORK_DGEBRD_NN, LWORK_DGELQF_MN,
+     $                   LWORK_DGEQRF_MN,
+     $                   LWORK_DORGBR_P_MM, LWORK_DORGBR_Q_NN,
+     $                   LWORK_DORGLQ_MN, LWORK_DORGLQ_NN,
+     $                   LWORK_DORGQR_MM, LWORK_DORGQR_MN,
+     $                   LWORK_DORMBR_PRT_MM, LWORK_DORMBR_QLN_MM,
+     $                   LWORK_DORMBR_PRT_MN, LWORK_DORMBR_QLN_MN,
+     $                   LWORK_DORMBR_PRT_NN, LWORK_DORMBR_QLN_NN
       DOUBLE PRECISION   ANRM, BIGNUM, EPS, SMLNUM
 *     ..
 *     .. Local Arrays ..
 *     ..
 *     .. External Functions ..
       LOGICAL            LSAME
-      INTEGER            ILAENV
       DOUBLE PRECISION   DLAMCH, DLANGE
-      EXTERNAL           DLAMCH, DLANGE, ILAENV, LSAME
+      EXTERNAL           DLAMCH, DLANGE, LSAME
 *     ..
 *     .. Intrinsic Functions ..
       INTRINSIC          INT, MAX, MIN, SQRT
 *
 *     Test the input arguments
 *
-      INFO = 0
-      MINMN = MIN( M, N )
-      WNTQA = LSAME( JOBZ, 'A' )
-      WNTQS = LSAME( JOBZ, 'S' )
+      INFO   = 0
+      MINMN  = MIN( M, N )
+      WNTQA  = LSAME( JOBZ, 'A' )
+      WNTQS  = LSAME( JOBZ, 'S' )
       WNTQAS = WNTQA .OR. WNTQS
-      WNTQO = LSAME( JOBZ, 'O' )
-      WNTQN = LSAME( JOBZ, 'N' )
+      WNTQO  = LSAME( JOBZ, 'O' )
+      WNTQN  = LSAME( JOBZ, 'N' )
       LQUERY = ( LWORK.EQ.-1 )
 *
       IF( .NOT.( WNTQA .OR. WNTQS .OR. WNTQO .OR. WNTQN ) ) THEN
       END IF
 *
 *     Compute workspace
-*      (Note: Comments in the code beginning "Workspace:" describe the
-*       minimal amount of workspace needed at that point in the code,
+*       Note: Comments in the code beginning "Workspace:" describe the
+*       minimal amount of workspace allocated at that point in the code,
 *       as well as the preferred amount for good performance.
 *       NB refers to the optimal block size for the immediately
-*       following subroutine, as returned by ILAENV.)
+*       following subroutine, as returned by ILAENV.
 *
       IF( INFO.EQ.0 ) THEN
          MINWRK = 1
          MAXWRK = 1
+         BDSPAC = 0
+         MNTHR  = INT( MINMN*11.0D0 / 6.0D0 )
          IF( M.GE.N .AND. MINMN.GT.0 ) THEN
 *
 *           Compute space needed for DBDSDC
 *
-            MNTHR = INT( MINMN*11.0D0 / 6.0D0 )
             IF( WNTQN ) THEN
+*              dbdsdc needs only 4*N (or 6*N for uplo=L for LAPACK <= 3.6)
+*              keep 7*N for backwards compatability.
                BDSPAC = 7*N
             ELSE
                BDSPAC = 3*N*N + 4*N
             END IF
+*
+*           Compute space preferred for each routine
+            CALL DGEBRD( M, N, DUM(1), M, DUM(1), DUM(1), DUM(1),
+     $                   DUM(1), DUM(1), -1, IERR )
+            LWORK_DGEBRD_MN = INT( DUM(1) )
+*
+            CALL DGEBRD( N, N, DUM(1), N, DUM(1), DUM(1), DUM(1),
+     $                   DUM(1), DUM(1), -1, IERR )
+            LWORK_DGEBRD_NN = INT( DUM(1) )
+*
+            CALL DGEQRF( M, N, DUM(1), M, DUM(1), DUM(1), -1, IERR )
+            LWORK_DGEQRF_MN = INT( DUM(1) )
+*
+            CALL DORGBR( 'Q', N, N, N, DUM(1), N, DUM(1), DUM(1), -1,
+     $                   IERR )
+            LWORK_DORGBR_Q_NN = INT( DUM(1) )
+*
+            CALL DORGQR( M, M, N, DUM(1), M, DUM(1), DUM(1), -1, IERR )
+            LWORK_DORGQR_MM = INT( DUM(1) )
+*
+            CALL DORGQR( M, N, N, DUM(1), M, DUM(1), DUM(1), -1, IERR )
+            LWORK_DORGQR_MN = INT( DUM(1) )
+*
+            CALL DORMBR( 'P', 'R', 'T', N, N, N, DUM(1), N,
+     $                   DUM(1), DUM(1), N, DUM(1), -1, IERR )
+            LWORK_DORMBR_PRT_NN = INT( DUM(1) )
+*
+            CALL DORMBR( 'Q', 'L', 'N', N, N, N, DUM(1), N,
+     $                   DUM(1), DUM(1), N, DUM(1), -1, IERR )
+            LWORK_DORMBR_QLN_NN = INT( DUM(1) )
+*
+            CALL DORMBR( 'Q', 'L', 'N', M, N, N, DUM(1), M,
+     $                   DUM(1), DUM(1), M, DUM(1), -1, IERR )
+            LWORK_DORMBR_QLN_MN = INT( DUM(1) )
+*
+            CALL DORMBR( 'Q', 'L', 'N', M, M, N, DUM(1), M,
+     $                   DUM(1), DUM(1), M, DUM(1), -1, IERR )
+            LWORK_DORMBR_QLN_MM = INT( DUM(1) )
+*
             IF( M.GE.MNTHR ) THEN
                IF( WNTQN ) THEN
 *
-*                 Path 1 (M much larger than N, JOBZ='N')
+*                 Path 1 (M >> N, JOBZ='N')
 *
-                  WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1,
-     $                    -1 )
-                  WRKBL = MAX( WRKBL, 3*N+2*N*
-     $                    ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
-                  MAXWRK = MAX( WRKBL, BDSPAC+N )
+                  WRKBL = N + LWORK_DGEQRF_MN
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DGEBRD_NN )
+                  MAXWRK = MAX( WRKBL, BDSPAC + N )
                   MINWRK = BDSPAC + N
                ELSE IF( WNTQO ) THEN
 *
-*                 Path 2 (M much larger than N, JOBZ='O')
-*
-                  WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
-                  WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,
-     $                    N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*N+2*N*
-     $                    ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*N+N*
-     $                    ILAENV( 1, 'DORMBR', 'QLN', N, N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*N+N*
-     $                    ILAENV( 1, 'DORMBR', 'PRT', N, N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, BDSPAC+3*N )
+*                 Path 2 (M >> N, JOBZ='O')
+*
+                  WRKBL = N + LWORK_DGEQRF_MN
+                  WRKBL = MAX( WRKBL,   N + LWORK_DORGQR_MN )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DGEBRD_NN )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DORMBR_QLN_NN )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DORMBR_PRT_NN )
+                  WRKBL = MAX( WRKBL, 3*N + BDSPAC )
                   MAXWRK = WRKBL + 2*N*N
                   MINWRK = BDSPAC + 2*N*N + 3*N
                ELSE IF( WNTQS ) THEN
 *
-*                 Path 3 (M much larger than N, JOBZ='S')
-*
-                  WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
-                  WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,
-     $                    N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*N+2*N*
-     $                    ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*N+N*
-     $                    ILAENV( 1, 'DORMBR', 'QLN', N, N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*N+N*
-     $                    ILAENV( 1, 'DORMBR', 'PRT', N, N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, BDSPAC+3*N )
+*                 Path 3 (M >> N, JOBZ='S')
+*
+                  WRKBL = N + LWORK_DGEQRF_MN
+                  WRKBL = MAX( WRKBL,   N + LWORK_DORGQR_MN )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DGEBRD_NN )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DORMBR_QLN_NN )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DORMBR_PRT_NN )
+                  WRKBL = MAX( WRKBL, 3*N + BDSPAC )
                   MAXWRK = WRKBL + N*N
                   MINWRK = BDSPAC + N*N + 3*N
                ELSE IF( WNTQA ) THEN
 *
-*                 Path 4 (M much larger than N, JOBZ='A')
-*
-                  WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
-                  WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'DORGQR', ' ', M,
-     $                    M, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*N+2*N*
-     $                    ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*N+N*
-     $                    ILAENV( 1, 'DORMBR', 'QLN', N, N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*N+N*
-     $                    ILAENV( 1, 'DORMBR', 'PRT', N, N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, BDSPAC+3*N )
+*                 Path 4 (M >> N, JOBZ='A')
+*
+                  WRKBL = N + LWORK_DGEQRF_MN
+                  WRKBL = MAX( WRKBL,   N + LWORK_DORGQR_MM )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DGEBRD_NN )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DORMBR_QLN_NN )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DORMBR_PRT_NN )
+                  WRKBL = MAX( WRKBL, 3*N + BDSPAC )
                   MAXWRK = WRKBL + N*N
-                  MINWRK = BDSPAC + N*N + 2*N + M
+                  MINWRK = N*N + MAX( 3*N + BDSPAC, N + M )
                END IF
             ELSE
 *
-*              Path 5 (M at least N, but not much larger)
+*              Path 5 (M >= N, but not much larger)
 *
-               WRKBL = 3*N + ( M+N )*ILAENV( 1, 'DGEBRD', ' ', M, N, -1,
-     $                 -1 )
+               WRKBL = 3*N + LWORK_DGEBRD_MN
                IF( WNTQN ) THEN
-                  MAXWRK = MAX( WRKBL, BDSPAC+3*N )
+*                 Path 5n (M >= N, jobz='N')
+                  MAXWRK = MAX( WRKBL, 3*N + BDSPAC )
                   MINWRK = 3*N + MAX( M, BDSPAC )
                ELSE IF( WNTQO ) THEN
-                  WRKBL = MAX( WRKBL, 3*N+N*
-     $                    ILAENV( 1, 'DORMBR', 'QLN', M, N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*N+N*
-     $                    ILAENV( 1, 'DORMBR', 'PRT', N, N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, BDSPAC+3*N )
+*                 Path 5o (M >= N, jobz='O')
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DORMBR_PRT_NN )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DORMBR_QLN_MN )
+                  WRKBL = MAX( WRKBL, 3*N + BDSPAC )
                   MAXWRK = WRKBL + M*N
-                  MINWRK = 3*N + MAX( M, N*N+BDSPAC )
+                  MINWRK = 3*N + MAX( M, N*N + BDSPAC )
                ELSE IF( WNTQS ) THEN
-                  WRKBL = MAX( WRKBL, 3*N+N*
-     $                    ILAENV( 1, 'DORMBR', 'QLN', M, N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*N+N*
-     $                    ILAENV( 1, 'DORMBR', 'PRT', N, N, N, -1 ) )
-                  MAXWRK = MAX( WRKBL, BDSPAC+3*N )
+*                 Path 5s (M >= N, jobz='S')
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DORMBR_QLN_MN )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DORMBR_PRT_NN )
+                  MAXWRK = MAX( WRKBL, 3*N + BDSPAC )
                   MINWRK = 3*N + MAX( M, BDSPAC )
                ELSE IF( WNTQA ) THEN
-                  WRKBL = MAX( WRKBL, 3*N+M*
-     $                    ILAENV( 1, 'DORMBR', 'QLN', M, M, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*N+N*
-     $                    ILAENV( 1, 'DORMBR', 'PRT', N, N, N, -1 ) )
-                  MAXWRK = MAX( MAXWRK, BDSPAC+3*N )
+*                 Path 5a (M >= N, jobz='A')
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DORMBR_QLN_MM )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DORMBR_PRT_NN )
+                  MAXWRK = MAX( WRKBL, 3*N + BDSPAC )
                   MINWRK = 3*N + MAX( M, BDSPAC )
                END IF
             END IF
 *
 *           Compute space needed for DBDSDC
 *
-            MNTHR = INT( MINMN*11.0D0 / 6.0D0 )
             IF( WNTQN ) THEN
+*              dbdsdc needs only 4*N (or 6*N for uplo=L for LAPACK <= 3.6)
+*              keep 7*N for backwards compatability.
                BDSPAC = 7*M
             ELSE
                BDSPAC = 3*M*M + 4*M
             END IF
+*
+*           Compute space preferred for each routine
+            CALL DGEBRD( M, N, DUM(1), M, DUM(1), DUM(1), DUM(1),
+     $                   DUM(1), DUM(1), -1, IERR )
+            LWORK_DGEBRD_MN = INT( DUM(1) )
+*
+            CALL DGEBRD( M, M, A, M, S, DUM(1), DUM(1),
+     $                   DUM(1), DUM(1), -1, IERR )
+            LWORK_DGEBRD_MM = INT( DUM(1) )
+*
+            CALL DGELQF( M, N, A, M, DUM(1), DUM(1), -1, IERR )
+            LWORK_DGELQF_MN = INT( DUM(1) )
+*
+            CALL DORGLQ( N, N, M, DUM(1), N, DUM(1), DUM(1), -1, IERR )
+            LWORK_DORGLQ_NN = INT( DUM(1) )
+*
+            CALL DORGLQ( M, N, M, A, M, DUM(1), DUM(1), -1, IERR )
+            LWORK_DORGLQ_MN = INT( DUM(1) )
+*
+            CALL DORGBR( 'P', M, M, M, A, N, DUM(1), DUM(1), -1, IERR )
+            LWORK_DORGBR_P_MM = INT( DUM(1) )
+*
+            CALL DORMBR( 'P', 'R', 'T', M, M, M, DUM(1), M,
+     $                   DUM(1), DUM(1), M, DUM(1), -1, IERR )
+            LWORK_DORMBR_PRT_MM = INT( DUM(1) )
+*
+            CALL DORMBR( 'P', 'R', 'T', M, N, M, DUM(1), M,
+     $                   DUM(1), DUM(1), M, DUM(1), -1, IERR )
+            LWORK_DORMBR_PRT_MN = INT( DUM(1) )
+*
+            CALL DORMBR( 'P', 'R', 'T', N, N, M, DUM(1), N,
+     $                   DUM(1), DUM(1), N, DUM(1), -1, IERR )
+            LWORK_DORMBR_PRT_NN = INT( DUM(1) )
+*
+            CALL DORMBR( 'Q', 'L', 'N', M, M, M, DUM(1), M,
+     $                   DUM(1), DUM(1), M, DUM(1), -1, IERR )
+            LWORK_DORMBR_QLN_MM = INT( DUM(1) )
+*
             IF( N.GE.MNTHR ) THEN
                IF( WNTQN ) THEN
 *
-*                 Path 1t (N much larger than M, JOBZ='N')
+*                 Path 1t (N >> M, JOBZ='N')
 *
-                  WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1,
-     $                    -1 )
-                  WRKBL = MAX( WRKBL, 3*M+2*M*
-     $                    ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
-                  MAXWRK = MAX( WRKBL, BDSPAC+M )
+                  WRKBL = M + LWORK_DGELQF_MN
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DGEBRD_MM )
+                  MAXWRK = MAX( WRKBL, BDSPAC + M )
                   MINWRK = BDSPAC + M
                ELSE IF( WNTQO ) THEN
 *
-*                 Path 2t (N much larger than M, JOBZ='O')
-*
-                  WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
-                  WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,
-     $                    N, M, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*M+2*M*
-     $                    ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*M+M*
-     $                    ILAENV( 1, 'DORMBR', 'QLN', M, M, M, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*M+M*
-     $                    ILAENV( 1, 'DORMBR', 'PRT', M, M, M, -1 ) )
-                  WRKBL = MAX( WRKBL, BDSPAC+3*M )
+*                 Path 2t (N >> M, JOBZ='O')
+*
+                  WRKBL = M + LWORK_DGELQF_MN
+                  WRKBL = MAX( WRKBL,   M + LWORK_DORGLQ_MN )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DGEBRD_MM )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DORMBR_QLN_MM )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DORMBR_PRT_MM )
+                  WRKBL = MAX( WRKBL, 3*M + BDSPAC )
                   MAXWRK = WRKBL + 2*M*M
                   MINWRK = BDSPAC + 2*M*M + 3*M
                ELSE IF( WNTQS ) THEN
 *
-*                 Path 3t (N much larger than M, JOBZ='S')
-*
-                  WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
-                  WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,
-     $                    N, M, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*M+2*M*
-     $                    ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*M+M*
-     $                    ILAENV( 1, 'DORMBR', 'QLN', M, M, M, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*M+M*
-     $                    ILAENV( 1, 'DORMBR', 'PRT', M, M, M, -1 ) )
-                  WRKBL = MAX( WRKBL, BDSPAC+3*M )
+*                 Path 3t (N >> M, JOBZ='S')
+*
+                  WRKBL = M + LWORK_DGELQF_MN
+                  WRKBL = MAX( WRKBL,   M + LWORK_DORGLQ_MN )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DGEBRD_MM )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DORMBR_QLN_MM )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DORMBR_PRT_MM )
+                  WRKBL = MAX( WRKBL, 3*M + BDSPAC )
                   MAXWRK = WRKBL + M*M
                   MINWRK = BDSPAC + M*M + 3*M
                ELSE IF( WNTQA ) THEN
 *
-*                 Path 4t (N much larger than M, JOBZ='A')
-*
-                  WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
-                  WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'DORGLQ', ' ', N,
-     $                    N, M, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*M+2*M*
-     $                    ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*M+M*
-     $                    ILAENV( 1, 'DORMBR', 'QLN', M, M, M, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*M+M*
-     $                    ILAENV( 1, 'DORMBR', 'PRT', M, M, M, -1 ) )
-                  WRKBL = MAX( WRKBL, BDSPAC+3*M )
+*                 Path 4t (N >> M, JOBZ='A')
+*
+                  WRKBL = M + LWORK_DGELQF_MN
+                  WRKBL = MAX( WRKBL,   M + LWORK_DORGLQ_NN )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DGEBRD_MM )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DORMBR_QLN_MM )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DORMBR_PRT_MM )
+                  WRKBL = MAX( WRKBL, 3*M + BDSPAC )
                   MAXWRK = WRKBL + M*M
-                  MINWRK = BDSPAC + M*M + 3*M
+                  MINWRK = M*M + MAX( 3*M + BDSPAC, M + N )
                END IF
             ELSE
 *
-*              Path 5t (N greater than M, but not much larger)
+*              Path 5t (N > M, but not much larger)
 *
-               WRKBL = 3*M + ( M+N )*ILAENV( 1, 'DGEBRD', ' ', M, N, -1,
-     $                 -1 )
+               WRKBL = 3*M + LWORK_DGEBRD_MN
                IF( WNTQN ) THEN
-                  MAXWRK = MAX( WRKBL, BDSPAC+3*M )
+*                 Path 5tn (N > M, jobz='N')
+                  MAXWRK = MAX( WRKBL, 3*M + BDSPAC )
                   MINWRK = 3*M + MAX( N, BDSPAC )
                ELSE IF( WNTQO ) THEN
-                  WRKBL = MAX( WRKBL, 3*M+M*
-     $                    ILAENV( 1, 'DORMBR', 'QLN', M, M, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*M+M*
-     $                    ILAENV( 1, 'DORMBR', 'PRT', M, N, M, -1 ) )
-                  WRKBL = MAX( WRKBL, BDSPAC+3*M )
+*                 Path 5to (N > M, jobz='O')
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DORMBR_QLN_MM )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DORMBR_PRT_MN )
+                  WRKBL = MAX( WRKBL, 3*M + BDSPAC )
                   MAXWRK = WRKBL + M*N
-                  MINWRK = 3*M + MAX( N, M*M+BDSPAC )
+                  MINWRK = 3*M + MAX( N, M*M + BDSPAC )
                ELSE IF( WNTQS ) THEN
-                  WRKBL = MAX( WRKBL, 3*M+M*
-     $                    ILAENV( 1, 'DORMBR', 'QLN', M, M, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*M+M*
-     $                    ILAENV( 1, 'DORMBR', 'PRT', M, N, M, -1 ) )
-                  MAXWRK = MAX( WRKBL, BDSPAC+3*M )
+*                 Path 5ts (N > M, jobz='S')
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DORMBR_QLN_MM )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DORMBR_PRT_MN )
+                  MAXWRK = MAX( WRKBL, 3*M + BDSPAC )
                   MINWRK = 3*M + MAX( N, BDSPAC )
                ELSE IF( WNTQA ) THEN
-                  WRKBL = MAX( WRKBL, 3*M+M*
-     $                    ILAENV( 1, 'DORMBR', 'QLN', M, M, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*M+M*
-     $                    ILAENV( 1, 'DORMBR', 'PRT', N, N, M, -1 ) )
-                  MAXWRK = MAX( WRKBL, BDSPAC+3*M )
+*                 Path 5ta (N > M, jobz='A')
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DORMBR_QLN_MM )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DORMBR_PRT_NN )
+                  MAXWRK = MAX( WRKBL, 3*M + BDSPAC )
                   MINWRK = 3*M + MAX( N, BDSPAC )
                END IF
             END IF
          END IF
+         
          MAXWRK = MAX( MAXWRK, MINWRK )
          WORK( 1 ) = MAXWRK
 *
 *
             IF( WNTQN ) THEN
 *
-*              Path 1 (M much larger than N, JOBZ='N')
+*              Path 1 (M >> N, JOBZ='N')
 *              No singular vectors to be computed
 *
                ITAU = 1
                NWORK = ITAU + N
 *
 *              Compute A=Q*R
-*              (Workspace: need 2*N, prefer N+N*NB)
+*              Workspace: need   N [tau] + N    [work]
+*              Workspace: prefer N [tau] + N*NB [work]
 *
                CALL DGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
 *              Zero out below R
 *
                NWORK = ITAUP + N
 *
 *              Bidiagonalize R in A
-*              (Workspace: need 4*N, prefer 3*N+2*N*NB)
+*              Workspace: need   3*N [e, tauq, taup] + N      [work]
+*              Workspace: prefer 3*N [e, tauq, taup] + 2*N*NB [work]
 *
                CALL DGEBRD( N, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
      $                      WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
                NWORK = IE + N
 *
 *              Perform bidiagonal SVD, computing singular values only
-*              (Workspace: need N+BDSPAC)
+*              Workspace: need   N [e] + BDSPAC
 *
                CALL DBDSDC( 'U', 'N', N, S, WORK( IE ), DUM, 1, DUM, 1,
      $                      DUM, IDUM, WORK( NWORK ), IWORK, INFO )
 *
             ELSE IF( WNTQO ) THEN
 *
-*              Path 2 (M much larger than N, JOBZ = 'O')
+*              Path 2 (M >> N, JOBZ = 'O')
 *              N left singular vectors to be overwritten on A and
 *              N right singular vectors to be computed in VT
 *
 *
 *              WORK(IR) is LDWRKR by N
 *
-               IF( LWORK.GE.LDA*N+N*N+3*N+BDSPAC ) THEN
+               IF( LWORK .GE. LDA*N + N*N + 3*N + BDSPAC ) THEN
                   LDWRKR = LDA
                ELSE
-                  LDWRKR = ( LWORK-N*N-3*N-BDSPAC ) / N
+                  LDWRKR = ( LWORK - N*N - 3*N - BDSPAC ) / N
                END IF
                ITAU = IR + LDWRKR*N
                NWORK = ITAU + N
 *
 *              Compute A=Q*R
-*              (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*              Workspace: need   N*N [R] + N [tau] + N    [work]
+*              Workspace: prefer N*N [R] + N [tau] + N*NB [work]
 *
                CALL DGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
 *              Copy R to WORK(IR), zeroing out below it
 *
                CALL DLACPY( 'U', N, N, A, LDA, WORK( IR ), LDWRKR )
-               CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, WORK( IR+1 ),
+               CALL DLASET( 'L', N - 1, N - 1, ZERO, ZERO, WORK(IR+1),
      $                      LDWRKR )
 *
 *              Generate Q in A
-*              (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*              Workspace: need   N*N [R] + N [tau] + N    [work]
+*              Workspace: prefer N*N [R] + N [tau] + N*NB [work]
 *
                CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
-     $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
+     $                      WORK( NWORK ), LWORK - NWORK + 1, IERR )
                IE = ITAU
                ITAUQ = IE + N
                ITAUP = ITAUQ + N
                NWORK = ITAUP + N
 *
-*              Bidiagonalize R in VT, copying result to WORK(IR)
-*              (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
+*              Bidiagonalize R in WORK(IR)
+*              Workspace: need   N*N [R] + 3*N [e, tauq, taup] + N      [work]
+*              Workspace: prefer N*N [R] + 3*N [e, tauq, taup] + 2*N*NB [work]
 *
                CALL DGEBRD( N, N, WORK( IR ), LDWRKR, S, WORK( IE ),
      $                      WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
 *              WORK(IU) is N by N
 *
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in WORK(IU) and computing right
 *              singular vectors of bidiagonal matrix in VT
-*              (Workspace: need N+N*N+BDSPAC)
+*              Workspace: need   N*N [R] + 3*N [e, tauq, taup] + N*N [U] + BDSPAC
 *
                CALL DBDSDC( 'U', 'I', N, S, WORK( IE ), WORK( IU ), N,
      $                      VT, LDVT, DUM, IDUM, WORK( NWORK ), IWORK,
 *
 *              Overwrite WORK(IU) by left singular vectors of R
 *              and VT by right singular vectors of R
-*              (Workspace: need 2*N*N+3*N, prefer 2*N*N+2*N+N*NB)
+*              Workspace: need   N*N [R] + 3*N [e, tauq, taup] + N*N [U] + N    [work]
+*              Workspace: prefer N*N [R] + 3*N [e, tauq, taup] + N*N [U] + N*NB [work]
 *
                CALL DORMBR( 'Q', 'L', 'N', N, N, N, WORK( IR ), LDWRKR,
      $                      WORK( ITAUQ ), WORK( IU ), N, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
                CALL DORMBR( 'P', 'R', 'T', N, N, N, WORK( IR ), LDWRKR,
      $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
 *              Multiply Q in A by left singular vectors of R in
 *              WORK(IU), storing result in WORK(IR) and copying to A
-*              (Workspace: need 2*N*N, prefer N*N+M*N)
+*              Workspace: need   N*N [R] + 3*N [e, tauq, taup] + N*N [U]
+*              Workspace: prefer M*N [R] + 3*N [e, tauq, taup] + N*N [U]
 *
                DO 10 I = 1, M, LDWRKR
-                  CHUNK = MIN( M-I+1, LDWRKR )
+                  CHUNK = MIN( M - I + 1, LDWRKR )
                   CALL DGEMM( 'N', 'N', CHUNK, N, N, ONE, A( I, 1 ),
      $                        LDA, WORK( IU ), N, ZERO, WORK( IR ),
      $                        LDWRKR )
 *
             ELSE IF( WNTQS ) THEN
 *
-*              Path 3 (M much larger than N, JOBZ='S')
+*              Path 3 (M >> N, JOBZ='S')
 *              N left singular vectors to be computed in U and
 *              N right singular vectors to be computed in VT
 *
                NWORK = ITAU + N
 *
 *              Compute A=Q*R
-*              (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*              Workspace: need   N*N [R] + N [tau] + N    [work]
+*              Workspace: prefer N*N [R] + N [tau] + N*NB [work]
 *
                CALL DGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
 *              Copy R to WORK(IR), zeroing out below it
 *
                CALL DLACPY( 'U', N, N, A, LDA, WORK( IR ), LDWRKR )
-               CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, WORK( IR+1 ),
+               CALL DLASET( 'L', N - 1, N - 1, ZERO, ZERO, WORK(IR+1),
      $                      LDWRKR )
 *
 *              Generate Q in A
-*              (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*              Workspace: need   N*N [R] + N [tau] + N    [work]
+*              Workspace: prefer N*N [R] + N [tau] + N*NB [work]
 *
                CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
-     $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
+     $                      WORK( NWORK ), LWORK - NWORK + 1, IERR )
                IE = ITAU
                ITAUQ = IE + N
                ITAUP = ITAUQ + N
                NWORK = ITAUP + N
 *
 *              Bidiagonalize R in WORK(IR)
-*              (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
+*              Workspace: need   N*N [R] + 3*N [e, tauq, taup] + N      [work]
+*              Workspace: prefer N*N [R] + 3*N [e, tauq, taup] + 2*N*NB [work]
 *
                CALL DGEBRD( N, N, WORK( IR ), LDWRKR, S, WORK( IE ),
      $                      WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagoal matrix in U and computing right singular
 *              vectors of bidiagonal matrix in VT
-*              (Workspace: need N+BDSPAC)
+*              Workspace: need   N*N [R] + 3*N [e, tauq, taup] + BDSPAC
 *
                CALL DBDSDC( 'U', 'I', N, S, WORK( IE ), U, LDU, VT,
      $                      LDVT, DUM, IDUM, WORK( NWORK ), IWORK,
 *
 *              Overwrite U by left singular vectors of R and VT
 *              by right singular vectors of R
-*              (Workspace: need N*N+3*N, prefer N*N+2*N+N*NB)
+*              Workspace: need   N*N [R] + 3*N [e, tauq, taup] + N    [work]
+*              Workspace: prefer N*N [R] + 3*N [e, tauq, taup] + N*NB [work]
 *
                CALL DORMBR( 'Q', 'L', 'N', N, N, N, WORK( IR ), LDWRKR,
      $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
                CALL DORMBR( 'P', 'R', 'T', N, N, N, WORK( IR ), LDWRKR,
      $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
 *              Multiply Q in A by left singular vectors of R in
 *              WORK(IR), storing result in U
-*              (Workspace: need N*N)
+*              Workspace: need   N*N [R]
 *
                CALL DLACPY( 'F', N, N, U, LDU, WORK( IR ), LDWRKR )
                CALL DGEMM( 'N', 'N', M, N, N, ONE, A, LDA, WORK( IR ),
 *
             ELSE IF( WNTQA ) THEN
 *
-*              Path 4 (M much larger than N, JOBZ='A')
+*              Path 4 (M >> N, JOBZ='A')
 *              M left singular vectors to be computed in U and
 *              N right singular vectors to be computed in VT
 *
                NWORK = ITAU + N
 *
 *              Compute A=Q*R, copying result to U
-*              (Workspace: need N*N+N+M, prefer N*N+N+M*NB)
+*              Workspace: need   N*N [U] + N [tau] + N    [work]
+*              Workspace: prefer N*N [U] + N [tau] + N*NB [work]
 *
                CALL DGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
                CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
 *
 *              Generate Q in U
-*              (Workspace: need N*N+N+M, prefer N*N+N+M*NB)
+*              Workspace: need   N*N [U] + N [tau] + M    [work]
+*              Workspace: prefer N*N [U] + N [tau] + M*NB [work]
                CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
-     $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
+     $                      WORK( NWORK ), LWORK - NWORK + 1, IERR )
 *
 *              Produce R in A, zeroing out other entries
 *
                NWORK = ITAUP + N
 *
 *              Bidiagonalize R in A
-*              (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
+*              Workspace: need   N*N [U] + 3*N [e, tauq, taup] + N      [work]
+*              Workspace: prefer N*N [U] + 3*N [e, tauq, taup] + 2*N*NB [work]
 *
                CALL DGEBRD( N, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
      $                      WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in WORK(IU) and computing right
 *              singular vectors of bidiagonal matrix in VT
-*              (Workspace: need N+N*N+BDSPAC)
+*              Workspace: need   N*N [U] + 3*N [e, tauq, taup] + BDSPAC
 *
                CALL DBDSDC( 'U', 'I', N, S, WORK( IE ), WORK( IU ), N,
      $                      VT, LDVT, DUM, IDUM, WORK( NWORK ), IWORK,
 *
 *              Overwrite WORK(IU) by left singular vectors of R and VT
 *              by right singular vectors of R
-*              (Workspace: need N*N+3*N, prefer N*N+2*N+N*NB)
+*              Workspace: need   N*N [U] + 3*N [e, tauq, taup] + N    [work]
+*              Workspace: prefer N*N [U] + 3*N [e, tauq, taup] + N*NB [work]
 *
                CALL DORMBR( 'Q', 'L', 'N', N, N, N, A, LDA,
      $                      WORK( ITAUQ ), WORK( IU ), LDWRKU,
-     $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
+     $                      WORK( NWORK ), LWORK - NWORK + 1, IERR )
                CALL DORMBR( 'P', 'R', 'T', N, N, N, A, LDA,
      $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
 *              Multiply Q in U by left singular vectors of R in
 *              WORK(IU), storing result in A
-*              (Workspace: need N*N)
+*              Workspace: need   N*N [U]
 *
                CALL DGEMM( 'N', 'N', M, N, N, ONE, U, LDU, WORK( IU ),
      $                     LDWRKU, ZERO, A, LDA )
 *
 *           M .LT. MNTHR
 *
-*           Path 5 (M at least N, but not much larger)
+*           Path 5 (M >= N, but not much larger)
 *           Reduce to bidiagonal form without QR decomposition
 *
             IE = 1
             NWORK = ITAUP + N
 *
 *           Bidiagonalize A
-*           (Workspace: need 3*N+M, prefer 3*N+(M+N)*NB)
+*           Workspace: need   3*N [e, tauq, taup] + M        [work]
+*           Workspace: prefer 3*N [e, tauq, taup] + (M+N)*NB [work]
 *
             CALL DGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
      $                   WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
      $                   IERR )
             IF( WNTQN ) THEN
 *
+*              Path 5n (M >= N, JOBZ='N')
 *              Perform bidiagonal SVD, only computing singular values
-*              (Workspace: need N+BDSPAC)
+*              Workspace: need   3*N [e, tauq, taup] + BDSPAC
 *
                CALL DBDSDC( 'U', 'N', N, S, WORK( IE ), DUM, 1, DUM, 1,
      $                      DUM, IDUM, WORK( NWORK ), IWORK, INFO )
             ELSE IF( WNTQO ) THEN
+*              Path 5o (M >= N, JOBZ='O')
                IU = NWORK
-               IF( LWORK.GE.M*N+3*N+BDSPAC ) THEN
+               IF( LWORK .GE. M*N + 3*N + BDSPAC ) THEN
 *
 *                 WORK( IU ) is M by N
 *
                   NWORK = IU + LDWRKU*N
                   CALL DLASET( 'F', M, N, ZERO, ZERO, WORK( IU ),
      $                         LDWRKU )
+*                 IR is unused; silence compile warnings
+                  IR = -1
                ELSE
 *
 *                 WORK( IU ) is N by N
 *                 WORK(IR) is LDWRKR by N
 *
                   IR = NWORK
-                  LDWRKR = ( LWORK-N*N-3*N ) / N
+                  LDWRKR = ( LWORK - N*N - 3*N ) / N
                END IF
                NWORK = IU + LDWRKU*N
 *
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in WORK(IU) and computing right
 *              singular vectors of bidiagonal matrix in VT
-*              (Workspace: need N+N*N+BDSPAC)
+*              Workspace: need   3*N [e, tauq, taup] + N*N [U] + BDSPAC
 *
                CALL DBDSDC( 'U', 'I', N, S, WORK( IE ), WORK( IU ),
      $                      LDWRKU, VT, LDVT, DUM, IDUM, WORK( NWORK ),
      $                      IWORK, INFO )
 *
 *              Overwrite VT by right singular vectors of A
-*              (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*              Workspace: need   3*N [e, tauq, taup] + N*N [U] + N    [work]
+*              Workspace: prefer 3*N [e, tauq, taup] + N*N [U] + N*NB [work]
 *
                CALL DORMBR( 'P', 'R', 'T', N, N, N, A, LDA,
      $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
-               IF( LWORK.GE.M*N+3*N+BDSPAC ) THEN
+               IF( LWORK .GE. M*N + 3*N + BDSPAC ) THEN
 *
+*                 Path 5o-fast
 *                 Overwrite WORK(IU) by left singular vectors of A
-*                 (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                 Workspace: need   3*N [e, tauq, taup] + M*N [U] + N    [work]
+*                 Workspace: prefer 3*N [e, tauq, taup] + M*N [U] + N*NB [work]
 *
                   CALL DORMBR( 'Q', 'L', 'N', M, N, N, A, LDA,
      $                         WORK( ITAUQ ), WORK( IU ), LDWRKU,
-     $                         WORK( NWORK ), LWORK-NWORK+1, IERR )
+     $                         WORK( NWORK ), LWORK - NWORK + 1, IERR )
 *
 *                 Copy left singular vectors of A from WORK(IU) to A
 *
                   CALL DLACPY( 'F', M, N, WORK( IU ), LDWRKU, A, LDA )
                ELSE
 *
+*                 Path 5o-slow
 *                 Generate Q in A
-*                 (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                 Workspace: need   3*N [e, tauq, taup] + N*N [U] + N    [work]
+*                 Workspace: prefer 3*N [e, tauq, taup] + N*N [U] + N*NB [work]
 *
                   CALL DORGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
-     $                         WORK( NWORK ), LWORK-NWORK+1, IERR )
+     $                         WORK( NWORK ), LWORK - NWORK + 1, IERR )
 *
 *                 Multiply Q in A by left singular vectors of
 *                 bidiagonal matrix in WORK(IU), storing result in
 *                 WORK(IR) and copying to A
-*                 (Workspace: need 2*N*N, prefer N*N+M*N)
+*                 Workspace: need   3*N [e, tauq, taup] + N*N [U] + NB*N [R]
+*                 Workspace: prefer 3*N [e, tauq, taup] + N*N [U] + M*N  [R]
 *
                   DO 20 I = 1, M, LDWRKR
-                     CHUNK = MIN( M-I+1, LDWRKR )
+                     CHUNK = MIN( M - I + 1, LDWRKR )
                      CALL DGEMM( 'N', 'N', CHUNK, N, N, ONE, A( I, 1 ),
      $                           LDA, WORK( IU ), LDWRKU, ZERO,
      $                           WORK( IR ), LDWRKR )
 *
             ELSE IF( WNTQS ) THEN
 *
+*              Path 5s (M >= N, JOBZ='S')
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in U and computing right singular
 *              vectors of bidiagonal matrix in VT
-*              (Workspace: need N+BDSPAC)
+*              Workspace: need   3*N [e, tauq, taup] + BDSPAC
 *
                CALL DLASET( 'F', M, N, ZERO, ZERO, U, LDU )
                CALL DBDSDC( 'U', 'I', N, S, WORK( IE ), U, LDU, VT,
 *
 *              Overwrite U by left singular vectors of A and VT
 *              by right singular vectors of A
-*              (Workspace: need 3*N, prefer 2*N+N*NB)
+*              Workspace: need   3*N [e, tauq, taup] + N    [work]
+*              Workspace: prefer 3*N [e, tauq, taup] + N*NB [work]
 *
                CALL DORMBR( 'Q', 'L', 'N', M, N, N, A, LDA,
      $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
                CALL DORMBR( 'P', 'R', 'T', N, N, N, A, LDA,
      $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
             ELSE IF( WNTQA ) THEN
 *
+*              Path 5a (M >= N, JOBZ='A')
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in U and computing right singular
 *              vectors of bidiagonal matrix in VT
-*              (Workspace: need N+BDSPAC)
+*              Workspace: need   3*N [e, tauq, taup] + BDSPAC
 *
                CALL DLASET( 'F', M, M, ZERO, ZERO, U, LDU )
                CALL DBDSDC( 'U', 'I', N, S, WORK( IE ), U, LDU, VT,
 *              Set the right corner of U to identity matrix
 *
                IF( M.GT.N ) THEN
-                  CALL DLASET( 'F', M-N, M-N, ZERO, ONE, U( N+1, N+1 ),
+                  CALL DLASET( 'F', M - N, M - N, ZERO, ONE, U(N+1,N+1),
      $                         LDU )
                END IF
 *
 *              Overwrite U by left singular vectors of A and VT
 *              by right singular vectors of A
-*              (Workspace: need N*N+2*N+M, prefer N*N+2*N+M*NB)
+*              Workspace: need   3*N [e, tauq, taup] + M    [work]
+*              Workspace: prefer 3*N [e, tauq, taup] + M*NB [work]
 *
                CALL DORMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
      $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
                CALL DORMBR( 'P', 'R', 'T', N, N, M, A, LDA,
      $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
             END IF
 *
          END IF
 *
             IF( WNTQN ) THEN
 *
-*              Path 1t (N much larger than M, JOBZ='N')
+*              Path 1t (N >> M, JOBZ='N')
 *              No singular vectors to be computed
 *
                ITAU = 1
                NWORK = ITAU + M
 *
 *              Compute A=L*Q
-*              (Workspace: need 2*M, prefer M+M*NB)
+*              Workspace: need   M [tau] + M [work]
+*              Workspace: prefer M [tau] + M*NB [work]
 *
                CALL DGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
 *              Zero out above L
 *
                NWORK = ITAUP + M
 *
 *              Bidiagonalize L in A
-*              (Workspace: need 4*M, prefer 3*M+2*M*NB)
+*              Workspace: need   3*M [e, tauq, taup] + M      [work]
+*              Workspace: prefer 3*M [e, tauq, taup] + 2*M*NB [work]
 *
                CALL DGEBRD( M, M, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
      $                      WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
                NWORK = IE + M
 *
 *              Perform bidiagonal SVD, computing singular values only
-*              (Workspace: need M+BDSPAC)
+*              Workspace: need   M [e] + BDSPAC
 *
                CALL DBDSDC( 'U', 'N', M, S, WORK( IE ), DUM, 1, DUM, 1,
      $                      DUM, IDUM, WORK( NWORK ), IWORK, INFO )
 *
             ELSE IF( WNTQO ) THEN
 *
-*              Path 2t (N much larger than M, JOBZ='O')
+*              Path 2t (N >> M, JOBZ='O')
 *              M right singular vectors to be overwritten on A and
 *              M left singular vectors to be computed in U
 *
                IVT = 1
 *
-*              IVT is M by M
+*              WORK(IVT) is M by M
+*              WORK(IL)  is M by M; it is later resized to M by chunk for gemm
 *
                IL = IVT + M*M
-               IF( LWORK.GE.M*N+M*M+3*M+BDSPAC ) THEN
-*
-*                 WORK(IL) is M by N
-*
+               IF( LWORK .GE. M*N + M*M + 3*M + BDSPAC ) THEN
                   LDWRKL = M
                   CHUNK = N
                ELSE
                   LDWRKL = M
-                  CHUNK = ( LWORK-M*M ) / M
+                  CHUNK = ( LWORK - M*M ) / M
                END IF
                ITAU = IL + LDWRKL*M
                NWORK = ITAU + M
 *
 *              Compute A=L*Q
-*              (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*              Workspace: need   M*M [VT] + M*M [L] + M [tau] + M    [work]
+*              Workspace: prefer M*M [VT] + M*M [L] + M [tau] + M*NB [work]
 *
                CALL DGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
 *              Copy L to WORK(IL), zeroing about above it
 *
                CALL DLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWRKL )
-               CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
-     $                      WORK( IL+LDWRKL ), LDWRKL )
+               CALL DLASET( 'U', M - 1, M - 1, ZERO, ZERO,
+     $                      WORK( IL + LDWRKL ), LDWRKL )
 *
 *              Generate Q in A
-*              (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*              Workspace: need   M*M [VT] + M*M [L] + M [tau] + M    [work]
+*              Workspace: prefer M*M [VT] + M*M [L] + M [tau] + M*NB [work]
 *
                CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
-     $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
+     $                      WORK( NWORK ), LWORK - NWORK + 1, IERR )
                IE = ITAU
                ITAUQ = IE + M
                ITAUP = ITAUQ + M
                NWORK = ITAUP + M
 *
 *              Bidiagonalize L in WORK(IL)
-*              (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
+*              Workspace: need   M*M [VT] + M*M [L] + 3*M [e, tauq, taup] + M      [work]
+*              Workspace: prefer M*M [VT] + M*M [L] + 3*M [e, tauq, taup] + 2*M*NB [work]
 *
                CALL DGEBRD( M, M, WORK( IL ), LDWRKL, S, WORK( IE ),
      $                      WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in U, and computing right singular
 *              vectors of bidiagonal matrix in WORK(IVT)
-*              (Workspace: need M+M*M+BDSPAC)
+*              Workspace: need   M*M [VT] + M*M [L] + 3*M [e, tauq, taup] + BDSPAC
 *
                CALL DBDSDC( 'U', 'I', M, S, WORK( IE ), U, LDU,
      $                      WORK( IVT ), M, DUM, IDUM, WORK( NWORK ),
 *
 *              Overwrite U by left singular vectors of L and WORK(IVT)
 *              by right singular vectors of L
-*              (Workspace: need 2*M*M+3*M, prefer 2*M*M+2*M+M*NB)
+*              Workspace: need   M*M [VT] + M*M [L] + 3*M [e, tauq, taup] + M    [work]
+*              Workspace: prefer M*M [VT] + M*M [L] + 3*M [e, tauq, taup] + M*NB [work]
 *
                CALL DORMBR( 'Q', 'L', 'N', M, M, M, WORK( IL ), LDWRKL,
      $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
                CALL DORMBR( 'P', 'R', 'T', M, M, M, WORK( IL ), LDWRKL,
      $                      WORK( ITAUP ), WORK( IVT ), M,
-     $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
+     $                      WORK( NWORK ), LWORK - NWORK + 1, IERR )
 *
 *              Multiply right singular vectors of L in WORK(IVT) by Q
 *              in A, storing result in WORK(IL) and copying to A
-*              (Workspace: need 2*M*M, prefer M*M+M*N)
+*              Workspace: need   M*M [VT] + M*M [L]
+*              Workspace: prefer M*M [VT] + M*N [L]
+*              At this point, L is resized as M by chunk.
 *
                DO 30 I = 1, N, CHUNK
-                  BLK = MIN( N-I+1, CHUNK )
+                  BLK = MIN( N - I + 1, CHUNK )
                   CALL DGEMM( 'N', 'N', M, BLK, M, ONE, WORK( IVT ), M,
      $                        A( 1, I ), LDA, ZERO, WORK( IL ), LDWRKL )
                   CALL DLACPY( 'F', M, BLK, WORK( IL ), LDWRKL,
 *
             ELSE IF( WNTQS ) THEN
 *
-*              Path 3t (N much larger than M, JOBZ='S')
+*              Path 3t (N >> M, JOBZ='S')
 *              M right singular vectors to be computed in VT and
 *              M left singular vectors to be computed in U
 *
                NWORK = ITAU + M
 *
 *              Compute A=L*Q
-*              (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*              Workspace: need   M*M [L] + M [tau] + M    [work]
+*              Workspace: prefer M*M [L] + M [tau] + M*NB [work]
 *
                CALL DGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
 *              Copy L to WORK(IL), zeroing out above it
 *
                CALL DLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWRKL )
-               CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
-     $                      WORK( IL+LDWRKL ), LDWRKL )
+               CALL DLASET( 'U', M - 1, M - 1, ZERO, ZERO,
+     $                      WORK( IL + LDWRKL ), LDWRKL )
 *
 *              Generate Q in A
-*              (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*              Workspace: need   M*M [L] + M [tau] + M    [work]
+*              Workspace: prefer M*M [L] + M [tau] + M*NB [work]
 *
                CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
-     $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
+     $                      WORK( NWORK ), LWORK - NWORK + 1, IERR )
                IE = ITAU
                ITAUQ = IE + M
                ITAUP = ITAUQ + M
                NWORK = ITAUP + M
 *
-*              Bidiagonalize L in WORK(IU), copying result to U
-*              (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
+*              Bidiagonalize L in WORK(IU).
+*              Workspace: need   M*M [L] + 3*M [e, tauq, taup] + M      [work]
+*              Workspace: prefer M*M [L] + 3*M [e, tauq, taup] + 2*M*NB [work]
 *
                CALL DGEBRD( M, M, WORK( IL ), LDWRKL, S, WORK( IE ),
      $                      WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in U and computing right singular
 *              vectors of bidiagonal matrix in VT
-*              (Workspace: need M+BDSPAC)
+*              Workspace: need   M*M [L] + 3*M [e, tauq, taup] + BDSPAC
 *
                CALL DBDSDC( 'U', 'I', M, S, WORK( IE ), U, LDU, VT,
      $                      LDVT, DUM, IDUM, WORK( NWORK ), IWORK,
 *
 *              Overwrite U by left singular vectors of L and VT
 *              by right singular vectors of L
-*              (Workspace: need M*M+3*M, prefer M*M+2*M+M*NB)
+*              Workspace: need   M*M [L] + 3*M [e, tauq, taup] + M    [work]
+*              Workspace: prefer M*M [L] + 3*M [e, tauq, taup] + M*NB [work]
 *
                CALL DORMBR( 'Q', 'L', 'N', M, M, M, WORK( IL ), LDWRKL,
      $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
                CALL DORMBR( 'P', 'R', 'T', M, M, M, WORK( IL ), LDWRKL,
      $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
 *              Multiply right singular vectors of L in WORK(IL) by
 *              Q in A, storing result in VT
-*              (Workspace: need M*M)
+*              Workspace: need   M*M [L]
 *
                CALL DLACPY( 'F', M, M, VT, LDVT, WORK( IL ), LDWRKL )
                CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IL ), LDWRKL,
 *
             ELSE IF( WNTQA ) THEN
 *
-*              Path 4t (N much larger than M, JOBZ='A')
+*              Path 4t (N >> M, JOBZ='A')
 *              N right singular vectors to be computed in VT and
 *              M left singular vectors to be computed in U
 *
                NWORK = ITAU + M
 *
 *              Compute A=L*Q, copying result to VT
-*              (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*              Workspace: need   M*M [VT] + M [tau] + M    [work]
+*              Workspace: prefer M*M [VT] + M [tau] + M*NB [work]
 *
                CALL DGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
                CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
 *
 *              Generate Q in VT
-*              (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*              Workspace: need   M*M [VT] + M [tau] + N    [work]
+*              Workspace: prefer M*M [VT] + M [tau] + N*NB [work]
 *
                CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
-     $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
+     $                      WORK( NWORK ), LWORK - NWORK + 1, IERR )
 *
 *              Produce L in A, zeroing out other entries
 *
                NWORK = ITAUP + M
 *
 *              Bidiagonalize L in A
-*              (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
+*              Workspace: need   M*M [VT] + 3*M [e, tauq, taup] + M      [work]
+*              Workspace: prefer M*M [VT] + 3*M [e, tauq, taup] + 2*M*NB [work]
 *
                CALL DGEBRD( M, M, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
      $                      WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in U and computing right singular
 *              vectors of bidiagonal matrix in WORK(IVT)
-*              (Workspace: need M+M*M+BDSPAC)
+*              Workspace: need   M*M [VT] + 3*M [e, tauq, taup] + BDSPAC
 *
                CALL DBDSDC( 'U', 'I', M, S, WORK( IE ), U, LDU,
      $                      WORK( IVT ), LDWKVT, DUM, IDUM,
 *
 *              Overwrite U by left singular vectors of L and WORK(IVT)
 *              by right singular vectors of L
-*              (Workspace: need M*M+3*M, prefer M*M+2*M+M*NB)
+*              Workspace: need   M*M [VT] + 3*M [e, tauq, taup]+ M    [work]
+*              Workspace: prefer M*M [VT] + 3*M [e, tauq, taup]+ M*NB [work]
 *
                CALL DORMBR( 'Q', 'L', 'N', M, M, M, A, LDA,
      $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
                CALL DORMBR( 'P', 'R', 'T', M, M, M, A, LDA,
      $                      WORK( ITAUP ), WORK( IVT ), LDWKVT,
-     $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
+     $                      WORK( NWORK ), LWORK - NWORK + 1, IERR )
 *
 *              Multiply right singular vectors of L in WORK(IVT) by
 *              Q in VT, storing result in A
-*              (Workspace: need M*M)
+*              Workspace: need   M*M [VT]
 *
                CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IVT ), LDWKVT,
      $                     VT, LDVT, ZERO, A, LDA )
 *
 *           N .LT. MNTHR
 *
-*           Path 5t (N greater than M, but not much larger)
+*           Path 5t (N > M, but not much larger)
 *           Reduce to bidiagonal form without LQ decomposition
 *
             IE = 1
             NWORK = ITAUP + M
 *
 *           Bidiagonalize A
-*           (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB)
+*           Workspace: need   3*M [e, tauq, taup] + N        [work]
+*           Workspace: prefer 3*M [e, tauq, taup] + (M+N)*NB [work]
 *
             CALL DGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
      $                   WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
      $                   IERR )
             IF( WNTQN ) THEN
 *
+*              Path 5tn (N > M, JOBZ='N')
 *              Perform bidiagonal SVD, only computing singular values
-*              (Workspace: need M+BDSPAC)
+*              Workspace: need   3*M [e, tauq, taup] + BDSPAC
 *
                CALL DBDSDC( 'L', 'N', M, S, WORK( IE ), DUM, 1, DUM, 1,
      $                      DUM, IDUM, WORK( NWORK ), IWORK, INFO )
             ELSE IF( WNTQO ) THEN
+*              Path 5to (N > M, JOBZ='O')
                LDWKVT = M
                IVT = NWORK
-               IF( LWORK.GE.M*N+3*M+BDSPAC ) THEN
+               IF( LWORK .GE. M*N + 3*M + BDSPAC ) THEN
 *
 *                 WORK( IVT ) is M by N
 *
                   CALL DLASET( 'F', M, N, ZERO, ZERO, WORK( IVT ),
      $                         LDWKVT )
                   NWORK = IVT + LDWKVT*N
+*                 IL is unused; silence compile warnings
+                  IL = -1
                ELSE
 *
 *                 WORK( IVT ) is M by M
 *
 *                 WORK(IL) is M by CHUNK
 *
-                  CHUNK = ( LWORK-M*M-3*M ) / M
+                  CHUNK = ( LWORK - M*M - 3*M ) / M
                END IF
 *
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in U and computing right singular
 *              vectors of bidiagonal matrix in WORK(IVT)
-*              (Workspace: need M*M+BDSPAC)
+*              Workspace: need   3*M [e, tauq, taup] + M*M [VT] + BDSPAC
 *
                CALL DBDSDC( 'L', 'I', M, S, WORK( IE ), U, LDU,
      $                      WORK( IVT ), LDWKVT, DUM, IDUM,
      $                      WORK( NWORK ), IWORK, INFO )
 *
 *              Overwrite U by left singular vectors of A
-*              (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*              Workspace: need   3*M [e, tauq, taup] + M*M [VT] + M    [work]
+*              Workspace: prefer 3*M [e, tauq, taup] + M*M [VT] + M*NB [work]
 *
                CALL DORMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
      $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
-               IF( LWORK.GE.M*N+3*M+BDSPAC ) THEN
+               IF( LWORK .GE. M*N + 3*M + BDSPAC ) THEN
 *
+*                 Path 5to-fast
 *                 Overwrite WORK(IVT) by left singular vectors of A
-*                 (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                 Workspace: need   3*M [e, tauq, taup] + M*N [VT] + M    [work]
+*                 Workspace: prefer 3*M [e, tauq, taup] + M*N [VT] + M*NB [work]
 *
                   CALL DORMBR( 'P', 'R', 'T', M, N, M, A, LDA,
      $                         WORK( ITAUP ), WORK( IVT ), LDWKVT,
-     $                         WORK( NWORK ), LWORK-NWORK+1, IERR )
+     $                         WORK( NWORK ), LWORK - NWORK + 1, IERR )
 *
 *                 Copy right singular vectors of A from WORK(IVT) to A
 *
                   CALL DLACPY( 'F', M, N, WORK( IVT ), LDWKVT, A, LDA )
                ELSE
 *
+*                 Path 5to-slow
 *                 Generate P**T in A
-*                 (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                 Workspace: need   3*M [e, tauq, taup] + M*M [VT] + M    [work]
+*                 Workspace: prefer 3*M [e, tauq, taup] + M*M [VT] + M*NB [work]
 *
                   CALL DORGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
-     $                         WORK( NWORK ), LWORK-NWORK+1, IERR )
+     $                         WORK( NWORK ), LWORK - NWORK + 1, IERR )
 *
 *                 Multiply Q in A by right singular vectors of
 *                 bidiagonal matrix in WORK(IVT), storing result in
 *                 WORK(IL) and copying to A
-*                 (Workspace: need 2*M*M, prefer M*M+M*N)
+*                 Workspace: need   3*M [e, tauq, taup] + M*M [VT] + M*NB [L]
+*                 Workspace: prefer 3*M [e, tauq, taup] + M*M [VT] + M*N  [L]
 *
                   DO 40 I = 1, N, CHUNK
-                     BLK = MIN( N-I+1, CHUNK )
+                     BLK = MIN( N - I + 1, CHUNK )
                      CALL DGEMM( 'N', 'N', M, BLK, M, ONE, WORK( IVT ),
      $                           LDWKVT, A( 1, I ), LDA, ZERO,
      $                           WORK( IL ), M )
                END IF
             ELSE IF( WNTQS ) THEN
 *
+*              Path 5ts (N > M, JOBZ='S')
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in U and computing right singular
 *              vectors of bidiagonal matrix in VT
-*              (Workspace: need M+BDSPAC)
+*              Workspace: need   3*M [e, tauq, taup] + BDSPAC
 *
                CALL DLASET( 'F', M, N, ZERO, ZERO, VT, LDVT )
                CALL DBDSDC( 'L', 'I', M, S, WORK( IE ), U, LDU, VT,
 *
 *              Overwrite U by left singular vectors of A and VT
 *              by right singular vectors of A
-*              (Workspace: need 3*M, prefer 2*M+M*NB)
+*              Workspace: need   3*M [e, tauq, taup] + M    [work]
+*              Workspace: prefer 3*M [e, tauq, taup] + M*NB [work]
 *
                CALL DORMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
      $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
                CALL DORMBR( 'P', 'R', 'T', M, N, M, A, LDA,
      $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
             ELSE IF( WNTQA ) THEN
 *
+*              Path 5ta (N > M, JOBZ='A')
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in U and computing right singular
 *              vectors of bidiagonal matrix in VT
-*              (Workspace: need M+BDSPAC)
+*              Workspace: need   3*M [e, tauq, taup] + BDSPAC
 *
                CALL DLASET( 'F', N, N, ZERO, ZERO, VT, LDVT )
                CALL DBDSDC( 'L', 'I', M, S, WORK( IE ), U, LDU, VT,
 *              Set the right corner of VT to identity matrix
 *
                IF( N.GT.M ) THEN
-                  CALL DLASET( 'F', N-M, N-M, ZERO, ONE, VT( M+1, M+1 ),
+                  CALL DLASET( 'F', N-M, N-M, ZERO, ONE, VT(M+1,M+1),
      $                         LDVT )
                END IF
 *
 *              Overwrite U by left singular vectors of A and VT
 *              by right singular vectors of A
-*              (Workspace: need 2*M+N, prefer 2*M+N*NB)
+*              Workspace: need   3*M [e, tauq, taup] + N    [work]
+*              Workspace: prefer 3*M [e, tauq, taup] + N*NB [work]
 *
                CALL DORMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
      $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
                CALL DORMBR( 'P', 'R', 'T', N, N, M, A, LDA,
      $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
             END IF
 *
          END IF
index 898570b66932e7dcfe0b6fc5f7b58259fb54dd33..0c40673a494dbca68c7231fe17f6ef2ba1da3b4b 100644 (file)
 *>          LWORK >= MAX(1,5*MIN(M,N)) for the paths (see comments inside code):
 *>             - PATH 1  (M much larger than N, JOBU='N') 
 *>             - PATH 1t (N much larger than M, JOBVT='N')
-*>          LWORK >= MAX(1,3*MIN(M,N)+MAX(M,N),5*MIN(M,N)) for the other paths
+*>          LWORK >= MAX(1,3*MIN(M,N) + MAX(M,N),5*MIN(M,N)) for the other paths
 *>          For good performance, LWORK should generally be larger.
 *>
 *>          If LWORK = -1, then a workspace query is assumed; the routine
       SUBROUTINE DGESVD( JOBU, JOBVT, M, N, A, LDA, S, U, LDU,
      $                   VT, LDVT, WORK, LWORK, INFO )
 *
-*  -- LAPACK driver routine (version 3.4.1) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     April 2012
             BDSPAC = 5*N
 *           Compute space needed for DGEQRF
             CALL DGEQRF( M, N, A, LDA, DUM(1), DUM(1), -1, IERR )
-            LWORK_DGEQRF=DUM(1)
+            LWORK_DGEQRF = INT( DUM(1) )
 *           Compute space needed for DORGQR
             CALL DORGQR( M, N, N, A, LDA, DUM(1), DUM(1), -1, IERR )
-            LWORK_DORGQR_N=DUM(1)
+            LWORK_DORGQR_N = INT( DUM(1) )
             CALL DORGQR( M, M, N, A, LDA, DUM(1), DUM(1), -1, IERR )
-            LWORK_DORGQR_M=DUM(1)
+            LWORK_DORGQR_M = INT( DUM(1) )
 *           Compute space needed for DGEBRD
             CALL DGEBRD( N, N, A, LDA, S, DUM(1), DUM(1),
      $                   DUM(1), DUM(1), -1, IERR )
-            LWORK_DGEBRD=DUM(1)
+            LWORK_DGEBRD = INT( DUM(1) )
 *           Compute space needed for DORGBR P
             CALL DORGBR( 'P', N, N, N, A, LDA, DUM(1),
      $                   DUM(1), -1, IERR )
-            LWORK_DORGBR_P=DUM(1)
+            LWORK_DORGBR_P = INT( DUM(1) )
 *           Compute space needed for DORGBR Q
             CALL DORGBR( 'Q', N, N, N, A, LDA, DUM(1),
      $                   DUM(1), -1, IERR )
-            LWORK_DORGBR_Q=DUM(1)
+            LWORK_DORGBR_Q = INT( DUM(1) )
 *
             IF( M.GE.MNTHR ) THEN
                IF( WNTUN ) THEN
 *                 Path 1 (M much larger than N, JOBU='N')
 *
                   MAXWRK = N + LWORK_DGEQRF
-                  MAXWRK = MAX( MAXWRK, 3*N+LWORK_DGEBRD )
+                  MAXWRK = MAX( MAXWRK, 3*N + LWORK_DGEBRD )
                   IF( WNTVO .OR. WNTVAS )
-     $               MAXWRK = MAX( MAXWRK, 3*N+LWORK_DORGBR_P )
+     $               MAXWRK = MAX( MAXWRK, 3*N + LWORK_DORGBR_P )
                   MAXWRK = MAX( MAXWRK, BDSPAC )
                   MINWRK = MAX( 4*N, BDSPAC )
                ELSE IF( WNTUO .AND. WNTVN ) THEN
 *                 Path 2 (M much larger than N, JOBU='O', JOBVT='N')
 *
                   WRKBL = N + LWORK_DGEQRF
-                  WRKBL = MAX( WRKBL, N+LWORK_DORGQR_N )
-                  WRKBL = MAX( WRKBL, 3*N+LWORK_DGEBRD )
-                  WRKBL = MAX( WRKBL, 3*N+LWORK_DORGBR_Q )
+                  WRKBL = MAX( WRKBL, N + LWORK_DORGQR_N )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DGEBRD )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DORGBR_Q )
                   WRKBL = MAX( WRKBL, BDSPAC )
-                  MAXWRK = MAX( N*N+WRKBL, N*N+M*N+N )
-                  MINWRK = MAX( 3*N+M, BDSPAC )
+                  MAXWRK = MAX( N*N + WRKBL, N*N + M*N + N )
+                  MINWRK = MAX( 3*N + M, BDSPAC )
                ELSE IF( WNTUO .AND. WNTVAS ) THEN
 *
 *                 Path 3 (M much larger than N, JOBU='O', JOBVT='S' or
 *                 'A')
 *
                   WRKBL = N + LWORK_DGEQRF
-                  WRKBL = MAX( WRKBL, N+LWORK_DORGQR_N )
-                  WRKBL = MAX( WRKBL, 3*N+LWORK_DGEBRD )
-                  WRKBL = MAX( WRKBL, 3*N+LWORK_DORGBR_Q )
-                  WRKBL = MAX( WRKBL, 3*N+LWORK_DORGBR_P )
+                  WRKBL = MAX( WRKBL, N + LWORK_DORGQR_N )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DGEBRD )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DORGBR_Q )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DORGBR_P )
                   WRKBL = MAX( WRKBL, BDSPAC )
-                  MAXWRK = MAX( N*N+WRKBL, N*N+M*N+N )
-                  MINWRK = MAX( 3*N+M, BDSPAC )
+                  MAXWRK = MAX( N*N + WRKBL, N*N + M*N + N )
+                  MINWRK = MAX( 3*N + M, BDSPAC )
                ELSE IF( WNTUS .AND. WNTVN ) THEN
 *
 *                 Path 4 (M much larger than N, JOBU='S', JOBVT='N')
 *
                   WRKBL = N + LWORK_DGEQRF
-                  WRKBL = MAX( WRKBL, N+LWORK_DORGQR_N )
-                  WRKBL = MAX( WRKBL, 3*N+LWORK_DGEBRD )
-                  WRKBL = MAX( WRKBL, 3*N+LWORK_DORGBR_Q )
+                  WRKBL = MAX( WRKBL, N + LWORK_DORGQR_N )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DGEBRD )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DORGBR_Q )
                   WRKBL = MAX( WRKBL, BDSPAC )
                   MAXWRK = N*N + WRKBL
-                  MINWRK = MAX( 3*N+M, BDSPAC )
+                  MINWRK = MAX( 3*N + M, BDSPAC )
                ELSE IF( WNTUS .AND. WNTVO ) THEN
 *
 *                 Path 5 (M much larger than N, JOBU='S', JOBVT='O')
 *
                   WRKBL = N + LWORK_DGEQRF
-                  WRKBL = MAX( WRKBL, N+LWORK_DORGQR_N )
-                  WRKBL = MAX( WRKBL, 3*N+LWORK_DGEBRD )
-                  WRKBL = MAX( WRKBL, 3*N+LWORK_DORGBR_Q )
-                  WRKBL = MAX( WRKBL, 3*N+LWORK_DORGBR_P )
+                  WRKBL = MAX( WRKBL, N + LWORK_DORGQR_N )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DGEBRD )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DORGBR_Q )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DORGBR_P )
                   WRKBL = MAX( WRKBL, BDSPAC )
                   MAXWRK = 2*N*N + WRKBL
-                  MINWRK = MAX( 3*N+M, BDSPAC )
+                  MINWRK = MAX( 3*N + M, BDSPAC )
                ELSE IF( WNTUS .AND. WNTVAS ) THEN
 *
 *                 Path 6 (M much larger than N, JOBU='S', JOBVT='S' or
 *                 'A')
 *
                   WRKBL = N + LWORK_DGEQRF
-                  WRKBL = MAX( WRKBL, N+LWORK_DORGQR_N )
-                  WRKBL = MAX( WRKBL, 3*N+LWORK_DGEBRD )
-                  WRKBL = MAX( WRKBL, 3*N+LWORK_DORGBR_Q )
-                  WRKBL = MAX( WRKBL, 3*N+LWORK_DORGBR_P )
+                  WRKBL = MAX( WRKBL, N + LWORK_DORGQR_N )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DGEBRD )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DORGBR_Q )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DORGBR_P )
                   WRKBL = MAX( WRKBL, BDSPAC )
                   MAXWRK = N*N + WRKBL
-                  MINWRK = MAX( 3*N+M, BDSPAC )
+                  MINWRK = MAX( 3*N + M, BDSPAC )
                ELSE IF( WNTUA .AND. WNTVN ) THEN
 *
 *                 Path 7 (M much larger than N, JOBU='A', JOBVT='N')
 *
                   WRKBL = N + LWORK_DGEQRF
-                  WRKBL = MAX( WRKBL, N+LWORK_DORGQR_M )
-                  WRKBL = MAX( WRKBL, 3*N+LWORK_DGEBRD )
-                  WRKBL = MAX( WRKBL, 3*N+LWORK_DORGBR_Q )
+                  WRKBL = MAX( WRKBL, N + LWORK_DORGQR_M )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DGEBRD )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DORGBR_Q )
                   WRKBL = MAX( WRKBL, BDSPAC )
                   MAXWRK = N*N + WRKBL
-                  MINWRK = MAX( 3*N+M, BDSPAC )
+                  MINWRK = MAX( 3*N + M, BDSPAC )
                ELSE IF( WNTUA .AND. WNTVO ) THEN
 *
 *                 Path 8 (M much larger than N, JOBU='A', JOBVT='O')
 *
                   WRKBL = N + LWORK_DGEQRF
-                  WRKBL = MAX( WRKBL, N+LWORK_DORGQR_M )
-                  WRKBL = MAX( WRKBL, 3*N+LWORK_DGEBRD )
-                  WRKBL = MAX( WRKBL, 3*N+LWORK_DORGBR_Q )
-                  WRKBL = MAX( WRKBL, 3*N+LWORK_DORGBR_P )
+                  WRKBL = MAX( WRKBL, N + LWORK_DORGQR_M )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DGEBRD )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DORGBR_Q )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DORGBR_P )
                   WRKBL = MAX( WRKBL, BDSPAC )
                   MAXWRK = 2*N*N + WRKBL
-                  MINWRK = MAX( 3*N+M, BDSPAC )
+                  MINWRK = MAX( 3*N + M, BDSPAC )
                ELSE IF( WNTUA .AND. WNTVAS ) THEN
 *
 *                 Path 9 (M much larger than N, JOBU='A', JOBVT='S' or
 *                 'A')
 *
                   WRKBL = N + LWORK_DGEQRF
-                  WRKBL = MAX( WRKBL, N+LWORK_DORGQR_M )
-                  WRKBL = MAX( WRKBL, 3*N+LWORK_DGEBRD )
-                  WRKBL = MAX( WRKBL, 3*N+LWORK_DORGBR_Q )
-                  WRKBL = MAX( WRKBL, 3*N+LWORK_DORGBR_P )
+                  WRKBL = MAX( WRKBL, N + LWORK_DORGQR_M )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DGEBRD )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DORGBR_Q )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_DORGBR_P )
                   WRKBL = MAX( WRKBL, BDSPAC )
                   MAXWRK = N*N + WRKBL
-                  MINWRK = MAX( 3*N+M, BDSPAC )
+                  MINWRK = MAX( 3*N + M, BDSPAC )
                END IF
             ELSE
 *
 *
                CALL DGEBRD( M, N, A, LDA, S, DUM(1), DUM(1),
      $                   DUM(1), DUM(1), -1, IERR )
-               LWORK_DGEBRD=DUM(1)
+               LWORK_DGEBRD = INT( DUM(1) )
                MAXWRK = 3*N + LWORK_DGEBRD
                IF( WNTUS .OR. WNTUO ) THEN
                   CALL DORGBR( 'Q', M, N, N, A, LDA, DUM(1),
      $                   DUM(1), -1, IERR )
-                  LWORK_DORGBR_Q=DUM(1)
-                  MAXWRK = MAX( MAXWRK, 3*N+LWORK_DORGBR_Q )
+                  LWORK_DORGBR_Q = INT( DUM(1) )
+                  MAXWRK = MAX( MAXWRK, 3*N + LWORK_DORGBR_Q )
                END IF
                IF( WNTUA ) THEN
                   CALL DORGBR( 'Q', M, M, N, A, LDA, DUM(1),
      $                   DUM(1), -1, IERR )
-                  LWORK_DORGBR_Q=DUM(1)
-                  MAXWRK = MAX( MAXWRK, 3*N+LWORK_DORGBR_Q )
+                  LWORK_DORGBR_Q = INT( DUM(1) )
+                  MAXWRK = MAX( MAXWRK, 3*N + LWORK_DORGBR_Q )
                END IF
                IF( .NOT.WNTVN ) THEN
-                 MAXWRK = MAX( MAXWRK, 3*N+LWORK_DORGBR_P )
+                 MAXWRK = MAX( MAXWRK, 3*N + LWORK_DORGBR_P )
                END IF
                MAXWRK = MAX( MAXWRK, BDSPAC )
-               MINWRK = MAX( 3*N+M, BDSPAC )
+               MINWRK = MAX( 3*N + M, BDSPAC )
             END IF
          ELSE IF( MINMN.GT.0 ) THEN
 *
             BDSPAC = 5*M
 *           Compute space needed for DGELQF
             CALL DGELQF( M, N, A, LDA, DUM(1), DUM(1), -1, IERR )
-            LWORK_DGELQF=DUM(1)
+            LWORK_DGELQF = INT( DUM(1) )
 *           Compute space needed for DORGLQ
             CALL DORGLQ( N, N, M, DUM(1), N, DUM(1), DUM(1), -1, IERR )
-            LWORK_DORGLQ_N=DUM(1)
+            LWORK_DORGLQ_N = INT( DUM(1) )
             CALL DORGLQ( M, N, M, A, LDA, DUM(1), DUM(1), -1, IERR )
-            LWORK_DORGLQ_M=DUM(1)
+            LWORK_DORGLQ_M = INT( DUM(1) )
 *           Compute space needed for DGEBRD
             CALL DGEBRD( M, M, A, LDA, S, DUM(1), DUM(1),
      $                   DUM(1), DUM(1), -1, IERR )
-            LWORK_DGEBRD=DUM(1)
+            LWORK_DGEBRD = INT( DUM(1) )
 *            Compute space needed for DORGBR P
             CALL DORGBR( 'P', M, M, M, A, N, DUM(1),
      $                   DUM(1), -1, IERR )
-            LWORK_DORGBR_P=DUM(1)
+            LWORK_DORGBR_P = INT( DUM(1) )
 *           Compute space needed for DORGBR Q
             CALL DORGBR( 'Q', M, M, M, A, N, DUM(1),
      $                   DUM(1), -1, IERR )
-            LWORK_DORGBR_Q=DUM(1)
+            LWORK_DORGBR_Q = INT( DUM(1) )
             IF( N.GE.MNTHR ) THEN
                IF( WNTVN ) THEN
 *
 *                 Path 1t(N much larger than M, JOBVT='N')
 *
                   MAXWRK = M + LWORK_DGELQF
-                  MAXWRK = MAX( MAXWRK, 3*M+LWORK_DGEBRD )
+                  MAXWRK = MAX( MAXWRK, 3*M + LWORK_DGEBRD )
                   IF( WNTUO .OR. WNTUAS )
-     $               MAXWRK = MAX( MAXWRK, 3*M+LWORK_DORGBR_Q )
+     $               MAXWRK = MAX( MAXWRK, 3*M + LWORK_DORGBR_Q )
                   MAXWRK = MAX( MAXWRK, BDSPAC )
                   MINWRK = MAX( 4*M, BDSPAC )
                ELSE IF( WNTVO .AND. WNTUN ) THEN
 *                 Path 2t(N much larger than M, JOBU='N', JOBVT='O')
 *
                   WRKBL = M + LWORK_DGELQF
-                  WRKBL = MAX( WRKBL, M+LWORK_DORGLQ_M )
-                  WRKBL = MAX( WRKBL, 3*M+LWORK_DGEBRD )
-                  WRKBL = MAX( WRKBL, 3*M+LWORK_DORGBR_P )
+                  WRKBL = MAX( WRKBL, M + LWORK_DORGLQ_M )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DGEBRD )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DORGBR_P )
                   WRKBL = MAX( WRKBL, BDSPAC )
-                  MAXWRK = MAX( M*M+WRKBL, M*M+M*N+M )
-                  MINWRK = MAX( 3*M+N, BDSPAC )
+                  MAXWRK = MAX( M*M + WRKBL, M*M + M*N + M )
+                  MINWRK = MAX( 3*M + N, BDSPAC )
                ELSE IF( WNTVO .AND. WNTUAS ) THEN
 *
 *                 Path 3t(N much larger than M, JOBU='S' or 'A',
 *                 JOBVT='O')
 *
                   WRKBL = M + LWORK_DGELQF
-                  WRKBL = MAX( WRKBL, M+LWORK_DORGLQ_M )
-                  WRKBL = MAX( WRKBL, 3*M+LWORK_DGEBRD )
-                  WRKBL = MAX( WRKBL, 3*M+LWORK_DORGBR_P )
-                  WRKBL = MAX( WRKBL, 3*M+LWORK_DORGBR_Q )
+                  WRKBL = MAX( WRKBL, M + LWORK_DORGLQ_M )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DGEBRD )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DORGBR_P )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DORGBR_Q )
                   WRKBL = MAX( WRKBL, BDSPAC )
-                  MAXWRK = MAX( M*M+WRKBL, M*M+M*N+M )
-                  MINWRK = MAX( 3*M+N, BDSPAC )
+                  MAXWRK = MAX( M*M + WRKBL, M*M + M*N + M )
+                  MINWRK = MAX( 3*M + N, BDSPAC )
                ELSE IF( WNTVS .AND. WNTUN ) THEN
 *
 *                 Path 4t(N much larger than M, JOBU='N', JOBVT='S')
 *
                   WRKBL = M + LWORK_DGELQF
-                  WRKBL = MAX( WRKBL, M+LWORK_DORGLQ_M )
-                  WRKBL = MAX( WRKBL, 3*M+LWORK_DGEBRD )
-                  WRKBL = MAX( WRKBL, 3*M+LWORK_DORGBR_P )
+                  WRKBL = MAX( WRKBL, M + LWORK_DORGLQ_M )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DGEBRD )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DORGBR_P )
                   WRKBL = MAX( WRKBL, BDSPAC )
                   MAXWRK = M*M + WRKBL
-                  MINWRK = MAX( 3*M+N, BDSPAC )
+                  MINWRK = MAX( 3*M + N, BDSPAC )
                ELSE IF( WNTVS .AND. WNTUO ) THEN
 *
 *                 Path 5t(N much larger than M, JOBU='O', JOBVT='S')
 *
                   WRKBL = M + LWORK_DGELQF
-                  WRKBL = MAX( WRKBL, M+LWORK_DORGLQ_M )
-                  WRKBL = MAX( WRKBL, 3*M+LWORK_DGEBRD )
-                  WRKBL = MAX( WRKBL, 3*M+LWORK_DORGBR_P )
-                  WRKBL = MAX( WRKBL, 3*M+LWORK_DORGBR_Q )
+                  WRKBL = MAX( WRKBL, M + LWORK_DORGLQ_M )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DGEBRD )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DORGBR_P )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DORGBR_Q )
                   WRKBL = MAX( WRKBL, BDSPAC )
                   MAXWRK = 2*M*M + WRKBL
-                  MINWRK = MAX( 3*M+N, BDSPAC )
+                  MINWRK = MAX( 3*M + N, BDSPAC )
                ELSE IF( WNTVS .AND. WNTUAS ) THEN
 *
 *                 Path 6t(N much larger than M, JOBU='S' or 'A',
 *                 JOBVT='S')
 *
                   WRKBL = M + LWORK_DGELQF
-                  WRKBL = MAX( WRKBL, M+LWORK_DORGLQ_M )
-                  WRKBL = MAX( WRKBL, 3*M+LWORK_DGEBRD )
-                  WRKBL = MAX( WRKBL, 3*M+LWORK_DORGBR_P )
-                  WRKBL = MAX( WRKBL, 3*M+LWORK_DORGBR_Q )
+                  WRKBL = MAX( WRKBL, M + LWORK_DORGLQ_M )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DGEBRD )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DORGBR_P )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DORGBR_Q )
                   WRKBL = MAX( WRKBL, BDSPAC )
                   MAXWRK = M*M + WRKBL
-                  MINWRK = MAX( 3*M+N, BDSPAC )
+                  MINWRK = MAX( 3*M + N, BDSPAC )
                ELSE IF( WNTVA .AND. WNTUN ) THEN
 *
 *                 Path 7t(N much larger than M, JOBU='N', JOBVT='A')
 *
                   WRKBL = M + LWORK_DGELQF
-                  WRKBL = MAX( WRKBL, M+LWORK_DORGLQ_N )
-                  WRKBL = MAX( WRKBL, 3*M+LWORK_DGEBRD )
-                  WRKBL = MAX( WRKBL, 3*M+LWORK_DORGBR_P )
+                  WRKBL = MAX( WRKBL, M + LWORK_DORGLQ_N )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DGEBRD )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DORGBR_P )
                   WRKBL = MAX( WRKBL, BDSPAC )
                   MAXWRK = M*M + WRKBL
-                  MINWRK = MAX( 3*M+N, BDSPAC )
+                  MINWRK = MAX( 3*M + N, BDSPAC )
                ELSE IF( WNTVA .AND. WNTUO ) THEN
 *
 *                 Path 8t(N much larger than M, JOBU='O', JOBVT='A')
 *
                   WRKBL = M + LWORK_DGELQF
-                  WRKBL = MAX( WRKBL, M+LWORK_DORGLQ_N )
-                  WRKBL = MAX( WRKBL, 3*M+LWORK_DGEBRD )
-                  WRKBL = MAX( WRKBL, 3*M+LWORK_DORGBR_P )
-                  WRKBL = MAX( WRKBL, 3*M+LWORK_DORGBR_Q )
+                  WRKBL = MAX( WRKBL, M + LWORK_DORGLQ_N )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DGEBRD )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DORGBR_P )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DORGBR_Q )
                   WRKBL = MAX( WRKBL, BDSPAC )
                   MAXWRK = 2*M*M + WRKBL
-                  MINWRK = MAX( 3*M+N, BDSPAC )
+                  MINWRK = MAX( 3*M + N, BDSPAC )
                ELSE IF( WNTVA .AND. WNTUAS ) THEN
 *
 *                 Path 9t(N much larger than M, JOBU='S' or 'A',
 *                 JOBVT='A')
 *
                   WRKBL = M + LWORK_DGELQF
-                  WRKBL = MAX( WRKBL, M+LWORK_DORGLQ_N )
-                  WRKBL = MAX( WRKBL, 3*M+LWORK_DGEBRD )
-                  WRKBL = MAX( WRKBL, 3*M+LWORK_DORGBR_P )
-                  WRKBL = MAX( WRKBL, 3*M+LWORK_DORGBR_Q )
+                  WRKBL = MAX( WRKBL, M + LWORK_DORGLQ_N )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DGEBRD )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DORGBR_P )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_DORGBR_Q )
                   WRKBL = MAX( WRKBL, BDSPAC )
                   MAXWRK = M*M + WRKBL
-                  MINWRK = MAX( 3*M+N, BDSPAC )
+                  MINWRK = MAX( 3*M + N, BDSPAC )
                END IF
             ELSE
 *
 *
                CALL DGEBRD( M, N, A, LDA, S, DUM(1), DUM(1),
      $                   DUM(1), DUM(1), -1, IERR )
-               LWORK_DGEBRD=DUM(1)
+               LWORK_DGEBRD = INT( DUM(1) )
                MAXWRK = 3*M + LWORK_DGEBRD
                IF( WNTVS .OR. WNTVO ) THEN
 *                Compute space needed for DORGBR P
                  CALL DORGBR( 'P', M, N, M, A, N, DUM(1),
      $                   DUM(1), -1, IERR )
-                 LWORK_DORGBR_P=DUM(1)
-                 MAXWRK = MAX( MAXWRK, 3*M+LWORK_DORGBR_P )
+                 LWORK_DORGBR_P = INT( DUM(1) )
+                 MAXWRK = MAX( MAXWRK, 3*M + LWORK_DORGBR_P )
                END IF
                IF( WNTVA ) THEN
                  CALL DORGBR( 'P', N, N, M, A, N, DUM(1),
      $                   DUM(1), -1, IERR )
-                 LWORK_DORGBR_P=DUM(1)
-                 MAXWRK = MAX( MAXWRK, 3*M+LWORK_DORGBR_P )
+                 LWORK_DORGBR_P = INT( DUM(1) )
+                 MAXWRK = MAX( MAXWRK, 3*M + LWORK_DORGBR_P )
                END IF
                IF( .NOT.WNTUN ) THEN
-                  MAXWRK = MAX( MAXWRK, 3*M+LWORK_DORGBR_Q )
+                  MAXWRK = MAX( MAXWRK, 3*M + LWORK_DORGBR_Q )
                END IF
                MAXWRK = MAX( MAXWRK, BDSPAC )
-               MINWRK = MAX( 3*M+N, BDSPAC )
+               MINWRK = MAX( 3*M + N, BDSPAC )
             END IF
          END IF
          MAXWRK = MAX( MAXWRK, MINWRK )
                IWORK = ITAU + N
 *
 *              Compute A=Q*R
-*              (Workspace: need 2*N, prefer N+N*NB)
+*              (Workspace: need 2*N, prefer N + N*NB)
 *
                CALL DGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),
      $                      LWORK-IWORK+1, IERR )
 *
 *              Zero out below R
 *
-               CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ), LDA )
+               IF( N .GT. 1 ) THEN
+                  CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),
+     $                         LDA )
+               END IF
                IE = 1
                ITAUQ = IE + N
                ITAUP = ITAUQ + N
                IWORK = ITAUP + N
 *
 *              Bidiagonalize R in A
-*              (Workspace: need 4*N, prefer 3*N+2*N*NB)
+*              (Workspace: need 4*N, prefer 3*N + 2*N*NB)
 *
                CALL DGEBRD( N, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
      $                      WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
                IF( WNTVO .OR. WNTVAS ) THEN
 *
 *                 If right singular vectors desired, generate P'.
-*                 (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
+*                 (Workspace: need 4*N-1, prefer 3*N + (N-1)*NB)
 *
                   CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
 *                 Sufficient workspace for a fast algorithm
 *
                   IR = 1
-                  IF( LWORK.GE.MAX( WRKBL, LDA*N+N )+LDA*N ) THEN
+                  IF( LWORK.GE.MAX( WRKBL, LDA*N + N ) + LDA*N ) THEN
 *
 *                    WORK(IU) is LDA by N, WORK(IR) is LDA by N
 *
                      LDWRKU = LDA
                      LDWRKR = LDA
-                  ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N+N )+N*N ) THEN
+                  ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N + N ) + N*N ) THEN
 *
 *                    WORK(IU) is LDA by N, WORK(IR) is N by N
 *
                   IWORK = ITAU + N
 *
 *                 Compute A=Q*R
-*                 (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                 (Workspace: need N*N + 2*N, prefer N*N + N + N*NB)
 *
                   CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
      $                         LDWRKR )
 *
 *                 Generate Q in A
-*                 (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                 (Workspace: need N*N + 2*N, prefer N*N + N + N*NB)
 *
                   CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                   IWORK = ITAUP + N
 *
 *                 Bidiagonalize R in WORK(IR)
-*                 (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
+*                 (Workspace: need N*N + 4*N, prefer N*N + 3*N + 2*N*NB)
 *
                   CALL DGEBRD( N, N, WORK( IR ), LDWRKR, S, WORK( IE ),
      $                         WORK( ITAUQ ), WORK( ITAUP ),
      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
 *
 *                 Generate left vectors bidiagonalizing R
-*                 (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
+*                 (Workspace: need N*N + 4*N, prefer N*N + 3*N + N*NB)
 *
                   CALL DORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
      $                         WORK( ITAUQ ), WORK( IWORK ),
 *
 *                 Perform bidiagonal QR iteration, computing left
 *                 singular vectors of R in WORK(IR)
-*                 (Workspace: need N*N+BDSPAC)
+*                 (Workspace: need N*N + BDSPAC)
 *
                   CALL DBDSQR( 'U', N, 0, N, 0, S, WORK( IE ), DUM, 1,
      $                         WORK( IR ), LDWRKR, DUM, 1,
 *
 *                 Multiply Q in A by left singular vectors of R in
 *                 WORK(IR), storing result in WORK(IU) and copying to A
-*                 (Workspace: need N*N+2*N, prefer N*N+M*N+N)
+*                 (Workspace: need N*N + 2*N, prefer N*N + M*N + N)
 *
                   DO 10 I = 1, M, LDWRKU
                      CHUNK = MIN( M-I+1, LDWRKU )
                   IWORK = ITAUP + N
 *
 *                 Bidiagonalize A
-*                 (Workspace: need 3*N+M, prefer 3*N+(M+N)*NB)
+*                 (Workspace: need 3*N + M, prefer 3*N + (M + N)*NB)
 *
                   CALL DGEBRD( M, N, A, LDA, S, WORK( IE ),
      $                         WORK( ITAUQ ), WORK( ITAUP ),
      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
 *
 *                 Generate left vectors bidiagonalizing A
-*                 (Workspace: need 4*N, prefer 3*N+N*NB)
+*                 (Workspace: need 4*N, prefer 3*N + N*NB)
 *
                   CALL DORGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
 *                 Sufficient workspace for a fast algorithm
 *
                   IR = 1
-                  IF( LWORK.GE.MAX( WRKBL, LDA*N+N )+LDA*N ) THEN
+                  IF( LWORK.GE.MAX( WRKBL, LDA*N + N ) + LDA*N ) THEN
 *
 *                    WORK(IU) is LDA by N and WORK(IR) is LDA by N
 *
                      LDWRKU = LDA
                      LDWRKR = LDA
-                  ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N+N )+N*N ) THEN
+                  ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N + N ) + N*N ) THEN
 *
 *                    WORK(IU) is LDA by N and WORK(IR) is N by N
 *
                   IWORK = ITAU + N
 *
 *                 Compute A=Q*R
-*                 (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                 (Workspace: need N*N + 2*N, prefer N*N + N + N*NB)
 *
                   CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
      $                            VT( 2, 1 ), LDVT )
 *
 *                 Generate Q in A
-*                 (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                 (Workspace: need N*N + 2*N, prefer N*N + N + N*NB)
 *
                   CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                   IWORK = ITAUP + N
 *
 *                 Bidiagonalize R in VT, copying result to WORK(IR)
-*                 (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
+*                 (Workspace: need N*N + 4*N, prefer N*N + 3*N + 2*N*NB)
 *
                   CALL DGEBRD( N, N, VT, LDVT, S, WORK( IE ),
      $                         WORK( ITAUQ ), WORK( ITAUP ),
                   CALL DLACPY( 'L', N, N, VT, LDVT, WORK( IR ), LDWRKR )
 *
 *                 Generate left vectors bidiagonalizing R in WORK(IR)
-*                 (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
+*                 (Workspace: need N*N + 4*N, prefer N*N + 3*N + N*NB)
 *
                   CALL DORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
      $                         WORK( ITAUQ ), WORK( IWORK ),
      $                         LWORK-IWORK+1, IERR )
 *
 *                 Generate right vectors bidiagonalizing R in VT
-*                 (Workspace: need N*N+4*N-1, prefer N*N+3*N+(N-1)*NB)
+*                 (Workspace: need N*N + 4*N-1, prefer N*N + 3*N + (N-1)*NB)
 *
                   CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
 *                 Perform bidiagonal QR iteration, computing left
 *                 singular vectors of R in WORK(IR) and computing right
 *                 singular vectors of R in VT
-*                 (Workspace: need N*N+BDSPAC)
+*                 (Workspace: need N*N + BDSPAC)
 *
                   CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ), VT, LDVT,
      $                         WORK( IR ), LDWRKR, DUM, 1,
 *
 *                 Multiply Q in A by left singular vectors of R in
 *                 WORK(IR), storing result in WORK(IU) and copying to A
-*                 (Workspace: need N*N+2*N, prefer N*N+M*N+N)
+*                 (Workspace: need N*N + 2*N, prefer N*N + M*N + N)
 *
                   DO 20 I = 1, M, LDWRKU
                      CHUNK = MIN( M-I+1, LDWRKU )
                   IWORK = ITAU + N
 *
 *                 Compute A=Q*R
-*                 (Workspace: need 2*N, prefer N+N*NB)
+*                 (Workspace: need 2*N, prefer N + N*NB)
 *
                   CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
      $                            VT( 2, 1 ), LDVT )
 *
 *                 Generate Q in A
-*                 (Workspace: need 2*N, prefer N+N*NB)
+*                 (Workspace: need 2*N, prefer N + N*NB)
 *
                   CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                   IWORK = ITAUP + N
 *
 *                 Bidiagonalize R in VT
-*                 (Workspace: need 4*N, prefer 3*N+2*N*NB)
+*                 (Workspace: need 4*N, prefer 3*N + 2*N*NB)
 *
                   CALL DGEBRD( N, N, VT, LDVT, S, WORK( IE ),
      $                         WORK( ITAUQ ), WORK( ITAUP ),
      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
 *
 *                 Multiply Q in A by left vectors bidiagonalizing R
-*                 (Workspace: need 3*N+M, prefer 3*N+M*NB)
+*                 (Workspace: need 3*N + M, prefer 3*N + M*NB)
 *
                   CALL DORMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,
      $                         WORK( ITAUQ ), A, LDA, WORK( IWORK ),
      $                         LWORK-IWORK+1, IERR )
 *
 *                 Generate right vectors bidiagonalizing R in VT
-*                 (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
+*                 (Workspace: need 4*N-1, prefer 3*N + (N-1)*NB)
 *
                   CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                      IWORK = ITAU + N
 *
 *                    Compute A=Q*R
-*                    (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                    (Workspace: need N*N + 2*N, prefer N*N + N + N*NB)
 *
                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
      $                            WORK( IR+1 ), LDWRKR )
 *
 *                    Generate Q in A
-*                    (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                    (Workspace: need N*N + 2*N, prefer N*N + N + N*NB)
 *
                      CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      IWORK = ITAUP + N
 *
 *                    Bidiagonalize R in WORK(IR)
-*                    (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
+*                    (Workspace: need N*N + 4*N, prefer N*N + 3*N + 2*N*NB)
 *
                      CALL DGEBRD( N, N, WORK( IR ), LDWRKR, S,
      $                            WORK( IE ), WORK( ITAUQ ),
      $                            LWORK-IWORK+1, IERR )
 *
 *                    Generate left vectors bidiagonalizing R in WORK(IR)
-*                    (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
+*                    (Workspace: need N*N + 4*N, prefer N*N + 3*N + N*NB)
 *
                      CALL DORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
      $                            WORK( ITAUQ ), WORK( IWORK ),
 *
 *                    Perform bidiagonal QR iteration, computing left
 *                    singular vectors of R in WORK(IR)
-*                    (Workspace: need N*N+BDSPAC)
+*                    (Workspace: need N*N + BDSPAC)
 *
                      CALL DBDSQR( 'U', N, 0, N, 0, S, WORK( IE ), DUM,
      $                            1, WORK( IR ), LDWRKR, DUM, 1,
                      IWORK = ITAU + N
 *
 *                    Compute A=Q*R, copying result to U
-*                    (Workspace: need 2*N, prefer N+N*NB)
+*                    (Workspace: need 2*N, prefer N + N*NB)
 *
                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
 *
 *                    Generate Q in U
-*                    (Workspace: need 2*N, prefer N+N*NB)
+*                    (Workspace: need 2*N, prefer N + N*NB)
 *
                      CALL DORGQR( M, N, N, U, LDU, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
 *
 *                    Zero out below R in A
 *
-                     CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),
-     $                            LDA )
+                     IF( N .GT. 1 ) THEN
+                        CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
+     $                               A( 2, 1 ), LDA )
+                     END IF
 *
 *                    Bidiagonalize R in A
-*                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
+*                    (Workspace: need 4*N, prefer 3*N + 2*N*NB)
 *
                      CALL DGEBRD( N, N, A, LDA, S, WORK( IE ),
      $                            WORK( ITAUQ ), WORK( ITAUP ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
 *
 *                    Multiply Q in U by left vectors bidiagonalizing R
-*                    (Workspace: need 3*N+M, prefer 3*N+M*NB)
+*                    (Workspace: need 3*N + M, prefer 3*N + M*NB)
 *
                      CALL DORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
      $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
                         LDWRKU = LDA
                         IR = IU + LDWRKU*N
                         LDWRKR = LDA
-                     ELSE IF( LWORK.GE.WRKBL+( LDA+N )*N ) THEN
+                     ELSE IF( LWORK.GE.WRKBL+( LDA + N )*N ) THEN
 *
 *                       WORK(IU) is LDA by N and WORK(IR) is N by N
 *
                      IWORK = ITAU + N
 *
 *                    Compute A=Q*R
-*                    (Workspace: need 2*N*N+2*N, prefer 2*N*N+N+N*NB)
+*                    (Workspace: need 2*N*N + 2*N, prefer 2*N*N + N + N*NB)
 *
                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
      $                            WORK( IU+1 ), LDWRKU )
 *
 *                    Generate Q in A
-*                    (Workspace: need 2*N*N+2*N, prefer 2*N*N+N+N*NB)
+*                    (Workspace: need 2*N*N + 2*N, prefer 2*N*N + N + N*NB)
 *
                      CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
 *
 *                    Bidiagonalize R in WORK(IU), copying result to
 *                    WORK(IR)
-*                    (Workspace: need 2*N*N+4*N,
+*                    (Workspace: need 2*N*N + 4*N,
 *                                prefer 2*N*N+3*N+2*N*NB)
 *
                      CALL DGEBRD( N, N, WORK( IU ), LDWRKU, S,
      $                            WORK( IR ), LDWRKR )
 *
 *                    Generate left bidiagonalizing vectors in WORK(IU)
-*                    (Workspace: need 2*N*N+4*N, prefer 2*N*N+3*N+N*NB)
+*                    (Workspace: need 2*N*N + 4*N, prefer 2*N*N + 3*N + N*NB)
 *
                      CALL DORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
      $                            WORK( ITAUQ ), WORK( IWORK ),
      $                            LWORK-IWORK+1, IERR )
 *
 *                    Generate right bidiagonalizing vectors in WORK(IR)
-*                    (Workspace: need 2*N*N+4*N-1,
+*                    (Workspace: need 2*N*N + 4*N-1,
 *                                prefer 2*N*N+3*N+(N-1)*NB)
 *
                      CALL DORGBR( 'P', N, N, N, WORK( IR ), LDWRKR,
 *                    Perform bidiagonal QR iteration, computing left
 *                    singular vectors of R in WORK(IU) and computing
 *                    right singular vectors of R in WORK(IR)
-*                    (Workspace: need 2*N*N+BDSPAC)
+*                    (Workspace: need 2*N*N + BDSPAC)
 *
                      CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ),
      $                            WORK( IR ), LDWRKR, WORK( IU ),
                      IWORK = ITAU + N
 *
 *                    Compute A=Q*R, copying result to U
-*                    (Workspace: need 2*N, prefer N+N*NB)
+*                    (Workspace: need 2*N, prefer N + N*NB)
 *
                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
 *
 *                    Generate Q in U
-*                    (Workspace: need 2*N, prefer N+N*NB)
+*                    (Workspace: need 2*N, prefer N + N*NB)
 *
                      CALL DORGQR( M, N, N, U, LDU, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
 *
 *                    Zero out below R in A
 *
-                     CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),
-     $                            LDA )
+                     IF( N .GT. 1 ) THEN
+                        CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
+     $                               A( 2, 1 ), LDA )
+                     END IF
 *
 *                    Bidiagonalize R in A
-*                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
+*                    (Workspace: need 4*N, prefer 3*N + 2*N*NB)
 *
                      CALL DGEBRD( N, N, A, LDA, S, WORK( IE ),
      $                            WORK( ITAUQ ), WORK( ITAUP ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
 *
 *                    Multiply Q in U by left vectors bidiagonalizing R
-*                    (Workspace: need 3*N+M, prefer 3*N+M*NB)
+*                    (Workspace: need 3*N + M, prefer 3*N + M*NB)
 *
                      CALL DORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
      $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
      $                            LWORK-IWORK+1, IERR )
 *
 *                    Generate right vectors bidiagonalizing R in A
-*                    (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
+*                    (Workspace: need 4*N-1, prefer 3*N + (N-1)*NB)
 *
                      CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      IWORK = ITAU + N
 *
 *                    Compute A=Q*R
-*                    (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                    (Workspace: need N*N + 2*N, prefer N*N + N + N*NB)
 *
                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
      $                            WORK( IU+1 ), LDWRKU )
 *
 *                    Generate Q in A
-*                    (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                    (Workspace: need N*N + 2*N, prefer N*N + N + N*NB)
 *
                      CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      IWORK = ITAUP + N
 *
 *                    Bidiagonalize R in WORK(IU), copying result to VT
-*                    (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
+*                    (Workspace: need N*N + 4*N, prefer N*N + 3*N + 2*N*NB)
 *
                      CALL DGEBRD( N, N, WORK( IU ), LDWRKU, S,
      $                            WORK( IE ), WORK( ITAUQ ),
      $                            LDVT )
 *
 *                    Generate left bidiagonalizing vectors in WORK(IU)
-*                    (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
+*                    (Workspace: need N*N + 4*N, prefer N*N + 3*N + N*NB)
 *
                      CALL DORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
      $                            WORK( ITAUQ ), WORK( IWORK ),
      $                            LWORK-IWORK+1, IERR )
 *
 *                    Generate right bidiagonalizing vectors in VT
-*                    (Workspace: need N*N+4*N-1,
+*                    (Workspace: need N*N + 4*N-1,
 *                                prefer N*N+3*N+(N-1)*NB)
 *
                      CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
 *                    Perform bidiagonal QR iteration, computing left
 *                    singular vectors of R in WORK(IU) and computing
 *                    right singular vectors of R in VT
-*                    (Workspace: need N*N+BDSPAC)
+*                    (Workspace: need N*N + BDSPAC)
 *
                      CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ), VT,
      $                            LDVT, WORK( IU ), LDWRKU, DUM, 1,
                      IWORK = ITAU + N
 *
 *                    Compute A=Q*R, copying result to U
-*                    (Workspace: need 2*N, prefer N+N*NB)
+*                    (Workspace: need 2*N, prefer N + N*NB)
 *
                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
 *
 *                    Generate Q in U
-*                    (Workspace: need 2*N, prefer N+N*NB)
+*                    (Workspace: need 2*N, prefer N + N*NB)
 *
                      CALL DORGQR( M, N, N, U, LDU, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      IWORK = ITAUP + N
 *
 *                    Bidiagonalize R in VT
-*                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
+*                    (Workspace: need 4*N, prefer 3*N + 2*N*NB)
 *
                      CALL DGEBRD( N, N, VT, LDVT, S, WORK( IE ),
      $                            WORK( ITAUQ ), WORK( ITAUP ),
 *
 *                    Multiply Q in U by left bidiagonalizing vectors
 *                    in VT
-*                    (Workspace: need 3*N+M, prefer 3*N+M*NB)
+*                    (Workspace: need 3*N + M, prefer 3*N + M*NB)
 *
                      CALL DORMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,
      $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
      $                            LWORK-IWORK+1, IERR )
 *
 *                    Generate right bidiagonalizing vectors in VT
-*                    (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
+*                    (Workspace: need 4*N-1, prefer 3*N + (N-1)*NB)
 *
                      CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      IWORK = ITAU + N
 *
 *                    Compute A=Q*R, copying result to U
-*                    (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                    (Workspace: need N*N + 2*N, prefer N*N + N + N*NB)
 *
                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
      $                            WORK( IR+1 ), LDWRKR )
 *
 *                    Generate Q in U
-*                    (Workspace: need N*N+N+M, prefer N*N+N+M*NB)
+*                    (Workspace: need N*N + N + M, prefer N*N + N + M*NB)
 *
                      CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      IWORK = ITAUP + N
 *
 *                    Bidiagonalize R in WORK(IR)
-*                    (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
+*                    (Workspace: need N*N + 4*N, prefer N*N + 3*N + 2*N*NB)
 *
                      CALL DGEBRD( N, N, WORK( IR ), LDWRKR, S,
      $                            WORK( IE ), WORK( ITAUQ ),
      $                            LWORK-IWORK+1, IERR )
 *
 *                    Generate left bidiagonalizing vectors in WORK(IR)
-*                    (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
+*                    (Workspace: need N*N + 4*N, prefer N*N + 3*N + N*NB)
 *
                      CALL DORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
      $                            WORK( ITAUQ ), WORK( IWORK ),
 *
 *                    Perform bidiagonal QR iteration, computing left
 *                    singular vectors of R in WORK(IR)
-*                    (Workspace: need N*N+BDSPAC)
+*                    (Workspace: need N*N + BDSPAC)
 *
                      CALL DBDSQR( 'U', N, 0, N, 0, S, WORK( IE ), DUM,
      $                            1, WORK( IR ), LDWRKR, DUM, 1,
                      IWORK = ITAU + N
 *
 *                    Compute A=Q*R, copying result to U
-*                    (Workspace: need 2*N, prefer N+N*NB)
+*                    (Workspace: need 2*N, prefer N + N*NB)
 *
                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
 *
 *                    Generate Q in U
-*                    (Workspace: need N+M, prefer N+M*NB)
+*                    (Workspace: need N + M, prefer N + M*NB)
 *
                      CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
 *
 *                    Zero out below R in A
 *
-                     CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),
-     $                            LDA )
+                     IF( N .GT. 1 ) THEN
+                        CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
+     $                                A( 2, 1 ), LDA )
+                     END IF
 *
 *                    Bidiagonalize R in A
-*                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
+*                    (Workspace: need 4*N, prefer 3*N + 2*N*NB)
 *
                      CALL DGEBRD( N, N, A, LDA, S, WORK( IE ),
      $                            WORK( ITAUQ ), WORK( ITAUP ),
 *
 *                    Multiply Q in U by left bidiagonalizing vectors
 *                    in A
-*                    (Workspace: need 3*N+M, prefer 3*N+M*NB)
+*                    (Workspace: need 3*N + M, prefer 3*N + M*NB)
 *
                      CALL DORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
      $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
                         LDWRKU = LDA
                         IR = IU + LDWRKU*N
                         LDWRKR = LDA
-                     ELSE IF( LWORK.GE.WRKBL+( LDA+N )*N ) THEN
+                     ELSE IF( LWORK.GE.WRKBL+( LDA + N )*N ) THEN
 *
 *                       WORK(IU) is LDA by N and WORK(IR) is N by N
 *
                      IWORK = ITAU + N
 *
 *                    Compute A=Q*R, copying result to U
-*                    (Workspace: need 2*N*N+2*N, prefer 2*N*N+N+N*NB)
+*                    (Workspace: need 2*N*N + 2*N, prefer 2*N*N + N + N*NB)
 *
                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
 *
 *                    Generate Q in U
-*                    (Workspace: need 2*N*N+N+M, prefer 2*N*N+N+M*NB)
+*                    (Workspace: need 2*N*N + N + M, prefer 2*N*N + N + M*NB)
 *
                      CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
 *
 *                    Bidiagonalize R in WORK(IU), copying result to
 *                    WORK(IR)
-*                    (Workspace: need 2*N*N+4*N,
+*                    (Workspace: need 2*N*N + 4*N,
 *                                prefer 2*N*N+3*N+2*N*NB)
 *
                      CALL DGEBRD( N, N, WORK( IU ), LDWRKU, S,
      $                            WORK( IR ), LDWRKR )
 *
 *                    Generate left bidiagonalizing vectors in WORK(IU)
-*                    (Workspace: need 2*N*N+4*N, prefer 2*N*N+3*N+N*NB)
+*                    (Workspace: need 2*N*N + 4*N, prefer 2*N*N + 3*N + N*NB)
 *
                      CALL DORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
      $                            WORK( ITAUQ ), WORK( IWORK ),
      $                            LWORK-IWORK+1, IERR )
 *
 *                    Generate right bidiagonalizing vectors in WORK(IR)
-*                    (Workspace: need 2*N*N+4*N-1,
+*                    (Workspace: need 2*N*N + 4*N-1,
 *                                prefer 2*N*N+3*N+(N-1)*NB)
 *
                      CALL DORGBR( 'P', N, N, N, WORK( IR ), LDWRKR,
 *                    Perform bidiagonal QR iteration, computing left
 *                    singular vectors of R in WORK(IU) and computing
 *                    right singular vectors of R in WORK(IR)
-*                    (Workspace: need 2*N*N+BDSPAC)
+*                    (Workspace: need 2*N*N + BDSPAC)
 *
                      CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ),
      $                            WORK( IR ), LDWRKR, WORK( IU ),
                      IWORK = ITAU + N
 *
 *                    Compute A=Q*R, copying result to U
-*                    (Workspace: need 2*N, prefer N+N*NB)
+*                    (Workspace: need 2*N, prefer N + N*NB)
 *
                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
 *
 *                    Generate Q in U
-*                    (Workspace: need N+M, prefer N+M*NB)
+*                    (Workspace: need N + M, prefer N + M*NB)
 *
                      CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
 *
 *                    Zero out below R in A
 *
-                     CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),
-     $                            LDA )
+                     IF( N .GT. 1 ) THEN
+                        CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
+     $                                A( 2, 1 ), LDA )
+                     END IF
 *
 *                    Bidiagonalize R in A
-*                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
+*                    (Workspace: need 4*N, prefer 3*N + 2*N*NB)
 *
                      CALL DGEBRD( N, N, A, LDA, S, WORK( IE ),
      $                            WORK( ITAUQ ), WORK( ITAUP ),
 *
 *                    Multiply Q in U by left bidiagonalizing vectors
 *                    in A
-*                    (Workspace: need 3*N+M, prefer 3*N+M*NB)
+*                    (Workspace: need 3*N + M, prefer 3*N + M*NB)
 *
                      CALL DORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
      $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
      $                            LWORK-IWORK+1, IERR )
 *
 *                    Generate right bidiagonalizing vectors in A
-*                    (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
+*                    (Workspace: need 4*N-1, prefer 3*N + (N-1)*NB)
 *
                      CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      IWORK = ITAU + N
 *
 *                    Compute A=Q*R, copying result to U
-*                    (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                    (Workspace: need N*N + 2*N, prefer N*N + N + N*NB)
 *
                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
 *
 *                    Generate Q in U
-*                    (Workspace: need N*N+N+M, prefer N*N+N+M*NB)
+*                    (Workspace: need N*N + N + M, prefer N*N + N + M*NB)
 *
                      CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      IWORK = ITAUP + N
 *
 *                    Bidiagonalize R in WORK(IU), copying result to VT
-*                    (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
+*                    (Workspace: need N*N + 4*N, prefer N*N + 3*N + 2*N*NB)
 *
                      CALL DGEBRD( N, N, WORK( IU ), LDWRKU, S,
      $                            WORK( IE ), WORK( ITAUQ ),
      $                            LDVT )
 *
 *                    Generate left bidiagonalizing vectors in WORK(IU)
-*                    (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
+*                    (Workspace: need N*N + 4*N, prefer N*N + 3*N + N*NB)
 *
                      CALL DORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
      $                            WORK( ITAUQ ), WORK( IWORK ),
      $                            LWORK-IWORK+1, IERR )
 *
 *                    Generate right bidiagonalizing vectors in VT
-*                    (Workspace: need N*N+4*N-1,
+*                    (Workspace: need N*N + 4*N-1,
 *                                prefer N*N+3*N+(N-1)*NB)
 *
                      CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
 *                    Perform bidiagonal QR iteration, computing left
 *                    singular vectors of R in WORK(IU) and computing
 *                    right singular vectors of R in VT
-*                    (Workspace: need N*N+BDSPAC)
+*                    (Workspace: need N*N + BDSPAC)
 *
                      CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ), VT,
      $                            LDVT, WORK( IU ), LDWRKU, DUM, 1,
                      IWORK = ITAU + N
 *
 *                    Compute A=Q*R, copying result to U
-*                    (Workspace: need 2*N, prefer N+N*NB)
+*                    (Workspace: need 2*N, prefer N + N*NB)
 *
                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
 *
 *                    Generate Q in U
-*                    (Workspace: need N+M, prefer N+M*NB)
+*                    (Workspace: need N + M, prefer N + M*NB)
 *
                      CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      IWORK = ITAUP + N
 *
 *                    Bidiagonalize R in VT
-*                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
+*                    (Workspace: need 4*N, prefer 3*N + 2*N*NB)
 *
                      CALL DGEBRD( N, N, VT, LDVT, S, WORK( IE ),
      $                            WORK( ITAUQ ), WORK( ITAUP ),
 *
 *                    Multiply Q in U by left bidiagonalizing vectors
 *                    in VT
-*                    (Workspace: need 3*N+M, prefer 3*N+M*NB)
+*                    (Workspace: need 3*N + M, prefer 3*N + M*NB)
 *
                      CALL DORMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,
      $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
      $                            LWORK-IWORK+1, IERR )
 *
 *                    Generate right bidiagonalizing vectors in VT
-*                    (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
+*                    (Workspace: need 4*N-1, prefer 3*N + (N-1)*NB)
 *
                      CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
             IWORK = ITAUP + N
 *
 *           Bidiagonalize A
-*           (Workspace: need 3*N+M, prefer 3*N+(M+N)*NB)
+*           (Workspace: need 3*N + M, prefer 3*N + (M + N)*NB)
 *
             CALL DGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
      $                   WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
 *
 *              If left singular vectors desired in U, copy result to U
 *              and generate left bidiagonalizing vectors in U
-*              (Workspace: need 3*N+NCU, prefer 3*N+NCU*NB)
+*              (Workspace: need 3*N + NCU, prefer 3*N + NCU*NB)
 *
                CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
                IF( WNTUS )
 *
 *              If right singular vectors desired in VT, copy result to
 *              VT and generate right bidiagonalizing vectors in VT
-*              (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
+*              (Workspace: need 4*N-1, prefer 3*N + (N-1)*NB)
 *
                CALL DLACPY( 'U', N, N, A, LDA, VT, LDVT )
                CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
 *
 *              If left singular vectors desired in A, generate left
 *              bidiagonalizing vectors in A
-*              (Workspace: need 4*N, prefer 3*N+N*NB)
+*              (Workspace: need 4*N, prefer 3*N + N*NB)
 *
                CALL DORGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
      $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
 *
 *              If right singular vectors desired in A, generate right
 *              bidiagonalizing vectors in A
-*              (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
+*              (Workspace: need 4*N-1, prefer 3*N + (N-1)*NB)
 *
                CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
      $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
                IWORK = ITAU + M
 *
 *              Compute A=L*Q
-*              (Workspace: need 2*M, prefer M+M*NB)
+*              (Workspace: need 2*M, prefer M + M*NB)
 *
                CALL DGELQF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),
      $                      LWORK-IWORK+1, IERR )
                IWORK = ITAUP + M
 *
 *              Bidiagonalize L in A
-*              (Workspace: need 4*M, prefer 3*M+2*M*NB)
+*              (Workspace: need 4*M, prefer 3*M + 2*M*NB)
 *
                CALL DGEBRD( M, M, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
      $                      WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
                IF( WNTUO .OR. WNTUAS ) THEN
 *
 *                 If left singular vectors desired, generate Q
-*                 (Workspace: need 4*M, prefer 3*M+M*NB)
+*                 (Workspace: need 4*M, prefer 3*M + M*NB)
 *
                   CALL DORGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),
      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
 *                 Sufficient workspace for a fast algorithm
 *
                   IR = 1
-                  IF( LWORK.GE.MAX( WRKBL, LDA*N+M )+LDA*M ) THEN
+                  IF( LWORK.GE.MAX( WRKBL, LDA*N + M ) + LDA*M ) THEN
 *
 *                    WORK(IU) is LDA by N and WORK(IR) is LDA by M
 *
                      LDWRKU = LDA
                      CHUNK = N
                      LDWRKR = LDA
-                  ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N+M )+M*M ) THEN
+                  ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N + M ) + M*M ) THEN
 *
 *                    WORK(IU) is LDA by N and WORK(IR) is M by M
 *
                   IWORK = ITAU + M
 *
 *                 Compute A=L*Q
-*                 (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                 (Workspace: need M*M + 2*M, prefer M*M + M + M*NB)
 *
                   CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
      $                         WORK( IR+LDWRKR ), LDWRKR )
 *
 *                 Generate Q in A
-*                 (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                 (Workspace: need M*M + 2*M, prefer M*M + M + M*NB)
 *
                   CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                   IWORK = ITAUP + M
 *
 *                 Bidiagonalize L in WORK(IR)
-*                 (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
+*                 (Workspace: need M*M + 4*M, prefer M*M + 3*M + 2*M*NB)
 *
                   CALL DGEBRD( M, M, WORK( IR ), LDWRKR, S, WORK( IE ),
      $                         WORK( ITAUQ ), WORK( ITAUP ),
      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
 *
 *                 Generate right vectors bidiagonalizing L
-*                 (Workspace: need M*M+4*M-1, prefer M*M+3*M+(M-1)*NB)
+*                 (Workspace: need M*M + 4*M-1, prefer M*M + 3*M + (M-1)*NB)
 *
                   CALL DORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
      $                         WORK( ITAUP ), WORK( IWORK ),
 *
 *                 Perform bidiagonal QR iteration, computing right
 *                 singular vectors of L in WORK(IR)
-*                 (Workspace: need M*M+BDSPAC)
+*                 (Workspace: need M*M + BDSPAC)
 *
                   CALL DBDSQR( 'U', M, M, 0, 0, S, WORK( IE ),
      $                         WORK( IR ), LDWRKR, DUM, 1, DUM, 1,
 *
 *                 Multiply right singular vectors of L in WORK(IR) by Q
 *                 in A, storing result in WORK(IU) and copying to A
-*                 (Workspace: need M*M+2*M, prefer M*M+M*N+M)
+*                 (Workspace: need M*M + 2*M, prefer M*M + M*N + M)
 *
                   DO 30 I = 1, N, CHUNK
                      BLK = MIN( N-I+1, CHUNK )
                   IWORK = ITAUP + M
 *
 *                 Bidiagonalize A
-*                 (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB)
+*                 (Workspace: need 3*M + N, prefer 3*M + (M + N)*NB)
 *
                   CALL DGEBRD( M, N, A, LDA, S, WORK( IE ),
      $                         WORK( ITAUQ ), WORK( ITAUP ),
      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
 *
 *                 Generate right vectors bidiagonalizing A
-*                 (Workspace: need 4*M, prefer 3*M+M*NB)
+*                 (Workspace: need 4*M, prefer 3*M + M*NB)
 *
                   CALL DORGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
 *                 Sufficient workspace for a fast algorithm
 *
                   IR = 1
-                  IF( LWORK.GE.MAX( WRKBL, LDA*N+M )+LDA*M ) THEN
+                  IF( LWORK.GE.MAX( WRKBL, LDA*N + M ) + LDA*M ) THEN
 *
 *                    WORK(IU) is LDA by N and WORK(IR) is LDA by M
 *
                      LDWRKU = LDA
                      CHUNK = N
                      LDWRKR = LDA
-                  ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N+M )+M*M ) THEN
+                  ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N + M ) + M*M ) THEN
 *
 *                    WORK(IU) is LDA by N and WORK(IR) is M by M
 *
                   IWORK = ITAU + M
 *
 *                 Compute A=L*Q
-*                 (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                 (Workspace: need M*M + 2*M, prefer M*M + M + M*NB)
 *
                   CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
      $                         LDU )
 *
 *                 Generate Q in A
-*                 (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                 (Workspace: need M*M + 2*M, prefer M*M + M + M*NB)
 *
                   CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                   IWORK = ITAUP + M
 *
 *                 Bidiagonalize L in U, copying result to WORK(IR)
-*                 (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
+*                 (Workspace: need M*M + 4*M, prefer M*M + 3*M + 2*M*NB)
 *
                   CALL DGEBRD( M, M, U, LDU, S, WORK( IE ),
      $                         WORK( ITAUQ ), WORK( ITAUP ),
                   CALL DLACPY( 'U', M, M, U, LDU, WORK( IR ), LDWRKR )
 *
 *                 Generate right vectors bidiagonalizing L in WORK(IR)
-*                 (Workspace: need M*M+4*M-1, prefer M*M+3*M+(M-1)*NB)
+*                 (Workspace: need M*M + 4*M-1, prefer M*M + 3*M + (M-1)*NB)
 *
                   CALL DORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
      $                         WORK( ITAUP ), WORK( IWORK ),
      $                         LWORK-IWORK+1, IERR )
 *
 *                 Generate left vectors bidiagonalizing L in U
-*                 (Workspace: need M*M+4*M, prefer M*M+3*M+M*NB)
+*                 (Workspace: need M*M + 4*M, prefer M*M + 3*M + M*NB)
 *
                   CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
 *                 Perform bidiagonal QR iteration, computing left
 *                 singular vectors of L in U, and computing right
 *                 singular vectors of L in WORK(IR)
-*                 (Workspace: need M*M+BDSPAC)
+*                 (Workspace: need M*M + BDSPAC)
 *
                   CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),
      $                         WORK( IR ), LDWRKR, U, LDU, DUM, 1,
 *
 *                 Multiply right singular vectors of L in WORK(IR) by Q
 *                 in A, storing result in WORK(IU) and copying to A
-*                 (Workspace: need M*M+2*M, prefer M*M+M*N+M))
+*                 (Workspace: need M*M + 2*M, prefer M*M + M*N + M))
 *
                   DO 40 I = 1, N, CHUNK
                      BLK = MIN( N-I+1, CHUNK )
                   IWORK = ITAU + M
 *
 *                 Compute A=L*Q
-*                 (Workspace: need 2*M, prefer M+M*NB)
+*                 (Workspace: need 2*M, prefer M + M*NB)
 *
                   CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
      $                         LDU )
 *
 *                 Generate Q in A
-*                 (Workspace: need 2*M, prefer M+M*NB)
+*                 (Workspace: need 2*M, prefer M + M*NB)
 *
                   CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                   IWORK = ITAUP + M
 *
 *                 Bidiagonalize L in U
-*                 (Workspace: need 4*M, prefer 3*M+2*M*NB)
+*                 (Workspace: need 4*M, prefer 3*M + 2*M*NB)
 *
                   CALL DGEBRD( M, M, U, LDU, S, WORK( IE ),
      $                         WORK( ITAUQ ), WORK( ITAUP ),
      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
 *
 *                 Multiply right vectors bidiagonalizing L by Q in A
-*                 (Workspace: need 3*M+N, prefer 3*M+N*NB)
+*                 (Workspace: need 3*M + N, prefer 3*M + N*NB)
 *
                   CALL DORMBR( 'P', 'L', 'T', M, N, M, U, LDU,
      $                         WORK( ITAUP ), A, LDA, WORK( IWORK ),
      $                         LWORK-IWORK+1, IERR )
 *
 *                 Generate left vectors bidiagonalizing L in U
-*                 (Workspace: need 4*M, prefer 3*M+M*NB)
+*                 (Workspace: need 4*M, prefer 3*M + M*NB)
 *
                   CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                      IWORK = ITAU + M
 *
 *                    Compute A=L*Q
-*                    (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                    (Workspace: need M*M + 2*M, prefer M*M + M + M*NB)
 *
                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
      $                            WORK( IR+LDWRKR ), LDWRKR )
 *
 *                    Generate Q in A
-*                    (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                    (Workspace: need M*M + 2*M, prefer M*M + M + M*NB)
 *
                      CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      IWORK = ITAUP + M
 *
 *                    Bidiagonalize L in WORK(IR)
-*                    (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
+*                    (Workspace: need M*M + 4*M, prefer M*M + 3*M + 2*M*NB)
 *
                      CALL DGEBRD( M, M, WORK( IR ), LDWRKR, S,
      $                            WORK( IE ), WORK( ITAUQ ),
 *
 *                    Generate right vectors bidiagonalizing L in
 *                    WORK(IR)
-*                    (Workspace: need M*M+4*M, prefer M*M+3*M+(M-1)*NB)
+*                    (Workspace: need M*M + 4*M, prefer M*M + 3*M + (M-1)*NB)
 *
                      CALL DORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
      $                            WORK( ITAUP ), WORK( IWORK ),
 *
 *                    Perform bidiagonal QR iteration, computing right
 *                    singular vectors of L in WORK(IR)
-*                    (Workspace: need M*M+BDSPAC)
+*                    (Workspace: need M*M + BDSPAC)
 *
                      CALL DBDSQR( 'U', M, M, 0, 0, S, WORK( IE ),
      $                            WORK( IR ), LDWRKR, DUM, 1, DUM, 1,
                      IWORK = ITAU + M
 *
 *                    Compute A=L*Q
-*                    (Workspace: need 2*M, prefer M+M*NB)
+*                    (Workspace: need 2*M, prefer M + M*NB)
 *
                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
 *
 *                    Generate Q in VT
-*                    (Workspace: need 2*M, prefer M+M*NB)
+*                    (Workspace: need 2*M, prefer M + M*NB)
 *
                      CALL DORGLQ( M, N, M, VT, LDVT, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
      $                            LDA )
 *
 *                    Bidiagonalize L in A
-*                    (Workspace: need 4*M, prefer 3*M+2*M*NB)
+*                    (Workspace: need 4*M, prefer 3*M + 2*M*NB)
 *
                      CALL DGEBRD( M, M, A, LDA, S, WORK( IE ),
      $                            WORK( ITAUQ ), WORK( ITAUP ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
 *
 *                    Multiply right vectors bidiagonalizing L by Q in VT
-*                    (Workspace: need 3*M+N, prefer 3*M+N*NB)
+*                    (Workspace: need 3*M + N, prefer 3*M + N*NB)
 *
                      CALL DORMBR( 'P', 'L', 'T', M, N, M, A, LDA,
      $                            WORK( ITAUP ), VT, LDVT,
                         LDWRKU = LDA
                         IR = IU + LDWRKU*M
                         LDWRKR = LDA
-                     ELSE IF( LWORK.GE.WRKBL+( LDA+M )*M ) THEN
+                     ELSE IF( LWORK.GE.WRKBL+( LDA + M )*M ) THEN
 *
 *                       WORK(IU) is LDA by M and WORK(IR) is M by M
 *
                      IWORK = ITAU + M
 *
 *                    Compute A=L*Q
-*                    (Workspace: need 2*M*M+2*M, prefer 2*M*M+M+M*NB)
+*                    (Workspace: need 2*M*M + 2*M, prefer 2*M*M + M + M*NB)
 *
                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
      $                            WORK( IU+LDWRKU ), LDWRKU )
 *
 *                    Generate Q in A
-*                    (Workspace: need 2*M*M+2*M, prefer 2*M*M+M+M*NB)
+*                    (Workspace: need 2*M*M + 2*M, prefer 2*M*M + M + M*NB)
 *
                      CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
 *
 *                    Bidiagonalize L in WORK(IU), copying result to
 *                    WORK(IR)
-*                    (Workspace: need 2*M*M+4*M,
+*                    (Workspace: need 2*M*M + 4*M,
 *                                prefer 2*M*M+3*M+2*M*NB)
 *
                      CALL DGEBRD( M, M, WORK( IU ), LDWRKU, S,
      $                            WORK( IR ), LDWRKR )
 *
 *                    Generate right bidiagonalizing vectors in WORK(IU)
-*                    (Workspace: need 2*M*M+4*M-1,
+*                    (Workspace: need 2*M*M + 4*M-1,
 *                                prefer 2*M*M+3*M+(M-1)*NB)
 *
                      CALL DORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
      $                            LWORK-IWORK+1, IERR )
 *
 *                    Generate left bidiagonalizing vectors in WORK(IR)
-*                    (Workspace: need 2*M*M+4*M, prefer 2*M*M+3*M+M*NB)
+*                    (Workspace: need 2*M*M + 4*M, prefer 2*M*M + 3*M + M*NB)
 *
                      CALL DORGBR( 'Q', M, M, M, WORK( IR ), LDWRKR,
      $                            WORK( ITAUQ ), WORK( IWORK ),
 *                    Perform bidiagonal QR iteration, computing left
 *                    singular vectors of L in WORK(IR) and computing
 *                    right singular vectors of L in WORK(IU)
-*                    (Workspace: need 2*M*M+BDSPAC)
+*                    (Workspace: need 2*M*M + BDSPAC)
 *
                      CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),
      $                            WORK( IU ), LDWRKU, WORK( IR ),
                      IWORK = ITAU + M
 *
 *                    Compute A=L*Q, copying result to VT
-*                    (Workspace: need 2*M, prefer M+M*NB)
+*                    (Workspace: need 2*M, prefer M + M*NB)
 *
                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
 *
 *                    Generate Q in VT
-*                    (Workspace: need 2*M, prefer M+M*NB)
+*                    (Workspace: need 2*M, prefer M + M*NB)
 *
                      CALL DORGLQ( M, N, M, VT, LDVT, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
      $                            LDA )
 *
 *                    Bidiagonalize L in A
-*                    (Workspace: need 4*M, prefer 3*M+2*M*NB)
+*                    (Workspace: need 4*M, prefer 3*M + 2*M*NB)
 *
                      CALL DGEBRD( M, M, A, LDA, S, WORK( IE ),
      $                            WORK( ITAUQ ), WORK( ITAUP ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
 *
 *                    Multiply right vectors bidiagonalizing L by Q in VT
-*                    (Workspace: need 3*M+N, prefer 3*M+N*NB)
+*                    (Workspace: need 3*M + N, prefer 3*M + N*NB)
 *
                      CALL DORMBR( 'P', 'L', 'T', M, N, M, A, LDA,
      $                            WORK( ITAUP ), VT, LDVT,
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
 *
 *                    Generate left bidiagonalizing vectors of L in A
-*                    (Workspace: need 4*M, prefer 3*M+M*NB)
+*                    (Workspace: need 4*M, prefer 3*M + M*NB)
 *
                      CALL DORGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      IWORK = ITAU + M
 *
 *                    Compute A=L*Q
-*                    (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                    (Workspace: need M*M + 2*M, prefer M*M + M + M*NB)
 *
                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
      $                            WORK( IU+LDWRKU ), LDWRKU )
 *
 *                    Generate Q in A
-*                    (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                    (Workspace: need M*M + 2*M, prefer M*M + M + M*NB)
 *
                      CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      IWORK = ITAUP + M
 *
 *                    Bidiagonalize L in WORK(IU), copying result to U
-*                    (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
+*                    (Workspace: need M*M + 4*M, prefer M*M + 3*M + 2*M*NB)
 *
                      CALL DGEBRD( M, M, WORK( IU ), LDWRKU, S,
      $                            WORK( IE ), WORK( ITAUQ ),
      $                            LDU )
 *
 *                    Generate right bidiagonalizing vectors in WORK(IU)
-*                    (Workspace: need M*M+4*M-1,
+*                    (Workspace: need M*M + 4*M-1,
 *                                prefer M*M+3*M+(M-1)*NB)
 *
                      CALL DORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
      $                            LWORK-IWORK+1, IERR )
 *
 *                    Generate left bidiagonalizing vectors in U
-*                    (Workspace: need M*M+4*M, prefer M*M+3*M+M*NB)
+*                    (Workspace: need M*M + 4*M, prefer M*M + 3*M + M*NB)
 *
                      CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
 *                    Perform bidiagonal QR iteration, computing left
 *                    singular vectors of L in U and computing right
 *                    singular vectors of L in WORK(IU)
-*                    (Workspace: need M*M+BDSPAC)
+*                    (Workspace: need M*M + BDSPAC)
 *
                      CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),
      $                            WORK( IU ), LDWRKU, U, LDU, DUM, 1,
                      IWORK = ITAU + M
 *
 *                    Compute A=L*Q, copying result to VT
-*                    (Workspace: need 2*M, prefer M+M*NB)
+*                    (Workspace: need 2*M, prefer M + M*NB)
 *
                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
 *
 *                    Generate Q in VT
-*                    (Workspace: need 2*M, prefer M+M*NB)
+*                    (Workspace: need 2*M, prefer M + M*NB)
 *
                      CALL DORGLQ( M, N, M, VT, LDVT, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      IWORK = ITAUP + M
 *
 *                    Bidiagonalize L in U
-*                    (Workspace: need 4*M, prefer 3*M+2*M*NB)
+*                    (Workspace: need 4*M, prefer 3*M + 2*M*NB)
 *
                      CALL DGEBRD( M, M, U, LDU, S, WORK( IE ),
      $                            WORK( ITAUQ ), WORK( ITAUP ),
 *
 *                    Multiply right bidiagonalizing vectors in U by Q
 *                    in VT
-*                    (Workspace: need 3*M+N, prefer 3*M+N*NB)
+*                    (Workspace: need 3*M + N, prefer 3*M + N*NB)
 *
                      CALL DORMBR( 'P', 'L', 'T', M, N, M, U, LDU,
      $                            WORK( ITAUP ), VT, LDVT,
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
 *
 *                    Generate left bidiagonalizing vectors in U
-*                    (Workspace: need 4*M, prefer 3*M+M*NB)
+*                    (Workspace: need 4*M, prefer 3*M + M*NB)
 *
                      CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
 *                 N right singular vectors to be computed in VT and
 *                 no left singular vectors to be computed
 *
-                  IF( LWORK.GE.M*M+MAX( N+M, 4*M, BDSPAC ) ) THEN
+                  IF( LWORK.GE.M*M+MAX( N + M, 4*M, BDSPAC ) ) THEN
 *
 *                    Sufficient workspace for a fast algorithm
 *
                      IWORK = ITAU + M
 *
 *                    Compute A=L*Q, copying result to VT
-*                    (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                    (Workspace: need M*M + 2*M, prefer M*M + M + M*NB)
 *
                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
      $                            WORK( IR+LDWRKR ), LDWRKR )
 *
 *                    Generate Q in VT
-*                    (Workspace: need M*M+M+N, prefer M*M+M+N*NB)
+*                    (Workspace: need M*M + M + N, prefer M*M + M + N*NB)
 *
                      CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      IWORK = ITAUP + M
 *
 *                    Bidiagonalize L in WORK(IR)
-*                    (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
+*                    (Workspace: need M*M + 4*M, prefer M*M + 3*M + 2*M*NB)
 *
                      CALL DGEBRD( M, M, WORK( IR ), LDWRKR, S,
      $                            WORK( IE ), WORK( ITAUQ ),
      $                            LWORK-IWORK+1, IERR )
 *
 *                    Generate right bidiagonalizing vectors in WORK(IR)
-*                    (Workspace: need M*M+4*M-1,
+*                    (Workspace: need M*M + 4*M-1,
 *                                prefer M*M+3*M+(M-1)*NB)
 *
                      CALL DORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
 *
 *                    Perform bidiagonal QR iteration, computing right
 *                    singular vectors of L in WORK(IR)
-*                    (Workspace: need M*M+BDSPAC)
+*                    (Workspace: need M*M + BDSPAC)
 *
                      CALL DBDSQR( 'U', M, M, 0, 0, S, WORK( IE ),
      $                            WORK( IR ), LDWRKR, DUM, 1, DUM, 1,
                      IWORK = ITAU + M
 *
 *                    Compute A=L*Q, copying result to VT
-*                    (Workspace: need 2*M, prefer M+M*NB)
+*                    (Workspace: need 2*M, prefer M + M*NB)
 *
                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
 *
 *                    Generate Q in VT
-*                    (Workspace: need M+N, prefer M+N*NB)
+*                    (Workspace: need M + N, prefer M + N*NB)
 *
                      CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
      $                            LDA )
 *
 *                    Bidiagonalize L in A
-*                    (Workspace: need 4*M, prefer 3*M+2*M*NB)
+*                    (Workspace: need 4*M, prefer 3*M + 2*M*NB)
 *
                      CALL DGEBRD( M, M, A, LDA, S, WORK( IE ),
      $                            WORK( ITAUQ ), WORK( ITAUP ),
 *
 *                    Multiply right bidiagonalizing vectors in A by Q
 *                    in VT
-*                    (Workspace: need 3*M+N, prefer 3*M+N*NB)
+*                    (Workspace: need 3*M + N, prefer 3*M + N*NB)
 *
                      CALL DORMBR( 'P', 'L', 'T', M, N, M, A, LDA,
      $                            WORK( ITAUP ), VT, LDVT,
 *                 N right singular vectors to be computed in VT and
 *                 M left singular vectors to be overwritten on A
 *
-                  IF( LWORK.GE.2*M*M+MAX( N+M, 4*M, BDSPAC ) ) THEN
+                  IF( LWORK.GE.2*M*M+MAX( N + M, 4*M, BDSPAC ) ) THEN
 *
 *                    Sufficient workspace for a fast algorithm
 *
                         LDWRKU = LDA
                         IR = IU + LDWRKU*M
                         LDWRKR = LDA
-                     ELSE IF( LWORK.GE.WRKBL+( LDA+M )*M ) THEN
+                     ELSE IF( LWORK.GE.WRKBL+( LDA + M )*M ) THEN
 *
 *                       WORK(IU) is LDA by M and WORK(IR) is M by M
 *
                      IWORK = ITAU + M
 *
 *                    Compute A=L*Q, copying result to VT
-*                    (Workspace: need 2*M*M+2*M, prefer 2*M*M+M+M*NB)
+*                    (Workspace: need 2*M*M + 2*M, prefer 2*M*M + M + M*NB)
 *
                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
 *
 *                    Generate Q in VT
-*                    (Workspace: need 2*M*M+M+N, prefer 2*M*M+M+N*NB)
+*                    (Workspace: need 2*M*M + M + N, prefer 2*M*M + M + N*NB)
 *
                      CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
 *
 *                    Bidiagonalize L in WORK(IU), copying result to
 *                    WORK(IR)
-*                    (Workspace: need 2*M*M+4*M,
+*                    (Workspace: need 2*M*M + 4*M,
 *                                prefer 2*M*M+3*M+2*M*NB)
 *
                      CALL DGEBRD( M, M, WORK( IU ), LDWRKU, S,
      $                            WORK( IR ), LDWRKR )
 *
 *                    Generate right bidiagonalizing vectors in WORK(IU)
-*                    (Workspace: need 2*M*M+4*M-1,
+*                    (Workspace: need 2*M*M + 4*M-1,
 *                                prefer 2*M*M+3*M+(M-1)*NB)
 *
                      CALL DORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
      $                            LWORK-IWORK+1, IERR )
 *
 *                    Generate left bidiagonalizing vectors in WORK(IR)
-*                    (Workspace: need 2*M*M+4*M, prefer 2*M*M+3*M+M*NB)
+*                    (Workspace: need 2*M*M + 4*M, prefer 2*M*M + 3*M + M*NB)
 *
                      CALL DORGBR( 'Q', M, M, M, WORK( IR ), LDWRKR,
      $                            WORK( ITAUQ ), WORK( IWORK ),
 *                    Perform bidiagonal QR iteration, computing left
 *                    singular vectors of L in WORK(IR) and computing
 *                    right singular vectors of L in WORK(IU)
-*                    (Workspace: need 2*M*M+BDSPAC)
+*                    (Workspace: need 2*M*M + BDSPAC)
 *
                      CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),
      $                            WORK( IU ), LDWRKU, WORK( IR ),
                      IWORK = ITAU + M
 *
 *                    Compute A=L*Q, copying result to VT
-*                    (Workspace: need 2*M, prefer M+M*NB)
+*                    (Workspace: need 2*M, prefer M + M*NB)
 *
                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
 *
 *                    Generate Q in VT
-*                    (Workspace: need M+N, prefer M+N*NB)
+*                    (Workspace: need M + N, prefer M + N*NB)
 *
                      CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
      $                            LDA )
 *
 *                    Bidiagonalize L in A
-*                    (Workspace: need 4*M, prefer 3*M+2*M*NB)
+*                    (Workspace: need 4*M, prefer 3*M + 2*M*NB)
 *
                      CALL DGEBRD( M, M, A, LDA, S, WORK( IE ),
      $                            WORK( ITAUQ ), WORK( ITAUP ),
 *
 *                    Multiply right bidiagonalizing vectors in A by Q
 *                    in VT
-*                    (Workspace: need 3*M+N, prefer 3*M+N*NB)
+*                    (Workspace: need 3*M + N, prefer 3*M + N*NB)
 *
                      CALL DORMBR( 'P', 'L', 'T', M, N, M, A, LDA,
      $                            WORK( ITAUP ), VT, LDVT,
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
 *
 *                    Generate left bidiagonalizing vectors in A
-*                    (Workspace: need 4*M, prefer 3*M+M*NB)
+*                    (Workspace: need 4*M, prefer 3*M + M*NB)
 *
                      CALL DORGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
 *                 N right singular vectors to be computed in VT and
 *                 M left singular vectors to be computed in U
 *
-                  IF( LWORK.GE.M*M+MAX( N+M, 4*M, BDSPAC ) ) THEN
+                  IF( LWORK.GE.M*M+MAX( N + M, 4*M, BDSPAC ) ) THEN
 *
 *                    Sufficient workspace for a fast algorithm
 *
                      IWORK = ITAU + M
 *
 *                    Compute A=L*Q, copying result to VT
-*                    (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                    (Workspace: need M*M + 2*M, prefer M*M + M + M*NB)
 *
                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
 *
 *                    Generate Q in VT
-*                    (Workspace: need M*M+M+N, prefer M*M+M+N*NB)
+*                    (Workspace: need M*M + M + N, prefer M*M + M + N*NB)
 *
                      CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      IWORK = ITAUP + M
 *
 *                    Bidiagonalize L in WORK(IU), copying result to U
-*                    (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
+*                    (Workspace: need M*M + 4*M, prefer M*M + 3*M + 2*M*NB)
 *
                      CALL DGEBRD( M, M, WORK( IU ), LDWRKU, S,
      $                            WORK( IE ), WORK( ITAUQ ),
      $                            LDU )
 *
 *                    Generate right bidiagonalizing vectors in WORK(IU)
-*                    (Workspace: need M*M+4*M, prefer M*M+3*M+(M-1)*NB)
+*                    (Workspace: need M*M + 4*M, prefer M*M + 3*M + (M-1)*NB)
 *
                      CALL DORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
      $                            WORK( ITAUP ), WORK( IWORK ),
      $                            LWORK-IWORK+1, IERR )
 *
 *                    Generate left bidiagonalizing vectors in U
-*                    (Workspace: need M*M+4*M, prefer M*M+3*M+M*NB)
+*                    (Workspace: need M*M + 4*M, prefer M*M + 3*M + M*NB)
 *
                      CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
 *                    Perform bidiagonal QR iteration, computing left
 *                    singular vectors of L in U and computing right
 *                    singular vectors of L in WORK(IU)
-*                    (Workspace: need M*M+BDSPAC)
+*                    (Workspace: need M*M + BDSPAC)
 *
                      CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),
      $                            WORK( IU ), LDWRKU, U, LDU, DUM, 1,
                      IWORK = ITAU + M
 *
 *                    Compute A=L*Q, copying result to VT
-*                    (Workspace: need 2*M, prefer M+M*NB)
+*                    (Workspace: need 2*M, prefer M + M*NB)
 *
                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
 *
 *                    Generate Q in VT
-*                    (Workspace: need M+N, prefer M+N*NB)
+*                    (Workspace: need M + N, prefer M + N*NB)
 *
                      CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                      IWORK = ITAUP + M
 *
 *                    Bidiagonalize L in U
-*                    (Workspace: need 4*M, prefer 3*M+2*M*NB)
+*                    (Workspace: need 4*M, prefer 3*M + 2*M*NB)
 *
                      CALL DGEBRD( M, M, U, LDU, S, WORK( IE ),
      $                            WORK( ITAUQ ), WORK( ITAUP ),
 *
 *                    Multiply right bidiagonalizing vectors in U by Q
 *                    in VT
-*                    (Workspace: need 3*M+N, prefer 3*M+N*NB)
+*                    (Workspace: need 3*M + N, prefer 3*M + N*NB)
 *
                      CALL DORMBR( 'P', 'L', 'T', M, N, M, U, LDU,
      $                            WORK( ITAUP ), VT, LDVT,
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
 *
 *                    Generate left bidiagonalizing vectors in U
-*                    (Workspace: need 4*M, prefer 3*M+M*NB)
+*                    (Workspace: need 4*M, prefer 3*M + M*NB)
 *
                      CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
             IWORK = ITAUP + M
 *
 *           Bidiagonalize A
-*           (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB)
+*           (Workspace: need 3*M + N, prefer 3*M + (M + N)*NB)
 *
             CALL DGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
      $                   WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
 *
 *              If left singular vectors desired in U, copy result to U
 *              and generate left bidiagonalizing vectors in U
-*              (Workspace: need 4*M-1, prefer 3*M+(M-1)*NB)
+*              (Workspace: need 4*M-1, prefer 3*M + (M-1)*NB)
 *
                CALL DLACPY( 'L', M, M, A, LDA, U, LDU )
                CALL DORGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
 *
 *              If right singular vectors desired in VT, copy result to
 *              VT and generate right bidiagonalizing vectors in VT
-*              (Workspace: need 3*M+NRVT, prefer 3*M+NRVT*NB)
+*              (Workspace: need 3*M + NRVT, prefer 3*M + NRVT*NB)
 *
                CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
                IF( WNTVA )
 *
 *              If left singular vectors desired in A, generate left
 *              bidiagonalizing vectors in A
-*              (Workspace: need 4*M-1, prefer 3*M+(M-1)*NB)
+*              (Workspace: need 4*M-1, prefer 3*M + (M-1)*NB)
 *
                CALL DORGBR( 'Q', M, M, N, A, LDA, WORK( ITAUQ ),
      $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
 *
 *              If right singular vectors desired in A, generate right
 *              bidiagonalizing vectors in A
-*              (Workspace: need 4*M, prefer 3*M+M*NB)
+*              (Workspace: need 4*M, prefer 3*M + M*NB)
 *
                CALL DORGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
      $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
index cfa2ff05d37b9702f94562e412776d3d99477040..accf2594e27dd5f0171665932c76bc745fde15c1 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is DOUBLE PRECISION
-*>          VL >=0.
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for singular values. VU > VL.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is DOUBLE PRECISION
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for singular values. VU > VL.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest singular value to be returned.
+*>          1 <= IL <= IU <= min(M,N), if min(M,N) > 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest singular values to be returned.
+*>          If RANGE='I', the index of the
+*>          largest singular value to be returned.
 *>          1 <= IL <= IU <= min(M,N), if min(M,N) > 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>          vectors, stored columnwise) as specified by RANGE; if 
 *>          JOBU = 'N', U is not referenced.
 *>          Note: The user must ensure that UCOL >= NS; if RANGE = 'V', 
-*>          the exact value of NS is not known ILQFin advance and an upper 
+*>          the exact value of NS is not known in advance and an upper
 *>          bound must be used.
 *> \endverbatim
 *>
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup doubleGEsing
 *
      $                    IL, IU, NS, S, U, LDU, VT, LDVT, WORK, 
      $                    LWORK, IWORK, INFO )
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBU, JOBVT, RANGE
          IF( INFO.EQ.0 ) THEN
             IF( WANTU .AND. LDU.LT.M ) THEN
                INFO = -15
-            ELSE IF( WANTVT .AND. LDVT.LT.MINMN ) THEN
-               INFO = -16
+            ELSE IF( WANTVT ) THEN
+               IF( INDS ) THEN
+                   IF( LDVT.LT.IU-IL+1 ) THEN
+                       INFO = -17
+                   END IF
+               ELSE IF( LDVT.LT.MINMN ) THEN
+                   INFO = -17
+               END IF
             END IF
          END IF
       END IF
 *
 *                 Path 1 (M much larger than N)
 *
-                  MAXWRK = N*(N*2+16) + 
+                  MAXWRK = N + 
      $                     N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
-                  MAXWRK = MAX( MAXWRK, N*(N*2+20) + 2*N*
+                  MAXWRK = MAX( MAXWRK, N*(N+5) + 2*N*
      $                     ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
-                  MINWRK = N*(N*2+21)
+                  IF (WANTU) THEN
+                      MAXWRK = MAX(MAXWRK,N*(N*3+6)+N*
+     $                     ILAENV( 1, 'DORMQR', ' ', N, N, -1, -1 ) )
+                  END IF
+                  IF (WANTVT) THEN
+                      MAXWRK = MAX(MAXWRK,N*(N*3+6)+N*
+     $                     ILAENV( 1, 'DORMLQ', ' ', N, N, -1, -1 ) )
+                  END IF
+                  MINWRK = N*(N*3+20)
                ELSE
 *
 *                 Path 2 (M at least N, but not much larger)
 *
-                  MAXWRK = N*(N*2+19) + ( M+N )*
+                  MAXWRK = 4*N + ( M+N )*
      $                     ILAENV( 1, 'DGEBRD', ' ', M, N, -1, -1 )
-                  MINWRK = N*(N*2+20) + M
+                  IF (WANTU) THEN
+                      MAXWRK = MAX(MAXWRK,N*(N*2+5)+N*
+     $                     ILAENV( 1, 'DORMQR', ' ', N, N, -1, -1 ) )
+                  END IF
+                  IF (WANTVT) THEN
+                      MAXWRK = MAX(MAXWRK,N*(N*2+5)+N*
+     $                     ILAENV( 1, 'DORMLQ', ' ', N, N, -1, -1 ) )
+                  END IF
+                  MINWRK = MAX(N*(N*2+19),4*N+M)
                END IF
             ELSE
                MNTHR = ILAENV( 6, 'DGESVD', JOBU // JOBVT, M, N, 0, 0 )
 *
 *                 Path 1t (N much larger than M)
 *
-                  MAXWRK = M*(M*2+16) + 
+                  MAXWRK = M + 
      $                     M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
-                  MAXWRK = MAX( MAXWRK, M*(M*2+20) + 2*M*
+                  MAXWRK = MAX( MAXWRK, M*(M+5) + 2*M*
      $                     ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
-                  MINWRK = M*(M*2+21)
+                  IF (WANTU) THEN
+                      MAXWRK = MAX(MAXWRK,M*(M*3+6)+M*
+     $                     ILAENV( 1, 'DORMQR', ' ', M, M, -1, -1 ) )
+                  END IF
+                  IF (WANTVT) THEN
+                      MAXWRK = MAX(MAXWRK,M*(M*3+6)+M*
+     $                     ILAENV( 1, 'DORMLQ', ' ', M, M, -1, -1 ) )
+                  END IF
+                  MINWRK = M*(M*3+20)
                ELSE
 *
-*                 Path 2t (N greater than M, but not much larger)
+*                 Path 2t (N at least M, but not much larger)
 *
-                  MAXWRK = M*(M*2+19) + ( M+N )*
+                  MAXWRK = 4*M + ( M+N )*
      $                     ILAENV( 1, 'DGEBRD', ' ', M, N, -1, -1 )
-                  MINWRK = M*(M*2+20) + N
+                  IF (WANTU) THEN
+                      MAXWRK = MAX(MAXWRK,M*(M*2+5)+M*
+     $                     ILAENV( 1, 'DORMQR', ' ', M, M, -1, -1 ) )
+                  END IF
+                  IF (WANTVT) THEN
+                      MAXWRK = MAX(MAXWRK,M*(M*2+5)+M*
+     $                     ILAENV( 1, 'DORMLQ', ' ', M, M, -1, -1 ) )
+                  END IF
+                  MINWRK = MAX(M*(M*2+19),4*M+N)
                END IF
             END IF
          END IF
                   CALL DCOPY( N, WORK( J ), 1, U( 1,I ), 1 )
                   J = J + N*2
                END DO
-               CALL DLASET( 'A', M-N, N, ZERO, ZERO, U( N+1,1 ), LDU )
+               CALL DLASET( 'A', M-N, NS, ZERO, ZERO, U( N+1,1 ), LDU )
 *
 *              Call DORMBR to compute QB*UB.
 *              (Workspace in WORK( ITEMP ): need N, prefer N*NB)
                   CALL DCOPY( N, WORK( J ), 1, U( 1,I ), 1 )
                   J = J + N*2
                END DO
-               CALL DLASET( 'A', M-N, N, ZERO, ZERO, U( N+1,1 ), LDU )
+               CALL DLASET( 'A', M-N, NS, ZERO, ZERO, U( N+1,1 ), LDU )
 *
 *              Call DORMBR to compute QB*UB.
 *              (Workspace in WORK( ITEMP ): need N, prefer N*NB)
                   CALL DCOPY( M, WORK( J ), 1, VT( I,1 ), LDVT )
                   J = J + M*2
                END DO
-               CALL DLASET( 'A', M, N-M, ZERO, ZERO, VT( 1,M+1 ), LDVT )
+               CALL DLASET( 'A', NS, N-M, ZERO, ZERO, VT( 1,M+1 ), LDVT)
 *
 *              Call DORMBR to compute (VB**T)*(PB**T)
 *              (Workspace in WORK( ITEMP ): need M, prefer M*NB)
                   CALL DCOPY( M, WORK( J ), 1, VT( I,1 ), LDVT )
                   J = J + M*2
                END DO
-               CALL DLASET( 'A', M, N-M, ZERO, ZERO, VT( 1,M+1 ), LDVT )
+               CALL DLASET( 'A', NS, N-M, ZERO, ZERO, VT( 1,M+1 ), LDVT)
 *
 *              Call DORMBR to compute VB**T * PB**T
 *              (Workspace in WORK( ITEMP ): need M, prefer M*NB)
index 3cd7eeb2ba82c71dd3c99fd797fac44c648ab6ee..3f6be168d7504196844f9f207ee29f6635d94b3a 100644 (file)
@@ -98,7 +98,7 @@
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2013
+*> \date June 2016
 *
 *> \ingroup doubleGEauxiliary
 *
 *  =====================================================================
       SUBROUTINE DGETC2( N, A, LDA, IPIV, JPIV, INFO )
 *
-*  -- LAPACK auxiliary routine (version 3.5.0) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2013
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            INFO, LDA, N
index b1871b5dd45e762f8ea6868e72f14a0cebd18820..30aa42d680ab800c140f7d00e08cefa4449ee71d 100644 (file)
@@ -37,7 +37,7 @@
 *> 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)
+*>    A = [ -----|----- ]  with n1 = min(m,n)/2
 *>        [  A21 | A22  ]       n2 = n-n1
 *>            
 *>                                       [ A11 ]
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup doubleGEcomputational
 *
 *  =====================================================================
       RECURSIVE SUBROUTINE DGETRF2( M, N, A, LDA, IPIV, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            INFO, LDA, M, N
index 812df3f232570975460a169cb13015d8bf7a70d6..034e94389d4777e79e9da3ca1eaef93fe500f96e 100644 (file)
       SUBROUTINE DGGHD3( COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB, Q,
      $                   LDQ, Z, LDZ, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     January 2015
 *
       INFO = 0
       NB = ILAENV( 1, 'DGGHD3', ' ', N, ILO, IHI, -1 )
-      LWKOPT = 6*N*NB
+      LWKOPT = MAX( 6*N*NB, 1 )
       WORK( 1 ) = DBLE( LWKOPT )
       INITQ = LSAME( COMPQ, 'I' )
       WANTQ = INITQ .OR. LSAME( COMPQ, 'V' )
index b32ba0fe63973b230062b5daa9edfcf97a819bd4..a0620d65f120fe9bb4e8959f0a517bbbed91ae84 100644 (file)
@@ -1,4 +1,4 @@
-*> \brief \b DGSVJ1 pre-processor for the routine sgesvj, applies Jacobi rotations targeting only particular pivots.
+*> \brief \b DGSVJ1 pre-processor for the routine dgesvj, applies Jacobi rotations targeting only particular pivots.
 *
 *  =========== DOCUMENTATION ===========
 *
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup doubleOTHERcomputational
 *
       SUBROUTINE DGSVJ1( JOBV, M, N, N1, A, LDA, D, SVA, MV, V, LDV,
      $                   EPS, SFMIN, TOL, NSWEEP, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       DOUBLE PRECISION   EPS, SFMIN, TOL
index bf6e414d72b67e745e6b5719180738292f091827..e5b02fc7fe10754af7afa91ed4f2e3fd65d9353e 100644 (file)
 *> \param[in,out] Q
 *> \verbatim
 *>          Q is DOUBLE PRECISION array, dimension (LDQ, N)
-*>          On entry, if COMPZ = 'V', the orthogonal matrix Q1 used in
+*>          On entry, if COMPQ = 'V', the orthogonal matrix Q1 used in
 *>          the reduction of (A,B) to generalized Hessenberg form.
-*>          On exit, if COMPZ = 'I', the orthogonal matrix of left Schur
-*>          vectors of (H,T), and if COMPZ = 'V', the orthogonal matrix
+*>          On exit, if COMPQ = 'I', the orthogonal matrix of left Schur
+*>          vectors of (H,T), and if COMPQ = 'V', the orthogonal matrix
 *>          of left Schur vectors of (A,B).
-*>          Not referenced if COMPZ = 'N'.
+*>          Not referenced if COMPQ = 'N'.
 *> \endverbatim
 *>
 *> \param[in] LDQ
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2013
+*> \date June 2016
 *
 *> \ingroup doubleGEcomputational
 *
      $                   ALPHAR, ALPHAI, BETA, Q, LDQ, Z, LDZ, WORK,
      $                   LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.5.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2013
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          COMPQ, COMPZ, JOB
index c37c1d2100c3fe533705cd2319ecaf88ea19ca9c..b4e018364fb0a5e383dc475fd6c1c4af882c7e6a 100644 (file)
@@ -54,7 +54,7 @@
 *>
 *>       The first stage consists of deflating the size of the problem
 *>       when there are multiple eigenvalues or if there is a zero in
-*>       the Z vector.  For each such occurence the dimension of the
+*>       the Z vector.  For each such occurrence the dimension of the
 *>       secular equation problem is reduced by one.  This stage is
 *>       performed by the routine DLAED2.
 *>
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup auxOTHERcomputational
 *
       SUBROUTINE DLAED1( N, D, Q, LDQ, INDXQ, RHO, CUTPNT, WORK, IWORK,
      $                   INFO )
 *
-*  -- LAPACK computational routine (version 3.4.2) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            CUTPNT, INFO, LDQ, N
index 658ece9a08aca90095fa102f99a82c5593927314..babd57be3eb56d3417ca675a2ef21651a2d57586 100644 (file)
@@ -59,7 +59,7 @@
 *>
 *>       The first stage consists of deflating the size of the problem
 *>       when there are multiple eigenvalues or if there is a zero in
-*>       the Z vector.  For each such occurence the dimension of the
+*>       the Z vector.  For each such occurrence the dimension of the
 *>       secular equation problem is reduced by one.  This stage is
 *>       performed by the routine DLAED8.
 *>
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup auxOTHERcomputational
 *
      $                   PERM, GIVPTR, GIVCOL, GIVNUM, WORK, IWORK,
      $                   INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            CURLVL, CURPBM, CUTPNT, ICOMPQ, INFO, LDQ, N,
index a941b940b00ce8772da39c335e567f7d78cd0b47..1e3366c9bfd991e7bad44b2b32d81fe8da36faa6 100644 (file)
@@ -99,7 +99,7 @@
 *>          will always be positive.  If the eigenvalues are real, then
 *>          the first (real) eigenvalue is  WR1 / SCALE1 , but this may
 *>          overflow or underflow, and in fact, SCALE1 may be zero or
-*>          less than the underflow threshhold if the exact eigenvalue
+*>          less than the underflow threshold if the exact eigenvalue
 *>          is sufficiently large.
 *> \endverbatim
 *>
 *>          eigenvalues are real, then the second (real) eigenvalue is
 *>          WR2 / SCALE2 , but this may overflow or underflow, and in
 *>          fact, SCALE2 may be zero or less than the underflow
-*>          threshhold if the exact eigenvalue is sufficiently large.
+*>          threshold if the exact eigenvalue is sufficiently large.
 *> \endverbatim
 *>
 *> \param[out] WR1
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup doubleOTHERauxiliary
 *
       SUBROUTINE DLAG2( A, LDA, B, LDB, SAFMIN, SCALE1, SCALE2, WR1,
      $                  WR2, WI )
 *
-*  -- LAPACK auxiliary routine (version 3.4.2) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            LDA, LDB
 *     Note: the test of R in the following IF is to cover the case when
 *           DISCR is small and negative and is flushed to zero during
 *           the calculation of R.  On machines which have a consistent
-*           flush-to-zero threshhold and handle numbers above that
-*           threshhold correctly, it would not be necessary.
+*           flush-to-zero threshold and handle numbers above that
+*           threshold correctly, it would not be necessary.
 *
       IF( DISCR.GE.ZERO .OR. R.EQ.ZERO ) THEN
          SUM = PP + SIGN( R, PP )
index 7126053e8a43ebeb48290cbda628d4d82810681f..8e9d37bd165981b78fa8252bf8b52c259ad03983 100644 (file)
@@ -50,7 +50,7 @@
 *> \param[in] N2
 *> \verbatim
 *>          N2 is INTEGER
-*>         These arguements contain the respective lengths of the two
+*>         These arguments contain the respective lengths of the two
 *>         sorted lists to be merged.
 *> \endverbatim
 *>
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup auxOTHERcomputational
 *
 *  =====================================================================
       SUBROUTINE DLAMRG( N1, N2, A, DTRD1, DTRD2, INDEX )
 *
-*  -- LAPACK computational routine (version 3.4.2) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            DTRD1, DTRD2, N1, N2
index aac01a49fabc8fd2fcd58ebb8794d13fa2e544cb..103cd366fb1680920c1c4630178fb585c5dcf393 100644 (file)
 *>          Z is DOUBLE PRECISION array, dimension (LDZ,N)
 *>          IF WANTZ is .TRUE., then on output, the orthogonal
 *>          similarity transformation mentioned above has been
-*>          accumulated into Z(ILOZ:IHIZ,ILO:IHI) from the right.
+*>          accumulated into Z(ILOZ:IHIZ,ILOZ:IHIZ) from the right.
 *>          If WANTZ is .FALSE., then Z is unreferenced.
 *> \endverbatim
 *>
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup doubleOTHERauxiliary
 *
      $                   IHIZ, Z, LDZ, NS, ND, SR, SI, V, LDV, NH, T,
      $                   LDT, NV, WV, LDWV, WORK, LWORK )
 *
-*  -- LAPACK auxiliary routine (version 3.4.2) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            IHIZ, ILOZ, KBOT, KTOP, LDH, LDT, LDV, LDWV,
index 37ce6f6b02ec26ad23db06eebeaa3fac15f2fdf8..b28df32aa7d7c509cdf81d2ea56b745144d79c0b 100644 (file)
 *>
 *> \param[in,out] Z
 *> \verbatim
-*>          Z is DOUBLE PRECISION array of size (LDZ,IHI)
+*>          Z is DOUBLE PRECISION array of size (LDZ,IHIZ)
 *>             If WANTZ = .TRUE., then the QR Sweep orthogonal
 *>             similarity transformation is accumulated into
-*>             Z(ILOZ:IHIZ,ILO:IHI) from the right.
+*>             Z(ILOZ:IHIZ,ILOZ:IHIZ) from the right.
 *>             If WANTZ = .FALSE., then Z is unreferenced.
 *> \endverbatim
 *>
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup doubleOTHERauxiliary
 *
      $                   SR, SI, H, LDH, ILOZ, IHIZ, Z, LDZ, V, LDV, U,
      $                   LDU, NV, WV, LDWV, NH, WH, LDWH )
 *
-*  -- LAPACK auxiliary routine (version 3.4.2) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            IHIZ, ILOZ, KACC22, KBOT, KTOP, LDH, LDU, LDV,
index f093563e9f3c8c9375347f86d6fca03d4ca6cf23..9a6f7f79532069db0753c53679d060b7570eecdd 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is DOUBLE PRECISION
+*>          The lower bound for the eigenvalues.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is DOUBLE PRECISION
-*>          The lower and upper bounds for the eigenvalues.
+*>          The upper bound for the eigenvalues.
 *> \endverbatim
 *>
 *> \param[in] D
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup auxOTHERauxiliary
 *
       SUBROUTINE DLARRC( JOBT, N, VL, VU, D, E, PIVMIN,
      $                            EIGCNT, LCNT, RCNT, INFO )
 *
-*  -- LAPACK auxiliary routine (version 3.4.2) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBT
index 65cdbe96e41ccc869ef2ecf1dc604e5533e3b00a..00add6f9d65219c4eb710e660c853b01a6e31a86 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is DOUBLE PRECISION
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues.  Eigenvalues less than or equal
+*>          to VL, or greater than VU, will not be returned.  VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is DOUBLE PRECISION
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues.  Eigenvalues less than or equal
 *>          to VL, or greater than VU, will not be returned.  VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup auxOTHERauxiliary
 *
      $                    M, W, WERR, WL, WU, IBLOCK, INDEXW,
      $                    WORK, IWORK, INFO )
 *
-*  -- LAPACK auxiliary routine (version 3.4.2) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          ORDER, RANGE
index e7eea10c6eecd7d71c5d90a4cf2660526dfd5983..d8e9c845918d043d891f4b1ecb78f7f22570b801 100644 (file)
 *> \param[in,out] VL
 *> \verbatim
 *>          VL is DOUBLE PRECISION
+*>          If RANGE='V', the lower bound for the eigenvalues.
+*>          Eigenvalues less than or equal to VL, or greater than VU,
+*>          will not be returned.  VL < VU.
+*>          If RANGE='I' or ='A', DLARRE computes bounds on the desired
+*>          part of the spectrum.
 *> \endverbatim
 *>
 *> \param[in,out] VU
 *> \verbatim
 *>          VU is DOUBLE PRECISION
-*>          If RANGE='V', the lower and upper bounds for the eigenvalues.
+*>          If RANGE='V', the upper bound for the eigenvalues.
 *>          Eigenvalues less than or equal to VL, or greater than VU,
 *>          will not be returned.  VL < VU.
 *>          If RANGE='I' or ='A', DLARRE computes bounds on the desired
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N.
 *> \endverbatim
 *>
 *> \verbatim
 *>          INFO is INTEGER
 *>          = 0:  successful exit
-*>          > 0:  A problem occured in DLARRE.
+*>          > 0:  A problem occurred in DLARRE.
 *>          < 0:  One of the called subroutines signaled an internal problem.
 *>                Needs inspection of the corresponding parameter IINFO
 *>                for further information.
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup auxOTHERauxiliary
 *
      $                    W, WERR, WGAP, IBLOCK, INDEXW, GERS, PIVMIN,
      $                    WORK, IWORK, INFO )
 *
-*  -- LAPACK auxiliary routine (version 3.4.2) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          RANGE
index f054caa8c9ae2b91e4960af08b6f77e33624cd6e..afec65c9912b741e69c79b72d6c321f7234335c0 100644 (file)
@@ -51,7 +51,7 @@
 *> \param[in] N
 *> \verbatim
 *>          N is INTEGER
-*>          The order of the matrix (subblock, if the matrix splitted).
+*>          The order of the matrix (subblock, if the matrix split).
 *> \endverbatim
 *>
 *> \param[in] D
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup auxOTHERauxiliary
 *
      $                   SPDIAM, CLGAPL, CLGAPR, PIVMIN, SIGMA,
      $                   DPLUS, LPLUS, WORK, INFO )
 *
-*  -- LAPACK auxiliary routine (version 3.6.0) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            CLSTRT, CLEND, INFO, N
index 828661f2c04c6a97df4c40cb68d3a2dae77415db..0628d49ed59f081639b4635914f45a18833c64ef 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is DOUBLE PRECISION
+*>          Lower bound of the interval that contains the desired
+*>          eigenvalues. VL < VU. Needed to compute gaps on the left or right
+*>          end of the extremal eigenvalues in the desired RANGE.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is DOUBLE PRECISION
-*>          Lower and upper bounds of the interval that contains the desired
+*>          Upper bound of the interval that contains the desired
 *>          eigenvalues. VL < VU. Needed to compute gaps on the left or right
 *>          end of the extremal eigenvalues in the desired RANGE.
 *> \endverbatim
@@ -81,7 +84,7 @@
 *>          L is DOUBLE PRECISION array, dimension (N)
 *>          On entry, the (N-1) subdiagonal elements of the unit
 *>          bidiagonal matrix L are in elements 1 to N-1 of L
-*>          (if the matrix is not splitted.) At the end of each block
+*>          (if the matrix is not split.) At the end of each block
 *>          is stored the corresponding shift as given by DLARRE.
 *>          On exit, L is overwritten.
 *> \endverbatim
 *>          INFO is INTEGER
 *>          = 0:  successful exit
 *>
-*>          > 0:  A problem occured in DLARRV.
+*>          > 0:  A problem occurred in DLARRV.
 *>          < 0:  One of the called subroutines signaled an internal problem.
 *>                Needs inspection of the corresponding parameter IINFO
 *>                for further information.
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup doubleOTHERauxiliary
 *
      $                   IBLOCK, INDEXW, GERS, Z, LDZ, ISUPPZ,
      $                   WORK, IWORK, INFO )
 *
-*  -- LAPACK auxiliary routine (version 3.6.0) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            DOL, DOU, INFO, LDZ, M, N
index 81f5aa813986274bf746616b6383e45adb632ef8..acd577833e63eda56750a4b9ab472a7e1a15e80c 100644 (file)
@@ -72,7 +72,7 @@
 *> \param[in] LDX
 *> \verbatim
 *>          LDX is INTEGER
-*>     The leading dimension of the vector X. LDX >= 0.
+*>     The leading dimension of the vector X. LDX >= M.
 *> \endverbatim
 *
 *  Authors:
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup doubleOTHERcomputational
 *
 *  =====================================================================
       SUBROUTINE DLARSCL2 ( M, N, D, X, LDX )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            M, N, LDX
index 9b9b33c0c1482888394180502b453a93f62e8c26..13c176ce3ee759b714f615dfe7248da73e29429c 100644 (file)
 *> \param[in] LDA
 *> \verbatim
 *>          LDA is INTEGER
-*>          The leading dimension of the array A.  LDA >= max(1,M).
+*>          The leading dimension of the array A.
+*>          If TYPE = 'G', 'L', 'U', 'H', LDA >= max(1,M);
+*>             TYPE = 'B', LDA >= KL+1;
+*>             TYPE = 'Q', LDA >= KU+1;
+*>             TYPE = 'Z', LDA >= 2*KL+KU+1.
 *> \endverbatim
 *>
 *> \param[out] INFO
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup auxOTHERauxiliary
 *
 *  =====================================================================
       SUBROUTINE DLASCL( TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO )
 *
-*  -- LAPACK auxiliary routine (version 3.4.2) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          TYPE
index 8cd9dd72c8c626113fd2ddec8d9741ba38cbde6e..f9b3b8a1542d54cf8cf4fee57ad27249c33bcede 100644 (file)
@@ -72,7 +72,7 @@
 *> \param[in] LDX
 *> \verbatim
 *>          LDX is INTEGER
-*>     The leading dimension of the vector X. LDX >= 0.
+*>     The leading dimension of the vector X. LDX >= M.
 *> \endverbatim
 *
 *  Authors:
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup doubleOTHERcomputational
 *
 *  =====================================================================
       SUBROUTINE DLASCL2 ( M, N, D, X, LDX )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            M, N, LDX
index 7b66d90b22f752c9307b95bd30a860a435730f74..cf7ae9089fa2853512e92f823d3156797b74a5b9 100644 (file)
@@ -60,7 +60,7 @@
 *>
 *>    The first stage consists of deflating the size of the problem
 *>    when there are multiple singular values or when there are zeros in
-*>    the Z vector.  For each such occurence the dimension of the
+*>    the Z vector.  For each such occurrence the dimension of the
 *>    secular equation problem is reduced by one.  This stage is
 *>    performed by the routine DLASD2.
 *>
 *>         The leading dimension of the array VT.  LDVT >= max( 1, M ).
 *> \endverbatim
 *>
-*> \param[out] IDXQ
+*> \param[in,out] IDXQ
 *> \verbatim
 *>          IDXQ is INTEGER array, dimension(N)
 *>         This contains the permutation which will reintegrate the
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup auxOTHERauxiliary
 *
       SUBROUTINE DLASD1( NL, NR, SQRE, D, ALPHA, BETA, U, LDU, VT, LDVT,
      $                   IDXQ, IWORK, WORK, INFO )
 *
-*  -- LAPACK auxiliary routine (version 3.6.0) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            INFO, LDU, LDVT, NL, NR, SQRE
index a5238b919c88b188c45130f0e9f1c3c51d0aee39..d562cc53e96961674554e4958492984f766aa692 100644 (file)
@@ -74,7 +74,7 @@
 *>
 *>       The first stage consists of deflating the size of the problem
 *>       when there are multiple singular values or if there is a zero
-*>       in the Z vector. For each such occurence the dimension of the
+*>       in the Z vector. For each such occurrence the dimension of the
 *>       secular equation problem is reduced by one. This stage is
 *>       performed by the routine DLASD7.
 *>
 *> \param[out] DIFR
 *> \verbatim
 *>          DIFR is DOUBLE PRECISION array,
-*>                  dimension ( LDGNUM, 2 ) if ICOMPQ = 1 and
-*>                  dimension ( N ) if ICOMPQ = 0.
-*>         On exit, DIFR(I, 1) is the distance between I-th updated
-*>         (undeflated) singular value and the I+1-th (undeflated) old
-*>         singular value.
+*>                   dimension ( LDDIFR, 2 ) if ICOMPQ = 1 and
+*>                   dimension ( K ) if ICOMPQ = 0.
+*>          On exit, DIFR(I,1) = D(I) - DSIGMA(I+1), DIFR(K,1) is not
+*>          defined and will not be referenced.
 *>
-*>         If ICOMPQ = 1, DIFR(1:K,2) is an array containing the
-*>         normalizing factors for the right singular vector matrix.
+*>          If ICOMPQ = 1, DIFR(1:K,2) is an array containing the
+*>          normalizing factors for the right singular vector matrix.
 *>
 *>         See DLASD8 for details on DIFL and DIFR.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup auxOTHERauxiliary
 *
      $                   LDGNUM, POLES, DIFL, DIFR, Z, K, C, S, WORK,
      $                   IWORK, INFO )
 *
-*  -- LAPACK auxiliary routine (version 3.6.0) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            GIVPTR, ICOMPQ, INFO, K, LDGCOL, LDGNUM, NL,
index 6beef32ac6601b3282a2a745ff8f44206b7003b6..94cc1141d586843f9f03d528a8615c353c886fe6 100644 (file)
@@ -59,7 +59,7 @@
 *> \verbatim
 *>          UPLO is CHARACTER*1
 *>        On entry, UPLO specifies whether the input bidiagonal matrix
-*>        is upper or lower bidiagonal, and wether it is square are
+*>        is upper or lower bidiagonal, and whether it is square are
 *>        not.
 *>           UPLO = 'U' or 'u'   B is upper bidiagonal.
 *>           UPLO = 'L' or 'l'   B is lower bidiagonal.
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup auxOTHERauxiliary
 *
       SUBROUTINE DLASDQ( UPLO, SQRE, N, NCVT, NRU, NCC, D, E, VT, LDVT,
      $                   U, LDU, C, LDC, WORK, INFO )
 *
-*  -- LAPACK auxiliary routine (version 3.4.2) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          UPLO
index 4506e19f215bf7e1219767ae9631830e353352ab..3ae35ad11b52c690e0c88add8d40b82fb2658c4e 100644 (file)
@@ -60,7 +60,7 @@
 *>
 *> \param[in,out] Z
 *> \verbatim
-*>          Z is DOUBLE PRECISION array, dimension ( 4*N )
+*>          Z is DOUBLE PRECISION array, dimension ( 4*N0 )
 *>         Z holds the qd array.
 *> \endverbatim
 *>
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup auxOTHERcomputational
 *
      $                   ITER, NDIV, IEEE, TTYPE, DMIN1, DMIN2, DN, DN1,
      $                   DN2, G, TAU )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       LOGICAL            IEEE
index 97d9bdeba31a930364553d60ffba192f91f01df7..45361b2cbe85c2e9114b651b1f861094f3f4adb1 100644 (file)
@@ -56,7 +56,7 @@
 *>
 *> \param[in] Z
 *> \verbatim
-*>          Z is DOUBLE PRECISION array, dimension ( 4*N )
+*>          Z is DOUBLE PRECISION array, dimension ( 4*N0 )
 *>        Z holds the qd array.
 *> \endverbatim
 *>
 *>
 *> \param[in,out] G
 *> \verbatim
-*>          G is REAL
+*>          G is DOUBLE PRECISION
 *>        G is passed as an argument in order to save its value between
 *>        calls to DLASQ4.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup auxOTHERcomputational
 *
       SUBROUTINE DLASQ4( I0, N0, Z, PP, N0IN, DMIN, DMIN1, DMIN2, DN,
      $                   DN1, DN2, TAU, TTYPE, G )
 *
-*  -- LAPACK computational routine (version 3.4.2) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            I0, N0, N0IN, PP, TTYPE
index f5d0e6cd1a8ceb180ec14fbf9293ab55ac4b6f94..fca457efce9642e991513cf4b208cb094c53b2c9 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup auxOTHERcomputational
 *
 *  =====================================================================
       SUBROUTINE DLASRT( ID, N, D, INFO )
 *
-*  -- LAPACK computational routine (version 3.4.2) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          ID
 *     ..
 *     .. Executable Statements ..
 *
-*     Test the input paramters.
+*     Test the input parameters.
 *
       INFO = 0
       DIR = -1
index a4b103053d2fcaebc85aaa4a0cf5d56625dd341c..0af00d39d08c80a8a54cda369e3fcd871421d086 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup doubleSYauxiliary
 *
       SUBROUTINE DLASY2( LTRANL, LTRANR, ISGN, N1, N2, TL, LDTL, TR,
      $                   LDTR, B, LDB, SCALE, X, LDX, XNORM, INFO )
 *
-*  -- LAPACK auxiliary routine (version 3.4.2) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       LOGICAL            LTRANL, LTRANR
    80       CONTINUE
    90    CONTINUE
   100 CONTINUE
-      IF( ABS( T16( 4, 4 ) ).LT.SMIN )
-     $   T16( 4, 4 ) = SMIN
+      IF( ABS( T16( 4, 4 ) ).LT.SMIN ) THEN
+         INFO = 1
+         T16( 4, 4 ) = SMIN
+      END IF
       SCALE = ONE
       IF( ( EIGHT*SMLNUM )*ABS( BTMP( 1 ) ).GT.ABS( T16( 1, 1 ) ) .OR.
      $    ( EIGHT*SMLNUM )*ABS( BTMP( 2 ) ).GT.ABS( T16( 2, 2 ) ) .OR.
index be70313bb37d4738627630d4004e2f389c416ffc..5eba2843bb1add52dff38c3f538761d52489a862 100644 (file)
@@ -58,7 +58,7 @@
 *>              Zx = +-e - f with the sign giving the greater value
 *>              of 2-norm(x). About 5 times as expensive as Default.
 *>          IJOB .ne. 2: Local look ahead strategy where all entries of
-*>              the r.h.s. b is choosen as either +1 or -1 (Default).
+*>              the r.h.s. b is chosen as either +1 or -1 (Default).
 *> \endverbatim
 *>
 *> \param[in] N
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup doubleOTHERauxiliary
 *
       SUBROUTINE DLATDF( IJOB, N, Z, LDZ, RHS, RDSUM, RDSCAL, IPIV,
      $                   JPIV )
 *
-*  -- LAPACK auxiliary routine (version 3.4.2) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            IJOB, LDZ, N
index b5675f71d4d2bbb7d84cd7ec3179f19ddb61930c..8d616bc1bdf24dc765720b8f1c1c4af6992038ac 100644 (file)
       SUBROUTINE DORBDB1( M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI,
      $                    TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.5.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     July 2012
      $                  X11(I+1,I+1), LDX11, WORK(ILARF) )
             CALL DLARF( 'R', M-P-I, Q-I, X21(I,I+1), LDX21, TAUQ1(I),
      $                  X21(I+1,I+1), LDX21, WORK(ILARF) )
-            C = SQRT( DNRM2( P-I, X11(I+1,I+1), 1, X11(I+1,I+1),
-     $          1 )**2 + DNRM2( M-P-I, X21(I+1,I+1), 1, X21(I+1,I+1),
-     $          1 )**2 )
+            C = SQRT( DNRM2( P-I, X11(I+1,I+1), 1 )**2
+     $          + DNRM2( M-P-I, X21(I+1,I+1), 1 )**2 )
             PHI(I) = ATAN2( S, C )
             CALL DORBDB5( P-I, M-P-I, Q-I-1, X11(I+1,I+1), 1,
      $                    X21(I+1,I+1), 1, X11(I+1,I+2), LDX11,
index 3cf82cf4003c4f55eecb29e7c43a7fcbff0e8ae7..554cc2ff64467c15d323a6dea0985debddd8c219 100644 (file)
       SUBROUTINE DORBDB2( M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI,
      $                    TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.5.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     July 2012
      $               X11(I+1,I), LDX11, WORK(ILARF) )
          CALL DLARF( 'R', M-P-I+1, Q-I+1, X11(I,I), LDX11, TAUQ1(I),
      $               X21(I,I), LDX21, WORK(ILARF) )
-         S = SQRT( DNRM2( P-I, X11(I+1,I), 1, X11(I+1,I),
-     $       1 )**2 + DNRM2( M-P-I+1, X21(I,I), 1, X21(I,I), 1 )**2 )
+         S = SQRT( DNRM2( P-I, X11(I+1,I), 1 )**2
+     $           + DNRM2( M-P-I+1, X21(I,I), 1 )**2 )
          THETA(I) = ATAN2( S, C )
 *
          CALL DORBDB5( P-I, M-P-I+1, Q-I, X11(I+1,I), 1, X21(I,I), 1,
index 03be504fa2f1be0beab7c88bd079bbdac2b35944..003c4402dc645458e26cbf49f1f533fae280285c 100644 (file)
       SUBROUTINE DORBDB3( M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI,
      $                    TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.5.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     July 2012
      $               X11(I,I), LDX11, WORK(ILARF) )
          CALL DLARF( 'R', M-P-I, Q-I+1, X21(I,I), LDX21, TAUQ1(I),
      $               X21(I+1,I), LDX21, WORK(ILARF) )
-         C = SQRT( DNRM2( P-I+1, X11(I,I), 1, X11(I,I),
-     $       1 )**2 + DNRM2( M-P-I, X21(I+1,I), 1, X21(I+1,I), 1 )**2 )
+         C = SQRT( DNRM2( P-I+1, X11(I,I), 1 )**2
+     $           + DNRM2( M-P-I, X21(I+1,I), 1 )**2 )
          THETA(I) = ATAN2( S, C )
 *
          CALL DORBDB5( P-I+1, M-P-I, Q-I, X11(I,I), 1, X21(I+1,I), 1,
index 8c72360540d3994e7772f5c5c60f85a743f2dba4..a8fe7435d884bc8af0642cc5d03dceafb022e310 100644 (file)
      $                    TAUP1, TAUP2, TAUQ1, PHANTOM, WORK, LWORK,
      $                    INFO )
 *
-*  -- LAPACK computational routine (version 3.5.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     July 2012
          CALL DLARF( 'R', M-P-I, Q-I+1, X21(I,I), LDX21, TAUQ1(I),
      $               X21(I+1,I), LDX21, WORK(ILARF) )
          IF( I .LT. M-Q ) THEN
-            S = SQRT( DNRM2( P-I, X11(I+1,I), 1, X11(I+1,I),
-     $          1 )**2 + DNRM2( M-P-I, X21(I+1,I), 1, X21(I+1,I),
-     $          1 )**2 )
+            S = SQRT( DNRM2( P-I, X11(I+1,I), 1 )**2
+     $              + DNRM2( M-P-I, X21(I+1,I), 1 )**2 )
             PHI(I) = ATAN2( S, C )
          END IF
 *
index 19dedbe8d958db1c28f1e5b4880b710447c3cbd5..dd0cd351c386ec694682b9c6e27af73367bfc463 100644 (file)
      $                   LWORKMIN, LWORKOPT, R
       LOGICAL            LQUERY, WANTU1, WANTU2, WANTV1T
 *     ..
+*     .. Local Arrays ..
+      DOUBLE PRECISION   DUM1(1), DUM2(1,1)
+*     ..
 *     .. External Subroutines ..
       EXTERNAL           DBBCSD, DCOPY, DLACPY, DLAPMR, DLAPMT, DORBDB1,
      $                   DORBDB2, DORBDB3, DORBDB4, DORGLQ, DORGQR,
          INFO = -8
       ELSE IF( LDX21 .LT. MAX( 1, M-P ) ) THEN
          INFO = -10
-      ELSE IF( WANTU1 .AND. LDU1 .LT. P ) THEN
+      ELSE IF( WANTU1 .AND. LDU1 .LT. MAX( 1, P ) ) THEN
          INFO = -13
-      ELSE IF( WANTU2 .AND. LDU2 .LT. M - P ) THEN
+      ELSE IF( WANTU2 .AND. LDU2 .LT. MAX( 1, M - P ) ) THEN
          INFO = -15
-      ELSE IF( WANTV1T .AND. LDV1T .LT. Q ) THEN
+      ELSE IF( WANTV1T .AND. LDV1T .LT. MAX( 1, Q ) ) THEN
          INFO = -17
       END IF
 *
          IORBDB = ITAUQ1 + MAX( 1, Q )
          IORGQR = ITAUQ1 + MAX( 1, Q )
          IORGLQ = ITAUQ1 + MAX( 1, Q )
+         LORGQRMIN = 1
+         LORGQROPT = 1
+         LORGLQMIN = 1
+         LORGLQOPT = 1
          IF( R .EQ. Q ) THEN
-            CALL DORBDB1( M, P, Q, X11, LDX11, X21, LDX21, THETA, 0, 0,
-     $                    0, 0, WORK, -1, CHILDINFO )
+            CALL DORBDB1( M, P, Q, X11, LDX11, X21, LDX21, THETA,
+     $                    DUM1, DUM1, DUM1, DUM1, WORK,
+     $                    -1, CHILDINFO )
             LORBDB = INT( WORK(1) )
-            IF( P .GE. M-P ) THEN
-               CALL DORGQR( P, P, Q, U1, LDU1, 0, WORK(1), -1,
-     $                      CHILDINFO )
-               LORGQRMIN = MAX( 1, P )
-               LORGQROPT = INT( WORK(1) )
-            ELSE
-               CALL DORGQR( M-P, M-P, Q, U2, LDU2, 0, WORK(1), -1,
+            IF( WANTU1 .AND. P .GT. 0 ) THEN
+               CALL DORGQR( P, P, Q, U1, LDU1, DUM1, WORK(1), -1,
      $                      CHILDINFO )
-               LORGQRMIN = MAX( 1, M-P )
-               LORGQROPT = INT( WORK(1) )
+               LORGQRMIN = MAX( LORGQRMIN, P )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            ENDIF
+            IF( WANTU2 .AND. M-P .GT. 0 ) THEN
+               CALL DORGQR( M-P, M-P, Q, U2, LDU2, DUM1, WORK(1),
+     $                      -1, CHILDINFO )
+               LORGQRMIN = MAX( LORGQRMIN, M-P )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            END IF
+            IF( WANTV1T .AND. Q .GT. 0 ) THEN
+               CALL DORGLQ( Q-1, Q-1, Q-1, V1T, LDV1T,
+     $                      DUM1, WORK(1), -1, CHILDINFO )
+               LORGLQMIN = MAX( LORGLQMIN, Q-1 )
+               LORGLQOPT = MAX( LORGLQOPT, INT( WORK(1) ) )
             END IF
-            CALL DORGLQ( MAX(0,Q-1), MAX(0,Q-1), MAX(0,Q-1), V1T, LDV1T,
-     $                   0, WORK(1), -1, CHILDINFO )
-            LORGLQMIN = MAX( 1, Q-1 )
-            LORGLQOPT = INT( WORK(1) )
             CALL DBBCSD( JOBU1, JOBU2, JOBV1T, 'N', 'N', M, P, Q, THETA,
-     $                   0, U1, LDU1, U2, LDU2, V1T, LDV1T, 0, 1, 0, 0,
-     $                   0, 0, 0, 0, 0, 0, WORK(1), -1, CHILDINFO )
+     $                   DUM1, U1, LDU1, U2, LDU2, V1T, LDV1T,
+     $                   DUM2, 1, DUM1, DUM1, DUM1,
+     $                   DUM1, DUM1, DUM1, DUM1,
+     $                   DUM1, WORK(1), -1, CHILDINFO )
             LBBCSD = INT( WORK(1) )
          ELSE IF( R .EQ. P ) THEN
-            CALL DORBDB2( M, P, Q, X11, LDX11, X21, LDX21, THETA, 0, 0,
-     $                    0, 0, WORK(1), -1, CHILDINFO )
+            CALL DORBDB2( M, P, Q, X11, LDX11, X21, LDX21, THETA,
+     $                    DUM1, DUM1, DUM1, DUM1,
+     $                    WORK(1), -1, CHILDINFO )
             LORBDB = INT( WORK(1) )
-            IF( P-1 .GE. M-P ) THEN
-               CALL DORGQR( P-1, P-1, P-1, U1(2,2), LDU1, 0, WORK(1),
+            IF( WANTU1 .AND. P .GT. 0 ) THEN
+               CALL DORGQR( P-1, P-1, P-1, U1(2,2), LDU1, DUM1,
+     $                      WORK(1), -1, CHILDINFO )
+               LORGQRMIN = MAX( LORGQRMIN, P-1 )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            END IF
+            IF( WANTU2 .AND. M-P .GT. 0 ) THEN
+               CALL DORGQR( M-P, M-P, Q, U2, LDU2, DUM1, WORK(1),
      $                      -1, CHILDINFO )
-               LORGQRMIN = MAX( 1, P-1 )
-               LORGQROPT = INT( WORK(1) )
-            ELSE
-               CALL DORGQR( M-P, M-P, Q, U2, LDU2, 0, WORK(1), -1,
+               LORGQRMIN = MAX( LORGQRMIN, M-P )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            END IF
+            IF( WANTV1T .AND. Q .GT. 0 ) THEN
+               CALL DORGLQ( Q, Q, R, V1T, LDV1T, DUM1, WORK(1), -1,
      $                      CHILDINFO )
-               LORGQRMIN = MAX( 1, M-P )
-               LORGQROPT = INT( WORK(1) )
+               LORGLQMIN = MAX( LORGLQMIN, Q )
+               LORGLQOPT = MAX( LORGLQOPT, INT( WORK(1) ) )
             END IF
-            CALL DORGLQ( Q, Q, R, V1T, LDV1T, 0, WORK(1), -1,
-     $                   CHILDINFO )
-            LORGLQMIN = MAX( 1, Q )
-            LORGLQOPT = INT( WORK(1) )
             CALL DBBCSD( JOBV1T, 'N', JOBU1, JOBU2, 'T', M, Q, P, THETA,
-     $                   0, V1T, LDV1T, 0, 1, U1, LDU1, U2, LDU2, 0, 0,
-     $                   0, 0, 0, 0, 0, 0, WORK(1), -1, CHILDINFO )
+     $                   DUM1, V1T, LDV1T, DUM2, 1, U1, LDU1,
+     $                   U2, LDU2, DUM1, DUM1, DUM1,
+     $                   DUM1, DUM1, DUM1, DUM1,
+     $                   DUM1, WORK(1), -1, CHILDINFO )
             LBBCSD = INT( WORK(1) )
          ELSE IF( R .EQ. M-P ) THEN
-            CALL DORBDB3( M, P, Q, X11, LDX11, X21, LDX21, THETA, 0, 0,
-     $                    0, 0, WORK(1), -1, CHILDINFO )
+            CALL DORBDB3( M, P, Q, X11, LDX11, X21, LDX21, THETA,
+     $                    DUM1, DUM1, DUM1, DUM1,
+     $                    WORK(1), -1, CHILDINFO )
             LORBDB = INT( WORK(1) )
-            IF( P .GE. M-P-1 ) THEN
-               CALL DORGQR( P, P, Q, U1, LDU1, 0, WORK(1), -1,
+            IF( WANTU1 .AND. P .GT. 0 ) THEN
+               CALL DORGQR( P, P, Q, U1, LDU1, DUM1, WORK(1), -1,
      $                      CHILDINFO )
-               LORGQRMIN = MAX( 1, P )
-               LORGQROPT = INT( WORK(1) )
-            ELSE
-               CALL DORGQR( M-P-1, M-P-1, M-P-1, U2(2,2), LDU2, 0,
-     $                      WORK(1), -1, CHILDINFO )
-               LORGQRMIN = MAX( 1, M-P-1 )
-               LORGQROPT = INT( WORK(1) )
+               LORGQRMIN = MAX( LORGQRMIN, P )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            END IF
+            IF( WANTU2 .AND. M-P .GT. 0 ) THEN
+               CALL DORGQR( M-P-1, M-P-1, M-P-1, U2(2,2), LDU2,
+     $                      DUM1, WORK(1), -1, CHILDINFO )
+               LORGQRMIN = MAX( LORGQRMIN, M-P-1 )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            END IF
+            IF( WANTV1T .AND. Q .GT. 0 ) THEN
+               CALL DORGLQ( Q, Q, R, V1T, LDV1T, DUM1, WORK(1), -1,
+     $                      CHILDINFO )
+               LORGLQMIN = MAX( LORGLQMIN, Q )
+               LORGLQOPT = MAX( LORGLQOPT, INT( WORK(1) ) )
             END IF
-            CALL DORGLQ( Q, Q, R, V1T, LDV1T, 0, WORK(1), -1,
-     $                   CHILDINFO )
-            LORGLQMIN = MAX( 1, Q )
-            LORGLQOPT = INT( WORK(1) )
             CALL DBBCSD( 'N', JOBV1T, JOBU2, JOBU1, 'T', M, M-Q, M-P,
-     $                   THETA, 0, 0, 1, V1T, LDV1T, U2, LDU2, U1, LDU1,
-     $                   0, 0, 0, 0, 0, 0, 0, 0, WORK(1), -1,
-     $                   CHILDINFO )
+     $                   THETA, DUM1, DUM2, 1, V1T, LDV1T, U2,
+     $                   LDU2, U1, LDU1, DUM1, DUM1, DUM1,
+     $                   DUM1, DUM1, DUM1, DUM1,
+     $                   DUM1, WORK(1), -1, CHILDINFO )
             LBBCSD = INT( WORK(1) )
          ELSE
-            CALL DORBDB4( M, P, Q, X11, LDX11, X21, LDX21, THETA, 0, 0,
-     $                    0, 0, 0, WORK(1), -1, CHILDINFO )
+            CALL DORBDB4( M, P, Q, X11, LDX11, X21, LDX21, THETA,
+     $                    DUM1, DUM1, DUM1, DUM1,
+     $                    DUM1, WORK(1), -1, CHILDINFO )
             LORBDB = M + INT( WORK(1) )
-            IF( P .GE. M-P ) THEN
-               CALL DORGQR( P, P, M-Q, U1, LDU1, 0, WORK(1), -1,
+            IF( WANTU1 .AND. P .GT. 0 ) THEN
+               CALL DORGQR( P, P, M-Q, U1, LDU1, DUM1, WORK(1), -1,
      $                      CHILDINFO )
-               LORGQRMIN = MAX( 1, P )
-               LORGQROPT = INT( WORK(1) )
-            ELSE
-               CALL DORGQR( M-P, M-P, M-Q, U2, LDU2, 0, WORK(1), -1,
+               LORGQRMIN = MAX( LORGQRMIN, P )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            END IF
+            IF( WANTU2 .AND. M-P .GT. 0 ) THEN
+               CALL DORGQR( M-P, M-P, M-Q, U2, LDU2, DUM1, WORK(1),
+     $                      -1, CHILDINFO )
+               LORGQRMIN = MAX( LORGQRMIN, M-P )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            END IF
+            IF( WANTV1T .AND. Q .GT. 0 ) THEN
+               CALL DORGLQ( Q, Q, Q, V1T, LDV1T, DUM1, WORK(1), -1,
      $                      CHILDINFO )
-               LORGQRMIN = MAX( 1, M-P )
-               LORGQROPT = INT( WORK(1) )
+               LORGLQMIN = MAX( LORGLQMIN, Q )
+               LORGLQOPT = MAX( LORGLQOPT, INT( WORK(1) ) )
             END IF
-            CALL DORGLQ( Q, Q, Q, V1T, LDV1T, 0, WORK(1), -1,
-     $                   CHILDINFO )
-            LORGLQMIN = MAX( 1, Q )
-            LORGLQOPT = INT( WORK(1) )
             CALL DBBCSD( JOBU2, JOBU1, 'N', JOBV1T, 'N', M, M-P, M-Q,
-     $                   THETA, 0, U2, LDU2, U1, LDU1, 0, 1, V1T, LDV1T,
-     $                   0, 0, 0, 0, 0, 0, 0, 0, WORK(1), -1,
-     $                   CHILDINFO )
+     $                   THETA, DUM1, U2, LDU2, U1, LDU1, DUM2,
+     $                   1, V1T, LDV1T, DUM1, DUM1, DUM1,
+     $                   DUM1, DUM1, DUM1, DUM1,
+     $                   DUM1, WORK(1), -1, CHILDINFO )
             LBBCSD = INT( WORK(1) )
          END IF
          LWORKMIN = MAX( IORBDB+LORBDB-1,
 *        Simultaneously diagonalize X11 and X21.
 *   
          CALL DBBCSD( JOBU1, JOBU2, JOBV1T, 'N', 'N', M, P, Q, THETA,
-     $                WORK(IPHI), U1, LDU1, U2, LDU2, V1T, LDV1T, 0, 1,
-     $                WORK(IB11D), WORK(IB11E), WORK(IB12D),
-     $                WORK(IB12E), WORK(IB21D), WORK(IB21E),
-     $                WORK(IB22D), WORK(IB22E), WORK(IBBCSD), LBBCSD,
-     $                CHILDINFO )
+     $                WORK(IPHI), U1, LDU1, U2, LDU2, V1T, LDV1T,
+     $                DUM2, 1, WORK(IB11D), WORK(IB11E),
+     $                WORK(IB12D), WORK(IB12E), WORK(IB21D),
+     $                WORK(IB21E), WORK(IB22D), WORK(IB22E),
+     $                WORK(IBBCSD), LBBCSD, CHILDINFO )
 *   
 *        Permute rows and columns to place zero submatrices in
 *        preferred positions
 *        Simultaneously diagonalize X11 and X21.
 *   
          CALL DBBCSD( JOBV1T, 'N', JOBU1, JOBU2, 'T', M, Q, P, THETA,
-     $                WORK(IPHI), V1T, LDV1T, 0, 1, U1, LDU1, U2, LDU2,
-     $                WORK(IB11D), WORK(IB11E), WORK(IB12D),
+     $                WORK(IPHI), V1T, LDV1T, DUM2, 1, U1, LDU1, U2,
+     $                LDU2, WORK(IB11D), WORK(IB11E), WORK(IB12D),
      $                WORK(IB12E), WORK(IB21D), WORK(IB21E),
      $                WORK(IB22D), WORK(IB22E), WORK(IBBCSD), LBBCSD,
      $                CHILDINFO )
 *        Simultaneously diagonalize X11 and X21.
 *   
          CALL DBBCSD( 'N', JOBV1T, JOBU2, JOBU1, 'T', M, M-Q, M-P,
-     $                THETA, WORK(IPHI), 0, 1, V1T, LDV1T, U2, LDU2, U1,
-     $                LDU1, WORK(IB11D), WORK(IB11E), WORK(IB12D),
-     $                WORK(IB12E), WORK(IB21D), WORK(IB21E),
-     $                WORK(IB22D), WORK(IB22E), WORK(IBBCSD), LBBCSD,
-     $                CHILDINFO )
+     $                THETA, WORK(IPHI), DUM2, 1, V1T, LDV1T, U2,
+     $                LDU2, U1, LDU1, WORK(IB11D), WORK(IB11E),
+     $                WORK(IB12D), WORK(IB12E), WORK(IB21D),
+     $                WORK(IB21E), WORK(IB22D), WORK(IB22E),
+     $                WORK(IBBCSD), LBBCSD, CHILDINFO )
 *   
 *        Permute rows and columns to place identity submatrices in
 *        preferred positions
 *        Simultaneously diagonalize X11 and X21.
 *   
          CALL DBBCSD( JOBU2, JOBU1, 'N', JOBV1T, 'N', M, M-P, M-Q,
-     $                THETA, WORK(IPHI), U2, LDU2, U1, LDU1, 0, 1, V1T,
-     $                LDV1T, WORK(IB11D), WORK(IB11E), WORK(IB12D),
-     $                WORK(IB12E), WORK(IB21D), WORK(IB21E),
-     $                WORK(IB22D), WORK(IB22E), WORK(IBBCSD), LBBCSD,
-     $                CHILDINFO )
+     $                THETA, WORK(IPHI), U2, LDU2, U1, LDU1, DUM2,
+     $                1, V1T, LDV1T, WORK(IB11D), WORK(IB11E),
+     $                WORK(IB12D), WORK(IB12E), WORK(IB21D),
+     $                WORK(IB21E), WORK(IB22D), WORK(IB22E),
+     $                WORK(IBBCSD), LBBCSD, CHILDINFO )
 *   
 *        Permute rows and columns to place identity submatrices in
 *        preferred positions
index 39517fb9358f71e9fcbb93187190c06257ef9588..fc8836f79f8c8e54fd2bf23e9380c7fd5a8f198e 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is DOUBLE PRECISION
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is DOUBLE PRECISION
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup doubleOTHEReigen
 *
      $                   VU, IL, IU, ABSTOL, M, W, Z, LDZ, WORK, IWORK,
      $                   IFAIL, INFO )
 *
-*  -- LAPACK driver routine (version 3.4.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE, UPLO
index fe8d62873446745ece5287f0912343d5fb352ead..a259ad78eed78aa478a148f3662fde55599ac285 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup doubleOTHEReigen
 *
       SUBROUTINE DSBGVD( JOBZ, UPLO, N, KA, KB, AB, LDAB, BB, LDBB, W,
      $                   Z, LDZ, WORK, LWORK, IWORK, LIWORK, INFO )
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, UPLO
       INDWK2 = INDWRK + N*N
       LLWRK2 = LWORK - INDWK2 + 1
       CALL DSBGST( JOBZ, UPLO, N, KA, KB, AB, LDAB, BB, LDBB, Z, LDZ,
-     $             WORK( INDWRK ), IINFO )
+     $             WORK, IINFO )
 *
 *     Reduce to tridiagonal form.
 *
index fc06677da5d60ad159004859c9c6bba549f74b4c..2db4ac346c94936910003aaa16e79e9fd45d8079 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is DOUBLE PRECISION
+*>
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is DOUBLE PRECISION
 *>
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
 *>
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup doubleOTHEReigen
 *
      $                   LDBB, Q, LDQ, VL, VU, IL, IU, ABSTOL, M, W, Z,
      $                   LDZ, WORK, IWORK, IFAIL, INFO )
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE, UPLO
index 64e2c1686b9fb37ff0dc21d5f8a2ad64225c4c23..99eb122c8a58fbbcaf45ccd21f24e71b92fd6fb7 100644 (file)
 *>               -3 : failure of SGETRF
 *>               -31: stop the iterative refinement after the 30th
 *>                    iterations
-*>          > 0: iterative refinement has been sucessfully used.
+*>          > 0: iterative refinement has been successfully used.
 *>               Returns the number of iterations
 *> \endverbatim
 *>
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup doubleGEsolve
 *
       SUBROUTINE DSGESV( N, NRHS, A, LDA, IPIV, B, LDB, X, LDX, WORK,
      $                   SWORK, ITER, INFO )
 *
-*  -- LAPACK driver routine (version 3.4.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            INFO, ITER, LDA, LDB, LDX, N, NRHS
index 35a96b2b8c88d3450796e37b05e43d56f0f93dfd..4f9e8d46f1f8307b5d8b3bd9925b2ea373fb15e3 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is DOUBLE PRECISION
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is DOUBLE PRECISION
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup doubleOTHEReigen
 *
      $                   ABSTOL, M, W, Z, LDZ, WORK, IWORK, IFAIL,
      $                   INFO )
 *
-*  -- LAPACK driver routine (version 3.4.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE, UPLO
index 9eb91f7a1ad50554dd3234da8d0011fdd8f76513..e87ad5fceef62c0c38032f1b496b748a25cfd02a 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is DOUBLE PRECISION
+*>
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is DOUBLE PRECISION
 *>
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
 *>
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup doubleOTHEReigen
 *
      $                   IL, IU, ABSTOL, M, W, Z, LDZ, WORK, IWORK,
      $                   IFAIL, INFO )
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE, UPLO
index bb72199ba1275965cc61a20432200ea01f3a9870..f7573dd3cba10898da3444c77e7fbc05f6c28963 100644 (file)
 *>               -3 : failure of SPOTRF
 *>               -31: stop the iterative refinement after the 30th
 *>                    iterations
-*>          > 0: iterative refinement has been sucessfully used.
+*>          > 0: iterative refinement has been successfully used.
 *>               Returns the number of iterations
 *> \endverbatim
 *>
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup doublePOsolve
 *
       SUBROUTINE DSPOSV( UPLO, N, NRHS, A, LDA, B, LDB, X, LDX, WORK,
      $                   SWORK, ITER, INFO )
 *
-*  -- LAPACK driver routine (version 3.4.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          UPLO
index 01bea27c391e25bcd0b0961aa01d097093cb0d1f..25d271206aaacff163545c4c67193c10eb229f67 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is DOUBLE PRECISION
+*>
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues.  Eigenvalues less than or equal
+*>          to VL, or greater than VU, will not be returned.  VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is DOUBLE PRECISION
 *>
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues.  Eigenvalues less than or equal
 *>          to VL, or greater than VU, will not be returned.  VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
 *>
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup auxOTHERcomputational
 *
      $                   M, NSPLIT, W, IBLOCK, ISPLIT, WORK, IWORK,
      $                   INFO )
 *
-*  -- LAPACK computational routine (version 3.4.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          ORDER, RANGE
index 298e1c766deb5118a1e4770fe35b5945ef3d8cc6..a56f90631e52f894d504e265b43571c7c410b663 100644 (file)
@@ -48,7 +48,7 @@
 *> either an interval (VL,VU] or a range of indices IL:IU for the desired
 *> eigenvalues.
 *>
-*> DSTEGR is a compatability wrapper around the improved DSTEMR routine.
+*> DSTEGR is a compatibility wrapper around the improved DSTEMR routine.
 *> See DSTEMR for further details.
 *>
 *> One important change is that the ABSTOL parameter no longer provides any
 *> \param[in] VL
 *> \verbatim
 *>          VL is DOUBLE PRECISION
+*>
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is DOUBLE PRECISION
 *>
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
 *>
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup doubleOTHERcomputational
 *
      $           ABSTOL, M, W, Z, LDZ, ISUPPZ, WORK, LWORK, IWORK,
      $           LIWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.4.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE
index 8967c18fc6a2e22fcfbf6429fa37e9a3bdbedaac..60884672f121cd6cd750ce6ba5b0f0bbfe3c8dfa 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is DOUBLE PRECISION
+*>
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is DOUBLE PRECISION
 *>
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
 *>
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2013
+*> \date June 2016
 *
 *> \ingroup doubleOTHERcomputational
 *
      $                   M, W, Z, LDZ, NZC, ISUPPZ, TRYRAC, WORK, LWORK,
      $                   IWORK, LIWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.5.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2013
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE
index 941ec97f357ee4a07d4d20ca21a8e2a268df36e5..dd40cf99c224452eb186a57dca84e9efada731b1 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is DOUBLE PRECISION
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is DOUBLE PRECISION
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup doubleOTHEReigen
 *
      $                   M, W, Z, LDZ, ISUPPZ, WORK, LWORK, IWORK,
      $                   LIWORK, INFO )
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE
index cda9de16c9b23c46c6aaad5c545cc7f7961b70e9..0cdfe999236c3cc8cafcf1217672080dd8e87109 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is DOUBLE PRECISION
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is DOUBLE PRECISION
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup doubleOTHEReigen
 *
       SUBROUTINE DSTEVX( JOBZ, RANGE, N, D, E, VL, VU, IL, IU, ABSTOL,
      $                   M, W, Z, LDZ, WORK, IWORK, IFAIL, INFO )
 *
-*  -- LAPACK driver routine (version 3.4.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE
index 08f363613d5b91a8f4f2b8b8c36fde148b8461e9..c78fb156d1af39530c538e59e3058369c9d60e9d 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is DOUBLE PRECISION
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is DOUBLE PRECISION
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup doubleSYeigen
 *
      $                   ABSTOL, M, W, Z, LDZ, ISUPPZ, WORK, LWORK,
      $                   IWORK, LIWORK, INFO )
 *
-*  -- LAPACK driver routine (version 3.4.2) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE, UPLO
index cb990e50d15ec23d9391a2def457ce4a42b540e5..52c847779ef3bc2bdfef505a4b46d4170af83d25 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is DOUBLE PRECISION
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is DOUBLE PRECISION
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup doubleSYeigen
 *
      $                   ABSTOL, M, W, Z, LDZ, WORK, LWORK, IWORK,
      $                   IFAIL, INFO )
 *
-*  -- LAPACK driver routine (version 3.4.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE, UPLO
index 0ed770637aeb42db01e10f513e31c6ccef819732..13ab094db9cdc5fa03d37d99965f82fe0ee0f9d2 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is DOUBLE PRECISION
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is DOUBLE PRECISION
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup doubleSYeigen
 *
      $                   VL, VU, IL, IU, ABSTOL, M, W, Z, LDZ, WORK,
      $                   LWORK, IWORK, IFAIL, INFO )
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE, UPLO
index 81264872ad2319f84b4195f0127ec651f93053a8..a7f40537879c7c3bb6d2d35610fd0e0b39227323 100644 (file)
 *  =====================================================================
       SUBROUTINE DSYTRF_ROOK( UPLO, N, A, LDA, IPIV, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.4.1) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     April 2012
 *        Determine the block size
 *
          NB = ILAENV( 1, 'DSYTRF_ROOK', UPLO, N, -1, -1, -1 )
-         LWKOPT = N*NB
+         LWKOPT = MAX( 1, N*NB )
          WORK( 1 ) = LWKOPT
       END IF
 *
index 09a87fe3dcee184c713ff9eca1f1bbaccf2fe397..9d1205b77d31cf18e082fc78bc7a0cd5d215ba0c 100644 (file)
 *>
 *> \param[out] WORK
 *> \verbatim
-*>          WORK is REAL array, dimension (N)
+*>          WORK is DOUBLE PRECISION array, dimension (N)
 *> \endverbatim
 *>
 *> \param[out] INFO
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup doubleSYcomputational
 *
       SUBROUTINE DSYTRS2( UPLO, N, NRHS, A, LDA, IPIV, B, LDB, 
      $                    WORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          UPLO
index 82b17626fd23c46d16cf0ec7f864ac4e40c4591e..14719e4fd6e658c202c7130322af53e1567ffcb4 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup doubleOTHERcomputational
 *
      $                   ALPHAR, ALPHAI, BETA, Q, LDQ, Z, LDZ, M, PL,
      $                   PR, DIF, WORK, LWORK, IWORK, LIWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.4.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       LOGICAL            WANTQ, WANTZ
 *
       M = 0
       PAIR = .FALSE.
+      IF( .NOT.LQUERY .OR. IJOB.NE.0 ) THEN
       DO 10 K = 1, N
          IF( PAIR ) THEN
             PAIR = .FALSE.
             END IF
          END IF
    10 CONTINUE
+      END IF
 *
       IF( IJOB.EQ.1 .OR. IJOB.EQ.2 .OR. IJOB.EQ.4 ) THEN
          LWMIN = MAX( 1, 4*N+16, 2*M*( N-M ) )
diff --git a/lapack-netlib/SRC/dtrevc3.f b/lapack-netlib/SRC/dtrevc3.f
new file mode 100644 (file)
index 0000000..ba5abb5
--- /dev/null
@@ -0,0 +1,1303 @@
+*> \brief \b DTREVC3
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at 
+*            http://www.netlib.org/lapack/explore-html/ 
+*
+*> \htmlonly
+*> Download DTREVC3 + dependencies 
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtrevc3.f"> 
+*> [TGZ]</a> 
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtrevc3.f"> 
+*> [ZIP]</a> 
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtrevc3.f"> 
+*> [TXT]</a>
+*> \endhtmlonly 
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE DTREVC3( SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL,
+*                           VR, LDVR, MM, M, WORK, LWORK, INFO )
+*
+*       .. Scalar Arguments ..
+*       CHARACTER          HOWMNY, SIDE
+*       INTEGER            INFO, LDT, LDVL, LDVR, LWORK, M, MM, N
+*       ..
+*       .. Array Arguments ..
+*       LOGICAL            SELECT( * )
+*       DOUBLE PRECISION   T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ),
+*      $                   WORK( * )
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> DTREVC3 computes some or all of the right and/or left eigenvectors of
+*> a real upper quasi-triangular matrix T.
+*> Matrices of this type are produced by the Schur factorization of
+*> a real general matrix:  A = Q*T*Q**T, as computed by DHSEQR.
+*>
+*> The right eigenvector x and the left eigenvector y of T corresponding
+*> to an eigenvalue w are defined by:
+*>
+*>    T*x = w*x,     (y**T)*T = w*(y**T)
+*>
+*> where y**T denotes the transpose of the vector y.
+*> The eigenvalues are not input to this routine, but are read directly
+*> from the diagonal blocks of T.
+*>
+*> This routine returns the matrices X and/or Y of right and left
+*> eigenvectors of T, or the products Q*X and/or Q*Y, where Q is an
+*> input matrix. If Q is the orthogonal factor that reduces a matrix
+*> A to Schur form T, then Q*X and Q*Y are the matrices of right and
+*> left eigenvectors of A.
+*>
+*> This uses a Level 3 BLAS version of the back transformation.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] SIDE
+*> \verbatim
+*>          SIDE is CHARACTER*1
+*>          = 'R':  compute right eigenvectors only;
+*>          = 'L':  compute left eigenvectors only;
+*>          = 'B':  compute both right and left eigenvectors.
+*> \endverbatim
+*>
+*> \param[in] HOWMNY
+*> \verbatim
+*>          HOWMNY is CHARACTER*1
+*>          = 'A':  compute all right and/or left eigenvectors;
+*>          = 'B':  compute all right and/or left eigenvectors,
+*>                  backtransformed by the matrices in VR and/or VL;
+*>          = 'S':  compute selected right and/or left eigenvectors,
+*>                  as indicated by the logical array SELECT.
+*> \endverbatim
+*>
+*> \param[in,out] SELECT
+*> \verbatim
+*>          SELECT is LOGICAL array, dimension (N)
+*>          If HOWMNY = 'S', SELECT specifies the eigenvectors to be
+*>          computed.
+*>          If w(j) is a real eigenvalue, the corresponding real
+*>          eigenvector is computed if SELECT(j) is .TRUE..
+*>          If w(j) and w(j+1) are the real and imaginary parts of a
+*>          complex eigenvalue, the corresponding complex eigenvector is
+*>          computed if either SELECT(j) or SELECT(j+1) is .TRUE., and
+*>          on exit SELECT(j) is set to .TRUE. and SELECT(j+1) is set to
+*>          .FALSE..
+*>          Not referenced if HOWMNY = 'A' or 'B'.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>          The order of the matrix T. N >= 0.
+*> \endverbatim
+*>
+*> \param[in] T
+*> \verbatim
+*>          T is DOUBLE PRECISION array, dimension (LDT,N)
+*>          The upper quasi-triangular matrix T in Schur canonical form.
+*> \endverbatim
+*>
+*> \param[in] LDT
+*> \verbatim
+*>          LDT is INTEGER
+*>          The leading dimension of the array T. LDT >= max(1,N).
+*> \endverbatim
+*>
+*> \param[in,out] VL
+*> \verbatim
+*>          VL is DOUBLE PRECISION array, dimension (LDVL,MM)
+*>          On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL must
+*>          contain an N-by-N matrix Q (usually the orthogonal matrix Q
+*>          of Schur vectors returned by DHSEQR).
+*>          On exit, if SIDE = 'L' or 'B', VL contains:
+*>          if HOWMNY = 'A', the matrix Y of left eigenvectors of T;
+*>          if HOWMNY = 'B', the matrix Q*Y;
+*>          if HOWMNY = 'S', the left eigenvectors of T specified by
+*>                           SELECT, stored consecutively in the columns
+*>                           of VL, in the same order as their
+*>                           eigenvalues.
+*>          A complex eigenvector corresponding to a complex eigenvalue
+*>          is stored in two consecutive columns, the first holding the
+*>          real part, and the second the imaginary part.
+*>          Not referenced if SIDE = 'R'.
+*> \endverbatim
+*>
+*> \param[in] LDVL
+*> \verbatim
+*>          LDVL is INTEGER
+*>          The leading dimension of the array VL.
+*>          LDVL >= 1, and if SIDE = 'L' or 'B', LDVL >= N.
+*> \endverbatim
+*>
+*> \param[in,out] VR
+*> \verbatim
+*>          VR is DOUBLE PRECISION array, dimension (LDVR,MM)
+*>          On entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', VR must
+*>          contain an N-by-N matrix Q (usually the orthogonal matrix Q
+*>          of Schur vectors returned by DHSEQR).
+*>          On exit, if SIDE = 'R' or 'B', VR contains:
+*>          if HOWMNY = 'A', the matrix X of right eigenvectors of T;
+*>          if HOWMNY = 'B', the matrix Q*X;
+*>          if HOWMNY = 'S', the right eigenvectors of T specified by
+*>                           SELECT, stored consecutively in the columns
+*>                           of VR, in the same order as their
+*>                           eigenvalues.
+*>          A complex eigenvector corresponding to a complex eigenvalue
+*>          is stored in two consecutive columns, the first holding the
+*>          real part and the second the imaginary part.
+*>          Not referenced if SIDE = 'L'.
+*> \endverbatim
+*>
+*> \param[in] LDVR
+*> \verbatim
+*>          LDVR is INTEGER
+*>          The leading dimension of the array VR.
+*>          LDVR >= 1, and if SIDE = 'R' or 'B', LDVR >= N.
+*> \endverbatim
+*>
+*> \param[in] MM
+*> \verbatim
+*>          MM is INTEGER
+*>          The number of columns in the arrays VL and/or VR. MM >= M.
+*> \endverbatim
+*>
+*> \param[out] M
+*> \verbatim
+*>          M is INTEGER
+*>          The number of columns in the arrays VL and/or VR actually
+*>          used to store the eigenvectors.
+*>          If HOWMNY = 'A' or 'B', M is set to N.
+*>          Each selected real eigenvector occupies one column and each
+*>          selected complex eigenvector occupies two columns.
+*> \endverbatim
+*>
+*> \param[out] WORK
+*> \verbatim
+*>          WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))
+*> \endverbatim
+*>
+*> \param[in] LWORK
+*> \verbatim
+*>          LWORK is INTEGER
+*>          The dimension of array WORK. LWORK >= max(1,3*N).
+*>          For optimum performance, LWORK >= N + 2*N*NB, where NB is
+*>          the optimal blocksize.
+*>
+*>          If LWORK = -1, then a workspace query is assumed; the routine
+*>          only calculates the optimal size of the WORK array, returns
+*>          this value as the first entry of the WORK array, and no error
+*>          message related to LWORK is issued by XERBLA.
+*> \endverbatim
+*>
+*> \param[out] INFO
+*> \verbatim
+*>          INFO is INTEGER
+*>          = 0:  successful exit
+*>          < 0:  if INFO = -i, the i-th argument had an illegal value
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date November 2011
+*
+*  @precisions fortran d -> s
+*
+*> \ingroup doubleOTHERcomputational
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  The algorithm used in this program is basically backward (forward)
+*>  substitution, with scaling to make the the code robust against
+*>  possible overflow.
+*>
+*>  Each eigenvector is normalized so that the element of largest
+*>  magnitude has magnitude 1; here the magnitude of a complex number
+*>  (x,y) is taken to be |x| + |y|.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE DTREVC3( SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL,
+     $                    VR, LDVR, MM, M, WORK, LWORK, INFO )
+      IMPLICIT NONE
+*
+*  -- LAPACK computational routine (version 3.4.0) --
+*  -- LAPACK is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     November 2011
+*
+*     .. Scalar Arguments ..
+      CHARACTER          HOWMNY, SIDE
+      INTEGER            INFO, LDT, LDVL, LDVR, LWORK, M, MM, N
+*     ..
+*     .. Array Arguments ..
+      LOGICAL            SELECT( * )
+      DOUBLE PRECISION   T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ),
+     $                   WORK( * )
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+      INTEGER            NBMIN, NBMAX
+      PARAMETER          ( NBMIN = 8, NBMAX = 128 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            ALLV, BOTHV, LEFTV, LQUERY, OVER, PAIR,
+     $                   RIGHTV, SOMEV
+      INTEGER            I, IERR, II, IP, IS, J, J1, J2, JNXT, K, KI,
+     $                   IV, MAXWRK, NB, KI2
+      DOUBLE PRECISION   BETA, BIGNUM, EMAX, OVFL, REC, REMAX, SCALE,
+     $                   SMIN, SMLNUM, ULP, UNFL, VCRIT, VMAX, WI, WR,
+     $                   XNORM
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            IDAMAX, ILAENV
+      DOUBLE PRECISION   DDOT, DLAMCH
+      EXTERNAL           LSAME, IDAMAX, ILAENV, DDOT, DLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           DAXPY, DCOPY, DGEMV, DLALN2, DSCAL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, SQRT
+*     ..
+*     .. Local Arrays ..
+      DOUBLE PRECISION   X( 2, 2 )
+      INTEGER            ISCOMPLEX( NBMAX )
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode and test the input parameters
+*
+      BOTHV  = LSAME( SIDE, 'B' )
+      RIGHTV = LSAME( SIDE, 'R' ) .OR. BOTHV
+      LEFTV  = LSAME( SIDE, 'L' ) .OR. BOTHV
+*
+      ALLV  = LSAME( HOWMNY, 'A' )
+      OVER  = LSAME( HOWMNY, 'B' )
+      SOMEV = LSAME( HOWMNY, 'S' )
+*
+      INFO = 0
+      NB = ILAENV( 1, 'DTREVC', SIDE // HOWMNY, N, -1, -1, -1 )
+      MAXWRK = N + 2*N*NB
+      WORK(1) = MAXWRK
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( .NOT.RIGHTV .AND. .NOT.LEFTV ) THEN
+         INFO = -1
+      ELSE IF( .NOT.ALLV .AND. .NOT.OVER .AND. .NOT.SOMEV ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDT.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      ELSE IF( LDVL.LT.1 .OR. ( LEFTV .AND. LDVL.LT.N ) ) THEN
+         INFO = -8
+      ELSE IF( LDVR.LT.1 .OR. ( RIGHTV .AND. LDVR.LT.N ) ) THEN
+         INFO = -10
+      ELSE IF( LWORK.LT.MAX( 1, 3*N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -14
+      ELSE
+*
+*        Set M to the number of columns required to store the selected
+*        eigenvectors, standardize the array SELECT if necessary, and
+*        test MM.
+*
+         IF( SOMEV ) THEN
+            M = 0
+            PAIR = .FALSE.
+            DO 10 J = 1, N
+               IF( PAIR ) THEN
+                  PAIR = .FALSE.
+                  SELECT( J ) = .FALSE.
+               ELSE
+                  IF( J.LT.N ) THEN
+                     IF( T( J+1, J ).EQ.ZERO ) THEN
+                        IF( SELECT( J ) )
+     $                     M = M + 1
+                     ELSE
+                        PAIR = .TRUE.
+                        IF( SELECT( J ) .OR. SELECT( J+1 ) ) THEN
+                           SELECT( J ) = .TRUE.
+                           M = M + 2
+                        END IF
+                     END IF
+                  ELSE
+                     IF( SELECT( N ) )
+     $                  M = M + 1
+                  END IF
+               END IF
+   10       CONTINUE
+         ELSE
+            M = N
+         END IF
+*
+         IF( MM.LT.M ) THEN
+            INFO = -11
+         END IF
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'DTREVC3', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Use blocked version of back-transformation if sufficient workspace.
+*     Zero-out the workspace to avoid potential NaN propagation.
+*
+      IF( OVER .AND. LWORK .GE. N + 2*N*NBMIN ) THEN
+         NB = (LWORK - N) / (2*N)
+         NB = MIN( NB, NBMAX )
+         CALL DLASET( 'F', N, 1+2*NB, ZERO, ZERO, WORK, N )
+      ELSE
+         NB = 1
+      END IF
+*
+*     Set the constants to control overflow.
+*
+      UNFL = DLAMCH( 'Safe minimum' )
+      OVFL = ONE / UNFL
+      CALL DLABAD( UNFL, OVFL )
+      ULP = DLAMCH( 'Precision' )
+      SMLNUM = UNFL*( N / ULP )
+      BIGNUM = ( ONE-ULP ) / SMLNUM
+*
+*     Compute 1-norm of each column of strictly upper triangular
+*     part of T to control overflow in triangular solver.
+*
+      WORK( 1 ) = ZERO
+      DO 30 J = 2, N
+         WORK( J ) = ZERO
+         DO 20 I = 1, J - 1
+            WORK( J ) = WORK( J ) + ABS( T( I, J ) )
+   20    CONTINUE
+   30 CONTINUE
+*
+*     Index IP is used to specify the real or complex eigenvalue:
+*       IP = 0, real eigenvalue,
+*            1, first  of conjugate complex pair: (wr,wi)
+*           -1, second of conjugate complex pair: (wr,wi)
+*       ISCOMPLEX array stores IP for each column in current block.
+*
+      IF( RIGHTV ) THEN
+*
+*        ============================================================
+*        Compute right eigenvectors.
+*
+*        IV is index of column in current block.
+*        For complex right vector, uses IV-1 for real part and IV for complex part.
+*        Non-blocked version always uses IV=2;
+*        blocked     version starts with IV=NB, goes down to 1 or 2.
+*        (Note the "0-th" column is used for 1-norms computed above.)
+         IV = 2
+         IF( NB.GT.2 ) THEN
+            IV = NB
+         END IF
+         
+         IP = 0
+         IS = M
+         DO 140 KI = N, 1, -1
+            IF( IP.EQ.-1 ) THEN
+*              previous iteration (ki+1) was second of conjugate pair,
+*              so this ki is first of conjugate pair; skip to end of loop
+               IP = 1
+               GO TO 140
+            ELSE IF( KI.EQ.1 ) THEN
+*              last column, so this ki must be real eigenvalue
+               IP = 0
+            ELSE IF( T( KI, KI-1 ).EQ.ZERO ) THEN
+*              zero on sub-diagonal, so this ki is real eigenvalue
+               IP = 0
+            ELSE
+*              non-zero on sub-diagonal, so this ki is second of conjugate pair
+               IP = -1
+            END IF
+
+            IF( SOMEV ) THEN
+               IF( IP.EQ.0 ) THEN
+                  IF( .NOT.SELECT( KI ) )
+     $               GO TO 140
+               ELSE
+                  IF( .NOT.SELECT( KI-1 ) )
+     $               GO TO 140
+               END IF
+            END IF
+*
+*           Compute the KI-th eigenvalue (WR,WI).
+*
+            WR = T( KI, KI )
+            WI = ZERO
+            IF( IP.NE.0 )
+     $         WI = SQRT( ABS( T( KI, KI-1 ) ) )*
+     $              SQRT( ABS( T( KI-1, KI ) ) )
+            SMIN = MAX( ULP*( ABS( WR )+ABS( WI ) ), SMLNUM )
+*
+            IF( IP.EQ.0 ) THEN
+*
+*              --------------------------------------------------------
+*              Real right eigenvector
+*
+               WORK( KI + IV*N ) = ONE
+*
+*              Form right-hand side.
+*
+               DO 50 K = 1, KI - 1
+                  WORK( K + IV*N ) = -T( K, KI )
+   50          CONTINUE
+*
+*              Solve upper quasi-triangular system:
+*              [ T(1:KI-1,1:KI-1) - WR ]*X = SCALE*WORK.
+*
+               JNXT = KI - 1
+               DO 60 J = KI - 1, 1, -1
+                  IF( J.GT.JNXT )
+     $               GO TO 60
+                  J1 = J
+                  J2 = J
+                  JNXT = J - 1
+                  IF( J.GT.1 ) THEN
+                     IF( T( J, J-1 ).NE.ZERO ) THEN
+                        J1   = J - 1
+                        JNXT = J - 2
+                     END IF
+                  END IF
+*
+                  IF( J1.EQ.J2 ) THEN
+*
+*                    1-by-1 diagonal block
+*
+                     CALL DLALN2( .FALSE., 1, 1, SMIN, ONE, T( J, J ),
+     $                            LDT, ONE, ONE, WORK( J+IV*N ), N, WR,
+     $                            ZERO, X, 2, SCALE, XNORM, IERR )
+*
+*                    Scale X(1,1) to avoid overflow when updating
+*                    the right-hand side.
+*
+                     IF( XNORM.GT.ONE ) THEN
+                        IF( WORK( J ).GT.BIGNUM / XNORM ) THEN
+                           X( 1, 1 ) = X( 1, 1 ) / XNORM
+                           SCALE = SCALE / XNORM
+                        END IF
+                     END IF
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE )
+     $                  CALL DSCAL( KI, SCALE, WORK( 1+IV*N ), 1 )
+                     WORK( J+IV*N ) = X( 1, 1 )
+*
+*                    Update right-hand side
+*
+                     CALL DAXPY( J-1, -X( 1, 1 ), T( 1, J ), 1,
+     $                           WORK( 1+IV*N ), 1 )
+*
+                  ELSE
+*
+*                    2-by-2 diagonal block
+*
+                     CALL DLALN2( .FALSE., 2, 1, SMIN, ONE,
+     $                            T( J-1, J-1 ), LDT, ONE, ONE,
+     $                            WORK( J-1+IV*N ), N, WR, ZERO, X, 2,
+     $                            SCALE, XNORM, IERR )
+*
+*                    Scale X(1,1) and X(2,1) to avoid overflow when
+*                    updating the right-hand side.
+*
+                     IF( XNORM.GT.ONE ) THEN
+                        BETA = MAX( WORK( J-1 ), WORK( J ) )
+                        IF( BETA.GT.BIGNUM / XNORM ) THEN
+                           X( 1, 1 ) = X( 1, 1 ) / XNORM
+                           X( 2, 1 ) = X( 2, 1 ) / XNORM
+                           SCALE = SCALE / XNORM
+                        END IF
+                     END IF
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE )
+     $                  CALL DSCAL( KI, SCALE, WORK( 1+IV*N ), 1 )
+                     WORK( J-1+IV*N ) = X( 1, 1 )
+                     WORK( J  +IV*N ) = X( 2, 1 )
+*
+*                    Update right-hand side
+*
+                     CALL DAXPY( J-2, -X( 1, 1 ), T( 1, J-1 ), 1,
+     $                           WORK( 1+IV*N ), 1 )
+                     CALL DAXPY( J-2, -X( 2, 1 ), T( 1, J ), 1,
+     $                           WORK( 1+IV*N ), 1 )
+                  END IF
+   60          CONTINUE
+*
+*              Copy the vector x or Q*x to VR and normalize.
+*
+               IF( .NOT.OVER ) THEN
+*                 ------------------------------
+*                 no back-transform: copy x to VR and normalize.
+                  CALL DCOPY( KI, WORK( 1 + IV*N ), 1, VR( 1, IS ), 1 )
+*
+                  II = IDAMAX( KI, VR( 1, IS ), 1 )
+                  REMAX = ONE / ABS( VR( II, IS ) )
+                  CALL DSCAL( KI, REMAX, VR( 1, IS ), 1 )
+*
+                  DO 70 K = KI + 1, N
+                     VR( K, IS ) = ZERO
+   70             CONTINUE
+*
+               ELSE IF( NB.EQ.1 ) THEN
+*                 ------------------------------
+*                 version 1: back-transform each vector with GEMV, Q*x.
+                  IF( KI.GT.1 )
+     $               CALL DGEMV( 'N', N, KI-1, ONE, VR, LDVR,
+     $                           WORK( 1 + IV*N ), 1, WORK( KI + IV*N ),
+     $                           VR( 1, KI ), 1 )
+*
+                  II = IDAMAX( N, VR( 1, KI ), 1 )
+                  REMAX = ONE / ABS( VR( II, KI ) )
+                  CALL DSCAL( N, REMAX, VR( 1, KI ), 1 )
+*
+               ELSE
+*                 ------------------------------
+*                 version 2: back-transform block of vectors with GEMM
+*                 zero out below vector
+                  DO K = KI + 1, N
+                     WORK( K + IV*N ) = ZERO
+                  END DO
+                  ISCOMPLEX( IV ) = IP
+*                 back-transform and normalization is done below
+               END IF
+            ELSE
+*
+*              --------------------------------------------------------
+*              Complex right eigenvector.
+*
+*              Initial solve
+*              [ ( T(KI-1,KI-1) T(KI-1,KI) ) - (WR + I*WI) ]*X = 0.
+*              [ ( T(KI,  KI-1) T(KI,  KI) )               ]
+*
+               IF( ABS( T( KI-1, KI ) ).GE.ABS( T( KI, KI-1 ) ) ) THEN
+                  WORK( KI-1 + (IV-1)*N ) = ONE
+                  WORK( KI   + (IV  )*N ) = WI / T( KI-1, KI )
+               ELSE
+                  WORK( KI-1 + (IV-1)*N ) = -WI / T( KI, KI-1 )
+                  WORK( KI   + (IV  )*N ) = ONE
+               END IF
+               WORK( KI   + (IV-1)*N ) = ZERO
+               WORK( KI-1 + (IV  )*N ) = ZERO
+*
+*              Form right-hand side.
+*
+               DO 80 K = 1, KI - 2
+                  WORK( K+(IV-1)*N ) = -WORK( KI-1+(IV-1)*N )*T(K,KI-1)
+                  WORK( K+(IV  )*N ) = -WORK( KI  +(IV  )*N )*T(K,KI  )
+   80          CONTINUE
+*
+*              Solve upper quasi-triangular system:
+*              [ T(1:KI-2,1:KI-2) - (WR+i*WI) ]*X = SCALE*(WORK+i*WORK2)
+*
+               JNXT = KI - 2
+               DO 90 J = KI - 2, 1, -1
+                  IF( J.GT.JNXT )
+     $               GO TO 90
+                  J1 = J
+                  J2 = J
+                  JNXT = J - 1
+                  IF( J.GT.1 ) THEN
+                     IF( T( J, J-1 ).NE.ZERO ) THEN
+                        J1   = J - 1
+                        JNXT = J - 2
+                     END IF
+                  END IF
+*
+                  IF( J1.EQ.J2 ) THEN
+*
+*                    1-by-1 diagonal block
+*
+                     CALL DLALN2( .FALSE., 1, 2, SMIN, ONE, T( J, J ),
+     $                            LDT, ONE, ONE, WORK( J+(IV-1)*N ), N,
+     $                            WR, WI, X, 2, SCALE, XNORM, IERR )
+*
+*                    Scale X(1,1) and X(1,2) to avoid overflow when
+*                    updating the right-hand side.
+*
+                     IF( XNORM.GT.ONE ) THEN
+                        IF( WORK( J ).GT.BIGNUM / XNORM ) THEN
+                           X( 1, 1 ) = X( 1, 1 ) / XNORM
+                           X( 1, 2 ) = X( 1, 2 ) / XNORM
+                           SCALE = SCALE / XNORM
+                        END IF
+                     END IF
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE ) THEN
+                        CALL DSCAL( KI, SCALE, WORK( 1+(IV-1)*N ), 1 )
+                        CALL DSCAL( KI, SCALE, WORK( 1+(IV  )*N ), 1 )
+                     END IF
+                     WORK( J+(IV-1)*N ) = X( 1, 1 )
+                     WORK( J+(IV  )*N ) = X( 1, 2 )
+*
+*                    Update the right-hand side
+*
+                     CALL DAXPY( J-1, -X( 1, 1 ), T( 1, J ), 1,
+     $                           WORK( 1+(IV-1)*N ), 1 )
+                     CALL DAXPY( J-1, -X( 1, 2 ), T( 1, J ), 1,
+     $                           WORK( 1+(IV  )*N ), 1 )
+*
+                  ELSE
+*
+*                    2-by-2 diagonal block
+*
+                     CALL DLALN2( .FALSE., 2, 2, SMIN, ONE,
+     $                            T( J-1, J-1 ), LDT, ONE, ONE,
+     $                            WORK( J-1+(IV-1)*N ), N, WR, WI, X, 2,
+     $                            SCALE, XNORM, IERR )
+*
+*                    Scale X to avoid overflow when updating
+*                    the right-hand side.
+*
+                     IF( XNORM.GT.ONE ) THEN
+                        BETA = MAX( WORK( J-1 ), WORK( J ) )
+                        IF( BETA.GT.BIGNUM / XNORM ) THEN
+                           REC = ONE / XNORM
+                           X( 1, 1 ) = X( 1, 1 )*REC
+                           X( 1, 2 ) = X( 1, 2 )*REC
+                           X( 2, 1 ) = X( 2, 1 )*REC
+                           X( 2, 2 ) = X( 2, 2 )*REC
+                           SCALE = SCALE*REC
+                        END IF
+                     END IF
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE ) THEN
+                        CALL DSCAL( KI, SCALE, WORK( 1+(IV-1)*N ), 1 )
+                        CALL DSCAL( KI, SCALE, WORK( 1+(IV  )*N ), 1 )
+                     END IF
+                     WORK( J-1+(IV-1)*N ) = X( 1, 1 )
+                     WORK( J  +(IV-1)*N ) = X( 2, 1 )
+                     WORK( J-1+(IV  )*N ) = X( 1, 2 )
+                     WORK( J  +(IV  )*N ) = X( 2, 2 )
+*
+*                    Update the right-hand side
+*
+                     CALL DAXPY( J-2, -X( 1, 1 ), T( 1, J-1 ), 1,
+     $                           WORK( 1+(IV-1)*N   ), 1 )
+                     CALL DAXPY( J-2, -X( 2, 1 ), T( 1, J ), 1,
+     $                           WORK( 1+(IV-1)*N   ), 1 )
+                     CALL DAXPY( J-2, -X( 1, 2 ), T( 1, J-1 ), 1,
+     $                           WORK( 1+(IV  )*N ), 1 )
+                     CALL DAXPY( J-2, -X( 2, 2 ), T( 1, J ), 1,
+     $                           WORK( 1+(IV  )*N ), 1 )
+                  END IF
+   90          CONTINUE
+*
+*              Copy the vector x or Q*x to VR and normalize.
+*
+               IF( .NOT.OVER ) THEN
+*                 ------------------------------
+*                 no back-transform: copy x to VR and normalize.
+                  CALL DCOPY( KI, WORK( 1+(IV-1)*N ), 1, VR(1,IS-1), 1 )
+                  CALL DCOPY( KI, WORK( 1+(IV  )*N ), 1, VR(1,IS  ), 1 )
+*
+                  EMAX = ZERO
+                  DO 100 K = 1, KI
+                     EMAX = MAX( EMAX, ABS( VR( K, IS-1 ) )+
+     $                                 ABS( VR( K, IS   ) ) )
+  100             CONTINUE
+                  REMAX = ONE / EMAX
+                  CALL DSCAL( KI, REMAX, VR( 1, IS-1 ), 1 )
+                  CALL DSCAL( KI, REMAX, VR( 1, IS   ), 1 )
+*
+                  DO 110 K = KI + 1, N
+                     VR( K, IS-1 ) = ZERO
+                     VR( K, IS   ) = ZERO
+  110             CONTINUE
+*
+               ELSE IF( NB.EQ.1 ) THEN
+*                 ------------------------------
+*                 version 1: back-transform each vector with GEMV, Q*x.
+                  IF( KI.GT.2 ) THEN
+                     CALL DGEMV( 'N', N, KI-2, ONE, VR, LDVR,
+     $                           WORK( 1    + (IV-1)*N ), 1,
+     $                           WORK( KI-1 + (IV-1)*N ), VR(1,KI-1), 1)
+                     CALL DGEMV( 'N', N, KI-2, ONE, VR, LDVR,
+     $                           WORK( 1  + (IV)*N ), 1,
+     $                           WORK( KI + (IV)*N ), VR( 1, KI ), 1 )
+                  ELSE
+                     CALL DSCAL( N, WORK(KI-1+(IV-1)*N), VR(1,KI-1), 1)
+                     CALL DSCAL( N, WORK(KI  +(IV  )*N), VR(1,KI  ), 1)
+                  END IF
+*
+                  EMAX = ZERO
+                  DO 120 K = 1, N
+                     EMAX = MAX( EMAX, ABS( VR( K, KI-1 ) )+
+     $                                 ABS( VR( K, KI   ) ) )
+  120             CONTINUE
+                  REMAX = ONE / EMAX
+                  CALL DSCAL( N, REMAX, VR( 1, KI-1 ), 1 )
+                  CALL DSCAL( N, REMAX, VR( 1, KI   ), 1 )
+*
+               ELSE
+*                 ------------------------------
+*                 version 2: back-transform block of vectors with GEMM
+*                 zero out below vector
+                  DO K = KI + 1, N
+                     WORK( K + (IV-1)*N ) = ZERO
+                     WORK( K + (IV  )*N ) = ZERO
+                  END DO
+                  ISCOMPLEX( IV-1 ) = -IP
+                  ISCOMPLEX( IV   ) =  IP
+                  IV = IV - 1
+*                 back-transform and normalization is done below
+               END IF
+            END IF
+            
+            IF( NB.GT.1 ) THEN
+*              --------------------------------------------------------
+*              Blocked version of back-transform
+*              For complex case, KI2 includes both vectors (KI-1 and KI)
+               IF( IP.EQ.0 ) THEN
+                  KI2 = KI
+               ELSE
+                  KI2 = KI - 1
+               END IF
+
+*              Columns IV:NB of work are valid vectors.
+*              When the number of vectors stored reaches NB-1 or NB,
+*              or if this was last vector, do the GEMM
+               IF( (IV.LE.2) .OR. (KI2.EQ.1) ) THEN
+                  CALL DGEMM( 'N', 'N', N, NB-IV+1, KI2+NB-IV, ONE,
+     $                        VR, LDVR,
+     $                        WORK( 1 + (IV)*N    ), N,
+     $                        ZERO,
+     $                        WORK( 1 + (NB+IV)*N ), N )
+*                 normalize vectors
+                  DO K = IV, NB
+                     IF( ISCOMPLEX(K).EQ.0 ) THEN
+*                       real eigenvector
+                        II = IDAMAX( N, WORK( 1 + (NB+K)*N ), 1 )
+                        REMAX = ONE / ABS( WORK( II + (NB+K)*N ) )
+                     ELSE IF( ISCOMPLEX(K).EQ.1 ) THEN
+*                       first eigenvector of conjugate pair
+                        EMAX = ZERO
+                        DO II = 1, N
+                           EMAX = MAX( EMAX,
+     $                                 ABS( WORK( II + (NB+K  )*N ) )+
+     $                                 ABS( WORK( II + (NB+K+1)*N ) ) )
+                        END DO
+                        REMAX = ONE / EMAX
+*                    else if ISCOMPLEX(K).EQ.-1
+*                       second eigenvector of conjugate pair
+*                       reuse same REMAX as previous K
+                     END IF
+                     CALL DSCAL( N, REMAX, WORK( 1 + (NB+K)*N ), 1 )
+                  END DO
+                  CALL DLACPY( 'F', N, NB-IV+1,
+     $                         WORK( 1 + (NB+IV)*N ), N,
+     $                         VR( 1, KI2 ), LDVR )
+                  IV = NB
+               ELSE
+                  IV = IV - 1
+               END IF
+            END IF ! blocked back-transform
+*
+            IS = IS - 1
+            IF( IP.NE.0 )
+     $         IS = IS - 1
+  140    CONTINUE
+      END IF
+
+      IF( LEFTV ) THEN
+*
+*        ============================================================
+*        Compute left eigenvectors.
+*
+*        IV is index of column in current block.
+*        For complex left vector, uses IV for real part and IV+1 for complex part.
+*        Non-blocked version always uses IV=1;
+*        blocked     version starts with IV=1, goes up to NB-1 or NB.
+*        (Note the "0-th" column is used for 1-norms computed above.)
+         IV = 1
+         IP = 0
+         IS = 1
+         DO 260 KI = 1, N
+            IF( IP.EQ.1 ) THEN
+*              previous iteration (ki-1) was first of conjugate pair,
+*              so this ki is second of conjugate pair; skip to end of loop
+               IP = -1
+               GO TO 260
+            ELSE IF( KI.EQ.N ) THEN
+*              last column, so this ki must be real eigenvalue
+               IP = 0
+            ELSE IF( T( KI+1, KI ).EQ.ZERO ) THEN
+*              zero on sub-diagonal, so this ki is real eigenvalue
+               IP = 0
+            ELSE
+*              non-zero on sub-diagonal, so this ki is first of conjugate pair
+               IP = 1
+            END IF
+*
+            IF( SOMEV ) THEN
+               IF( .NOT.SELECT( KI ) )
+     $            GO TO 260
+            END IF
+*
+*           Compute the KI-th eigenvalue (WR,WI).
+*
+            WR = T( KI, KI )
+            WI = ZERO
+            IF( IP.NE.0 )
+     $         WI = SQRT( ABS( T( KI, KI+1 ) ) )*
+     $              SQRT( ABS( T( KI+1, KI ) ) )
+            SMIN = MAX( ULP*( ABS( WR )+ABS( WI ) ), SMLNUM )
+*
+            IF( IP.EQ.0 ) THEN
+*
+*              --------------------------------------------------------
+*              Real left eigenvector
+*
+               WORK( KI + IV*N ) = ONE
+*
+*              Form right-hand side.
+*
+               DO 160 K = KI + 1, N
+                  WORK( K + IV*N ) = -T( KI, K )
+  160          CONTINUE
+*
+*              Solve transposed quasi-triangular system:
+*              [ T(KI+1:N,KI+1:N) - WR ]**T * X = SCALE*WORK
+*
+               VMAX = ONE
+               VCRIT = BIGNUM
+*
+               JNXT = KI + 1
+               DO 170 J = KI + 1, N
+                  IF( J.LT.JNXT )
+     $               GO TO 170
+                  J1 = J
+                  J2 = J
+                  JNXT = J + 1
+                  IF( J.LT.N ) THEN
+                     IF( T( J+1, J ).NE.ZERO ) THEN
+                        J2 = J + 1
+                        JNXT = J + 2
+                     END IF
+                  END IF
+*
+                  IF( J1.EQ.J2 ) THEN
+*
+*                    1-by-1 diagonal block
+*
+*                    Scale if necessary to avoid overflow when forming
+*                    the right-hand side.
+*
+                     IF( WORK( J ).GT.VCRIT ) THEN
+                        REC = ONE / VMAX
+                        CALL DSCAL( N-KI+1, REC, WORK( KI+IV*N ), 1 )
+                        VMAX = ONE
+                        VCRIT = BIGNUM
+                     END IF
+*
+                     WORK( J+IV*N ) = WORK( J+IV*N ) -
+     $                                DDOT( J-KI-1, T( KI+1, J ), 1,
+     $                                      WORK( KI+1+IV*N ), 1 )
+*
+*                    Solve [ T(J,J) - WR ]**T * X = WORK
+*
+                     CALL DLALN2( .FALSE., 1, 1, SMIN, ONE, T( J, J ),
+     $                            LDT, ONE, ONE, WORK( J+IV*N ), N, WR,
+     $                            ZERO, X, 2, SCALE, XNORM, IERR )
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE )
+     $                  CALL DSCAL( N-KI+1, SCALE, WORK( KI+IV*N ), 1 )
+                     WORK( J+IV*N ) = X( 1, 1 )
+                     VMAX = MAX( ABS( WORK( J+IV*N ) ), VMAX )
+                     VCRIT = BIGNUM / VMAX
+*
+                  ELSE
+*
+*                    2-by-2 diagonal block
+*
+*                    Scale if necessary to avoid overflow when forming
+*                    the right-hand side.
+*
+                     BETA = MAX( WORK( J ), WORK( J+1 ) )
+                     IF( BETA.GT.VCRIT ) THEN
+                        REC = ONE / VMAX
+                        CALL DSCAL( N-KI+1, REC, WORK( KI+IV*N ), 1 )
+                        VMAX = ONE
+                        VCRIT = BIGNUM
+                     END IF
+*
+                     WORK( J+IV*N ) = WORK( J+IV*N ) -
+     $                                DDOT( J-KI-1, T( KI+1, J ), 1,
+     $                                      WORK( KI+1+IV*N ), 1 )
+*
+                     WORK( J+1+IV*N ) = WORK( J+1+IV*N ) -
+     $                                  DDOT( J-KI-1, T( KI+1, J+1 ), 1,
+     $                                        WORK( KI+1+IV*N ), 1 )
+*
+*                    Solve
+*                    [ T(J,J)-WR   T(J,J+1)      ]**T * X = SCALE*( WORK1 )
+*                    [ T(J+1,J)    T(J+1,J+1)-WR ]                ( WORK2 )
+*
+                     CALL DLALN2( .TRUE., 2, 1, SMIN, ONE, T( J, J ),
+     $                            LDT, ONE, ONE, WORK( J+IV*N ), N, WR,
+     $                            ZERO, X, 2, SCALE, XNORM, IERR )
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE )
+     $                  CALL DSCAL( N-KI+1, SCALE, WORK( KI+IV*N ), 1 )
+                     WORK( J  +IV*N ) = X( 1, 1 )
+                     WORK( J+1+IV*N ) = X( 2, 1 )
+*
+                     VMAX = MAX( ABS( WORK( J  +IV*N ) ),
+     $                           ABS( WORK( J+1+IV*N ) ), VMAX )
+                     VCRIT = BIGNUM / VMAX
+*
+                  END IF
+  170          CONTINUE
+*
+*              Copy the vector x or Q*x to VL and normalize.
+*
+               IF( .NOT.OVER ) THEN
+*                 ------------------------------
+*                 no back-transform: copy x to VL and normalize.
+                  CALL DCOPY( N-KI+1, WORK( KI + IV*N ), 1,
+     $                                VL( KI, IS ), 1 )
+*
+                  II = IDAMAX( N-KI+1, VL( KI, IS ), 1 ) + KI - 1
+                  REMAX = ONE / ABS( VL( II, IS ) )
+                  CALL DSCAL( N-KI+1, REMAX, VL( KI, IS ), 1 )
+*
+                  DO 180 K = 1, KI - 1
+                     VL( K, IS ) = ZERO
+  180             CONTINUE
+*
+               ELSE IF( NB.EQ.1 ) THEN
+*                 ------------------------------
+*                 version 1: back-transform each vector with GEMV, Q*x.
+                  IF( KI.LT.N )
+     $               CALL DGEMV( 'N', N, N-KI, ONE,
+     $                           VL( 1, KI+1 ), LDVL,
+     $                           WORK( KI+1 + IV*N ), 1,
+     $                           WORK( KI   + IV*N ), VL( 1, KI ), 1 )
+*
+                  II = IDAMAX( N, VL( 1, KI ), 1 )
+                  REMAX = ONE / ABS( VL( II, KI ) )
+                  CALL DSCAL( N, REMAX, VL( 1, KI ), 1 )
+*
+               ELSE
+*                 ------------------------------
+*                 version 2: back-transform block of vectors with GEMM
+*                 zero out above vector
+*                 could go from KI-NV+1 to KI-1
+                  DO K = 1, KI - 1
+                     WORK( K + IV*N ) = ZERO
+                  END DO
+                  ISCOMPLEX( IV ) = IP
+*                 back-transform and normalization is done below
+               END IF
+            ELSE
+*
+*              --------------------------------------------------------
+*              Complex left eigenvector.
+*
+*              Initial solve:
+*              [ ( T(KI,KI)    T(KI,KI+1)  )**T - (WR - I* WI) ]*X = 0.
+*              [ ( T(KI+1,KI) T(KI+1,KI+1) )                   ]
+*
+               IF( ABS( T( KI, KI+1 ) ).GE.ABS( T( KI+1, KI ) ) ) THEN
+                  WORK( KI   + (IV  )*N ) = WI / T( KI, KI+1 )
+                  WORK( KI+1 + (IV+1)*N ) = ONE
+               ELSE
+                  WORK( KI   + (IV  )*N ) = ONE
+                  WORK( KI+1 + (IV+1)*N ) = -WI / T( KI+1, KI )
+               END IF
+               WORK( KI+1 + (IV  )*N ) = ZERO
+               WORK( KI   + (IV+1)*N ) = ZERO
+*
+*              Form right-hand side.
+*
+               DO 190 K = KI + 2, N
+                  WORK( K+(IV  )*N ) = -WORK( KI  +(IV  )*N )*T(KI,  K)
+                  WORK( K+(IV+1)*N ) = -WORK( KI+1+(IV+1)*N )*T(KI+1,K)
+  190          CONTINUE
+*
+*              Solve transposed quasi-triangular system:
+*              [ T(KI+2:N,KI+2:N)**T - (WR-i*WI) ]*X = WORK1+i*WORK2
+*
+               VMAX = ONE
+               VCRIT = BIGNUM
+*
+               JNXT = KI + 2
+               DO 200 J = KI + 2, N
+                  IF( J.LT.JNXT )
+     $               GO TO 200
+                  J1 = J
+                  J2 = J
+                  JNXT = J + 1
+                  IF( J.LT.N ) THEN
+                     IF( T( J+1, J ).NE.ZERO ) THEN
+                        J2 = J + 1
+                        JNXT = J + 2
+                     END IF
+                  END IF
+*
+                  IF( J1.EQ.J2 ) THEN
+*
+*                    1-by-1 diagonal block
+*
+*                    Scale if necessary to avoid overflow when
+*                    forming the right-hand side elements.
+*
+                     IF( WORK( J ).GT.VCRIT ) THEN
+                        REC = ONE / VMAX
+                        CALL DSCAL( N-KI+1, REC, WORK(KI+(IV  )*N), 1 )
+                        CALL DSCAL( N-KI+1, REC, WORK(KI+(IV+1)*N), 1 )
+                        VMAX = ONE
+                        VCRIT = BIGNUM
+                     END IF
+*
+                     WORK( J+(IV  )*N ) = WORK( J+(IV)*N ) -
+     $                                  DDOT( J-KI-2, T( KI+2, J ), 1,
+     $                                        WORK( KI+2+(IV)*N ), 1 )
+                     WORK( J+(IV+1)*N ) = WORK( J+(IV+1)*N ) -
+     $                                  DDOT( J-KI-2, T( KI+2, J ), 1,
+     $                                        WORK( KI+2+(IV+1)*N ), 1 )
+*
+*                    Solve [ T(J,J)-(WR-i*WI) ]*(X11+i*X12)= WK+I*WK2
+*
+                     CALL DLALN2( .FALSE., 1, 2, SMIN, ONE, T( J, J ),
+     $                            LDT, ONE, ONE, WORK( J+IV*N ), N, WR,
+     $                            -WI, X, 2, SCALE, XNORM, IERR )
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE ) THEN
+                        CALL DSCAL( N-KI+1, SCALE, WORK(KI+(IV  )*N), 1)
+                        CALL DSCAL( N-KI+1, SCALE, WORK(KI+(IV+1)*N), 1)
+                     END IF
+                     WORK( J+(IV  )*N ) = X( 1, 1 )
+                     WORK( J+(IV+1)*N ) = X( 1, 2 )
+                     VMAX = MAX( ABS( WORK( J+(IV  )*N ) ),
+     $                           ABS( WORK( J+(IV+1)*N ) ), VMAX )
+                     VCRIT = BIGNUM / VMAX
+*
+                  ELSE
+*
+*                    2-by-2 diagonal block
+*
+*                    Scale if necessary to avoid overflow when forming
+*                    the right-hand side elements.
+*
+                     BETA = MAX( WORK( J ), WORK( J+1 ) )
+                     IF( BETA.GT.VCRIT ) THEN
+                        REC = ONE / VMAX
+                        CALL DSCAL( N-KI+1, REC, WORK(KI+(IV  )*N), 1 )
+                        CALL DSCAL( N-KI+1, REC, WORK(KI+(IV+1)*N), 1 )
+                        VMAX = ONE
+                        VCRIT = BIGNUM
+                     END IF
+*
+                     WORK( J  +(IV  )*N ) = WORK( J+(IV)*N ) -
+     $                                DDOT( J-KI-2, T( KI+2, J ), 1,
+     $                                      WORK( KI+2+(IV)*N ), 1 )
+*
+                     WORK( J  +(IV+1)*N ) = WORK( J+(IV+1)*N ) -
+     $                                DDOT( J-KI-2, T( KI+2, J ), 1,
+     $                                      WORK( KI+2+(IV+1)*N ), 1 )
+*
+                     WORK( J+1+(IV  )*N ) = WORK( J+1+(IV)*N ) -
+     $                                DDOT( J-KI-2, T( KI+2, J+1 ), 1,
+     $                                      WORK( KI+2+(IV)*N ), 1 )
+*
+                     WORK( J+1+(IV+1)*N ) = WORK( J+1+(IV+1)*N ) -
+     $                                DDOT( J-KI-2, T( KI+2, J+1 ), 1,
+     $                                      WORK( KI+2+(IV+1)*N ), 1 )
+*
+*                    Solve 2-by-2 complex linear equation
+*                    [ (T(j,j)   T(j,j+1)  )**T - (wr-i*wi)*I ]*X = SCALE*B
+*                    [ (T(j+1,j) T(j+1,j+1))                  ]
+*
+                     CALL DLALN2( .TRUE., 2, 2, SMIN, ONE, T( J, J ),
+     $                            LDT, ONE, ONE, WORK( J+IV*N ), N, WR,
+     $                            -WI, X, 2, SCALE, XNORM, IERR )
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE ) THEN
+                        CALL DSCAL( N-KI+1, SCALE, WORK(KI+(IV  )*N), 1)
+                        CALL DSCAL( N-KI+1, SCALE, WORK(KI+(IV+1)*N), 1)
+                     END IF
+                     WORK( J  +(IV  )*N ) = X( 1, 1 )
+                     WORK( J  +(IV+1)*N ) = X( 1, 2 )
+                     WORK( J+1+(IV  )*N ) = X( 2, 1 )
+                     WORK( J+1+(IV+1)*N ) = X( 2, 2 )
+                     VMAX = MAX( ABS( X( 1, 1 ) ), ABS( X( 1, 2 ) ),
+     $                           ABS( X( 2, 1 ) ), ABS( X( 2, 2 ) ),
+     $                           VMAX )
+                     VCRIT = BIGNUM / VMAX
+*
+                  END IF
+  200          CONTINUE
+*
+*              Copy the vector x or Q*x to VL and normalize.
+*
+               IF( .NOT.OVER ) THEN
+*                 ------------------------------
+*                 no back-transform: copy x to VL and normalize.
+                  CALL DCOPY( N-KI+1, WORK( KI + (IV  )*N ), 1,
+     $                        VL( KI, IS   ), 1 )
+                  CALL DCOPY( N-KI+1, WORK( KI + (IV+1)*N ), 1,
+     $                        VL( KI, IS+1 ), 1 )
+*
+                  EMAX = ZERO
+                  DO 220 K = KI, N
+                     EMAX = MAX( EMAX, ABS( VL( K, IS   ) )+
+     $                                 ABS( VL( K, IS+1 ) ) )
+  220             CONTINUE
+                  REMAX = ONE / EMAX
+                  CALL DSCAL( N-KI+1, REMAX, VL( KI, IS   ), 1 )
+                  CALL DSCAL( N-KI+1, REMAX, VL( KI, IS+1 ), 1 )
+*
+                  DO 230 K = 1, KI - 1
+                     VL( K, IS   ) = ZERO
+                     VL( K, IS+1 ) = ZERO
+  230             CONTINUE
+*
+               ELSE IF( NB.EQ.1 ) THEN
+*                 ------------------------------
+*                 version 1: back-transform each vector with GEMV, Q*x.
+                  IF( KI.LT.N-1 ) THEN
+                     CALL DGEMV( 'N', N, N-KI-1, ONE,
+     $                           VL( 1, KI+2 ), LDVL,
+     $                           WORK( KI+2 + (IV)*N ), 1,
+     $                           WORK( KI   + (IV)*N ),
+     $                           VL( 1, KI ), 1 )
+                     CALL DGEMV( 'N', N, N-KI-1, ONE,
+     $                           VL( 1, KI+2 ), LDVL,
+     $                           WORK( KI+2 + (IV+1)*N ), 1,
+     $                           WORK( KI+1 + (IV+1)*N ),
+     $                           VL( 1, KI+1 ), 1 )
+                  ELSE
+                     CALL DSCAL( N, WORK(KI+  (IV  )*N), VL(1, KI  ), 1)
+                     CALL DSCAL( N, WORK(KI+1+(IV+1)*N), VL(1, KI+1), 1)
+                  END IF
+*
+                  EMAX = ZERO
+                  DO 240 K = 1, N
+                     EMAX = MAX( EMAX, ABS( VL( K, KI   ) )+
+     $                                 ABS( VL( K, KI+1 ) ) )
+  240             CONTINUE
+                  REMAX = ONE / EMAX
+                  CALL DSCAL( N, REMAX, VL( 1, KI   ), 1 )
+                  CALL DSCAL( N, REMAX, VL( 1, KI+1 ), 1 )
+*
+               ELSE
+*                 ------------------------------
+*                 version 2: back-transform block of vectors with GEMM
+*                 zero out above vector
+*                 could go from KI-NV+1 to KI-1
+                  DO K = 1, KI - 1
+                     WORK( K + (IV  )*N ) = ZERO
+                     WORK( K + (IV+1)*N ) = ZERO
+                  END DO
+                  ISCOMPLEX( IV   ) =  IP
+                  ISCOMPLEX( IV+1 ) = -IP
+                  IV = IV + 1
+*                 back-transform and normalization is done below
+               END IF
+            END IF
+
+            IF( NB.GT.1 ) THEN
+*              --------------------------------------------------------
+*              Blocked version of back-transform
+*              For complex case, KI2 includes both vectors (KI and KI+1)
+               IF( IP.EQ.0 ) THEN
+                  KI2 = KI
+               ELSE
+                  KI2 = KI + 1
+               END IF
+
+*              Columns 1:IV of work are valid vectors.
+*              When the number of vectors stored reaches NB-1 or NB,
+*              or if this was last vector, do the GEMM
+               IF( (IV.GE.NB-1) .OR. (KI2.EQ.N) ) THEN
+                  CALL DGEMM( 'N', 'N', N, IV, N-KI2+IV, ONE,
+     $                        VL( 1, KI2-IV+1 ), LDVL,
+     $                        WORK( KI2-IV+1 + (1)*N ), N,
+     $                        ZERO,
+     $                        WORK( 1 + (NB+1)*N ), N )
+*                 normalize vectors
+                  DO K = 1, IV
+                     IF( ISCOMPLEX(K).EQ.0) THEN
+*                       real eigenvector
+                        II = IDAMAX( N, WORK( 1 + (NB+K)*N ), 1 )
+                        REMAX = ONE / ABS( WORK( II + (NB+K)*N ) )
+                     ELSE IF( ISCOMPLEX(K).EQ.1) THEN
+*                       first eigenvector of conjugate pair
+                        EMAX = ZERO
+                        DO II = 1, N
+                           EMAX = MAX( EMAX,
+     $                                 ABS( WORK( II + (NB+K  )*N ) )+
+     $                                 ABS( WORK( II + (NB+K+1)*N ) ) )
+                        END DO
+                        REMAX = ONE / EMAX
+*                    else if ISCOMPLEX(K).EQ.-1
+*                       second eigenvector of conjugate pair
+*                       reuse same REMAX as previous K
+                     END IF
+                     CALL DSCAL( N, REMAX, WORK( 1 + (NB+K)*N ), 1 )
+                  END DO
+                  CALL DLACPY( 'F', N, IV,
+     $                         WORK( 1 + (NB+1)*N ), N,
+     $                         VL( 1, KI2-IV+1 ), LDVL )
+                  IV = 1
+               ELSE
+                  IV = IV + 1
+               END IF
+            END IF ! blocked back-transform
+*
+            IS = IS + 1
+            IF( IP.NE.0 )
+     $         IS = IS + 1
+  260    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of DTREVC3
+*
+      END
index 89a4468fffa6bc815c21d7df0d4fe83a7f7b27eb..b963ad7386deba19b0c98fb9d1810c7c1834827d 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup auxOTHERauxiliary
 *
 *  =====================================================================
       INTEGER FUNCTION ILAENV( ISPEC, NAME, OPTS, N1, N2, N3, N4 )
 *
-*  -- LAPACK auxiliary routine (version 3.6.0) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER*( * )    NAME, OPTS
             ELSE
                NB = 64
             END IF
+         ELSE IF ( C3.EQ.'EVC' ) THEN
+            IF( SNAME ) THEN
+               NB = 64
+            ELSE
+               NB = 64
+            END IF
          END IF
       ELSE IF( C2.EQ.'LA' ) THEN
          IF( C3.EQ.'UUM' ) THEN
index c882d03f5e48f7e2166fab51987c0f4b909e3d5b..0da02707e63905f54f06d3402ad6062495b1da1c 100644 (file)
 *  ==========
 *
 *>  \param[out] VERS_MAJOR
+*>  \verbatim
 *>      return the lapack major version
+*>  \endverbatim
 *>
 *>  \param[out] VERS_MINOR
+*>  \verbatim
 *>      return the lapack minor version from the major version
+*>  \endverbatim
 *>
 *>  \param[out] VERS_PATCH
+*>  \verbatim
 *>      return the lapack patch version from the minor version
+*>  \endverbatim
 *
 *  Authors:
 *  ========
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup auxOTHERauxiliary
 *
 *  =====================================================================
       SUBROUTINE ILAVER( VERS_MAJOR, VERS_MINOR, VERS_PATCH )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *  =====================================================================
 *
@@ -59,7 +65,7 @@
 *  =====================================================================
       VERS_MAJOR = 3
       VERS_MINOR = 6
-      VERS_PATCH = 0
+      VERS_PATCH = 1
 *  =====================================================================
 *
       RETURN
index 46b87c7ee59df8ffaacde9aaaef6127552d67374..d2cd707fbdc8e5c14167c3fec09a9d730c43cd3a 100644 (file)
 *> \param[in,out] U1
 *> \verbatim
 *>          U1 is REAL array, dimension (LDU1,P)
-*>          On entry, an LDU1-by-P matrix. On exit, U1 is postmultiplied
+*>          On entry, a P-by-P matrix. On exit, U1 is postmultiplied
 *>          by the left singular vector matrix common to [ B11 ; 0 ] and
 *>          [ B12 0 0 ; 0 -I 0 0 ].
 *> \endverbatim
 *> \param[in] LDU1
 *> \verbatim
 *>          LDU1 is INTEGER
-*>          The leading dimension of the array U1.
+*>          The leading dimension of the array U1, LDU1 >= MAX(1,P).
 *> \endverbatim
 *>
 *> \param[in,out] U2
 *> \verbatim
 *>          U2 is REAL array, dimension (LDU2,M-P)
-*>          On entry, an LDU2-by-(M-P) matrix. On exit, U2 is
+*>          On entry, an (M-P)-by-(M-P) matrix. On exit, U2 is
 *>          postmultiplied by the left singular vector matrix common to
 *>          [ B21 ; 0 ] and [ B22 0 0 ; 0 0 I ].
 *> \endverbatim
 *> \param[in] LDU2
 *> \verbatim
 *>          LDU2 is INTEGER
-*>          The leading dimension of the array U2.
+*>          The leading dimension of the array U2, LDU2 >= MAX(1,M-P).
 *> \endverbatim
 *>
 *> \param[in,out] V1T
 *> \verbatim
 *>          V1T is REAL array, dimension (LDV1T,Q)
-*>          On entry, a LDV1T-by-Q matrix. On exit, V1T is premultiplied
+*>          On entry, a Q-by-Q matrix. On exit, V1T is premultiplied
 *>          by the transpose of the right singular vector
 *>          matrix common to [ B11 ; 0 ] and [ B21 ; 0 ].
 *> \endverbatim
 *> \param[in] LDV1T
 *> \verbatim
 *>          LDV1T is INTEGER
-*>          The leading dimension of the array V1T.
+*>          The leading dimension of the array V1T, LDV1T >= MAX(1,Q).
 *> \endverbatim
 *>
 *> \param[in,out] V2T
 *> \verbatim
 *>          V2T is REAL array, dimenison (LDV2T,M-Q)
-*>          On entry, a LDV2T-by-(M-Q) matrix. On exit, V2T is
+*>          On entry, an (M-Q)-by-(M-Q) matrix. On exit, V2T is
 *>          premultiplied by the transpose of the right
 *>          singular vector matrix common to [ B12 0 0 ; 0 -I 0 ] and
 *>          [ B22 0 0 ; 0 0 I ].
 *> \param[in] LDV2T
 *> \verbatim
 *>          LDV2T is INTEGER
-*>          The leading dimension of the array V2T.
+*>          The leading dimension of the array V2T, LDV2T >= MAX(1,M-Q).
 *> \endverbatim
 *>
 *> \param[out] B11D
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup realOTHERcomputational
 *
      $                   V2T, LDV2T, B11D, B11E, B12D, B12E, B21D, B21E,
      $                   B22D, B22E, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBU1, JOBU2, JOBV1T, JOBV2T, TRANS
index 261aa1c21f9fcfd4e9621d36fd54d7de9585b218..b31cc0bf09c108ddc4c5b45da56c6d8654821f85 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup auxOTHERcomputational
 *
       SUBROUTINE SBDSDC( UPLO, COMPQ, N, D, E, U, LDU, VT, LDVT, Q, IQ,
      $                   WORK, IWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.4.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          COMPQ, UPLO
       WSTART = 1
       QSTART = 3
       IF( ICOMPQ.EQ.1 ) THEN
-         CALL SCOPY( N, D, 1, Q( 1 ), 1 )
+         CALL SCOPY( N,   D, 1, Q( 1   ), 1 )
          CALL SCOPY( N-1, E, 1, Q( N+1 ), 1 )
       END IF
       IF( IUPLO.EQ.2 ) THEN
 *     If ICOMPQ = 0, use SLASDQ to compute the singular values.
 *
       IF( ICOMPQ.EQ.0 ) THEN
+*        Ignore WSTART, instead using WORK( 1 ), since the two vectors
+*        for CS and -SN above are added only if ICOMPQ == 2,
+*        and adding them exceeds documented WORK size of 4*n.
          CALL SLASDQ( 'U', 0, N, 0, 0, 0, D, E, VT, LDVT, U, LDU, U,
-     $                LDU, WORK( WSTART ), INFO )
+     $                LDU, WORK( 1 ), INFO )
          GO TO 40
       END IF
 *
index 75264070022b1aed0568575f8cb310530ba85a94..6b5c3c41932d5c4b126faa85554b0a934ca47924 100644 (file)
@@ -80,7 +80,7 @@
 *>          = 'L':  B is lower bidiagonal.
 *> \endverbatim
 *>
-*> \param[in] JOBXZ
+*> \param[in] JOBZ
 *> \verbatim
 *>          JOBZ is CHARACTER*1
 *>          = 'N':  Compute singular values only;
 *>
 *> \param[in] VL
 *> \verbatim
-*>          VL is REAL
-*>          VL >=0.
+*>         VL is REAL
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for singular values. VU > VL.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>         VU is REAL
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for singular values. VU > VL.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest singular value to be returned.
+*>          1 <= IL <= IU <= min(M,N), if min(M,N) > 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest singular values to be returned.
+*>          If RANGE='I', the index of the
+*>          largest singular value to be returned.
 *>          1 <= IL <= IU <= min(M,N), if min(M,N) > 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>          If JOBZ = 'V', then if INFO = 0, the first NS elements of
 *>          IWORK are zero. If INFO > 0, then IWORK contains the indices 
 *>          of the eigenvectors that failed to converge in DSTEVX.
+*> \endverbatim
 *>
+*> \param[out] INFO
+*> \verbatim
 *>          INFO is INTEGER
 *>          = 0:  successful exit
 *>          < 0:  if INFO = -i, the i-th argument had an illegal value
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup realOTHEReigen
 *
       SUBROUTINE SBDSVDX( UPLO, JOBZ, RANGE, N, D, E, VL, VU, IL, IU, 
      $                    NS, S, Z, LDZ, WORK, IWORK, INFO)
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     November 2016
          IF( ABS( E( I ) ).LE.THRESH ) E( I ) = ZERO
       END DO
       IF( ABS( D( N ) ).LE.THRESH ) D( N ) = ZERO
-      E( N ) = ZERO
 *
 *     Pointers for arrays used by SSTEVX.
 *
 *        of the active submatrix.
 *
          RNGVX = 'I'
-         CALL SLASET( 'F', N*2, N+1, ZERO, ZERO, Z, LDZ )
+         IF( WANTZ ) CALL SLASET( 'F', N*2, N+1, ZERO, ZERO, Z, LDZ )
       ELSE IF( VALSV ) THEN
 *
 *        Find singular values in a half-open interval. We aim
          IF( NS.EQ.0 ) THEN
             RETURN
          ELSE
-            CALL SLASET( 'F', N*2, NS, ZERO, ZERO, Z, LDZ )
+            IF( WANTZ ) CALL SLASET( 'F', N*2, NS, ZERO, ZERO, Z, LDZ )
          END IF
       ELSE IF( INDSV ) THEN
 *
 *
          IF( VLTGK.EQ.VUTGK ) VLTGK = VLTGK - TOL
 *
-         CALL SLASET( 'F', N*2, IU-IL+1, ZERO, ZERO, Z, LDZ )
+         IF( WANTZ ) CALL SLASET( 'F', N*2, IU-IL+1, ZERO, ZERO, Z, LDZ)
       END IF             
 *
 *     Initialize variables and pointers for S, Z, and WORK.
                   NRU = 0
                   NRV = 0       
                END IF !** NTGK.GT.0 **! 
-               IF( IROWZ.LT.N*2 )  Z( 1:IROWZ-1, ICOLZ ) = ZERO           
+               IF( IROWZ.LT.N*2 .AND. WANTZ ) THEN
+                  Z( 1:IROWZ-1, ICOLZ ) = ZERO
+               END IF
             END DO !** IDPTR loop **!
-            IF( SPLIT ) THEN
+            IF( SPLIT .AND. WANTZ ) THEN
 *
 *              Bring back eigenvector corresponding
 *              to eigenvalue equal to zero.
          IF( K.NE.NS+1-I ) THEN
             S( K ) = S( NS+1-I )
             S( NS+1-I ) = SMIN
-            CALL SSWAP( N*2, Z( 1,K ), 1, Z( 1,NS+1-I ), 1 )
+            IF( WANTZ ) CALL SSWAP( N*2, Z( 1,K ), 1, Z( 1,NS+1-I ), 1 )
          END IF
       END DO
 *   
          K = IU - IL + 1
          IF( K.LT.NS ) THEN
             S( K+1:NS ) = ZERO
-            Z( 1:N*2,K+1:NS ) = ZERO
+            IF( WANTZ ) Z( 1:N*2,K+1:NS ) = ZERO
             NS = K
          END IF
       END IF 
 *     Reorder Z: U = Z( 1:N,1:NS ), V = Z( N+1:N*2,1:NS ).
 *     If B is a lower diagonal, swap U and V.
 *
+      IF( WANTZ ) THEN
       DO I = 1, NS
          CALL SCOPY( N*2, Z( 1,I ), 1, WORK, 1 )
          IF( LOWER ) THEN
             CALL SCOPY( N, WORK( 1 ), 2, Z( N+1,I ), 1 )
          END IF
       END DO
+      END IF
 *
       RETURN
 *
index d1effd9e3324bea4b460fa2e30754fc1c69440c2..d94b885163ab485d042cc48b63178e15977c82ea 100644 (file)
@@ -83,7 +83,7 @@
 *>
 *> \param[in] AB
 *> \verbatim
-*>          AB is DOUBLE PRECISION array, dimension (LDAB,N)
+*>          AB is REAL array, dimension (LDAB,N)
 *>          On entry, the matrix A in band storage, in rows 1 to KL+KU+1.
 *>          The j-th column of A is stored in the j-th column of the
 *>          array AB as follows:
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup realGBcomputational
 *
       SUBROUTINE SGBEQUB( M, N, KL, KU, AB, LDAB, R, C, ROWCND, COLCND,
      $                    AMAX, INFO )
 *
-*  -- LAPACK computational routine (version 3.4.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            INFO, KL, KU, LDAB, M, N
index a154c3d6e7b4a18a424158aed5166cfd14f93b27..234ea170eb876a5e40a153c1592a04f622638591 100644 (file)
 *>
 *> \param[in] AB
 *> \verbatim
-*>          AB is DOUBLE PRECISION array, dimension (LDAB,N)
+*>          AB is REAL array, dimension (LDAB,N)
 *>     The original band matrix A, stored in rows 1 to KL+KU+1.
 *>     The j-th column of A is stored in the j-th column of the
 *>     array AB as follows:
 *>
 *> \param[in] AFB
 *> \verbatim
-*>          AFB is DOUBLE PRECISION array, dimension (LDAFB,N)
+*>          AFB is REAL array, dimension (LDAFB,N)
 *>     Details of the LU factorization of the band matrix A, as
 *>     computed by DGBTRF.  U is stored as an upper triangular band
 *>     matrix with KL+KU superdiagonals in rows 1 to KL+KU+1, and
      $                    ERR_BNDS_COMP, NPARAMS, PARAMS, WORK, IWORK,
      $                    INFO )
 *
-*  -- LAPACK computational routine (version 3.4.1) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     April 2012
 *
 *     Perform refinement on each right-hand side
 *
-      IF (REF_TYPE .NE. 0) THEN
+      IF ( REF_TYPE .NE. 0 .AND. INFO .EQ. 0 ) THEN
 
          PREC_TYPE = ILAPREC( 'D' )
 
index fe98b450e16f75ee594e20ea63937d0fee60f08c..1deb4d5f7e5612ec0aa7f0f4391c51e943b241e4 100644 (file)
@@ -90,7 +90,7 @@
 *>
 *> \param[in] SELECT
 *> \verbatim
-*>          SELECT is procedure) LOGICAL FUNCTION of two REAL arguments
+*>          SELECT is a LOGICAL FUNCTION of two REAL arguments
 *>          SELECT must be declared EXTERNAL in the calling subroutine.
 *>          If SORT = 'S', SELECT is used to select eigenvalues to sort
 *>          to the top left of the Schur form.
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup realGEeigen
 *
      $                   WR, WI, VS, LDVS, RCONDE, RCONDV, WORK, LWORK,
      $                   IWORK, LIWORK, BWORK, INFO )
 *
-*  -- LAPACK driver routine (version 3.4.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBVS, SENSE, SORT
index 667de0afe45d5d39ddee0982afd961675dc465dc..9f21d1fc5a48292775ff8d473133ee96374f6164 100644 (file)
@@ -26,7 +26,7 @@
 *       INTEGER            INFO, LDA, LDVL, LDVR, LWORK, N
 *       ..
 *       .. Array Arguments ..
-*       REAL               A( LDA, * ), VL( LDVL, * ), VR( LDVR, * ),
+*       REAL   A( LDA, * ), VL( LDVL, * ), VR( LDVR, * ),
 *      $                   WI( * ), WORK( * ), WR( * )
 *       ..
 *  
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
+*
+*  @generated from dgeev.f, fortran d -> s, Tue Apr 19 01:47:44 2016
 *
 *> \ingroup realGEeigen
 *
 *  =====================================================================
       SUBROUTINE SGEEV( JOBVL, JOBVR, N, A, LDA, WR, WI, VL, LDVL, VR,
      $                  LDVR, WORK, LWORK, INFO )
+      implicit none
 *
-*  -- LAPACK driver routine (version 3.4.2) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBVL, JOBVR
       INTEGER            INFO, LDA, LDVL, LDVR, LWORK, N
 *     ..
 *     .. Array Arguments ..
-      REAL               A( LDA, * ), VL( LDVL, * ), VR( LDVR, * ),
+      REAL   A( LDA, * ), VL( LDVL, * ), VR( LDVR, * ),
      $                   WI( * ), WORK( * ), WR( * )
 *     ..
 *
 *  =====================================================================
 *
 *     .. Parameters ..
-      REAL               ZERO, ONE
+      REAL   ZERO, ONE
       PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0 )
 *     ..
 *     .. Local Scalars ..
       LOGICAL            LQUERY, SCALEA, WANTVL, WANTVR
       CHARACTER          SIDE
       INTEGER            HSWORK, I, IBAL, IERR, IHI, ILO, ITAU, IWRK, K,
-     $                   MAXWRK, MINWRK, NOUT
-      REAL               ANRM, BIGNUM, CS, CSCALE, EPS, R, SCL, SMLNUM,
+     $                   LWORK_TREVC, MAXWRK, MINWRK, NOUT
+      REAL   ANRM, BIGNUM, CS, CSCALE, EPS, R, SCL, SMLNUM,
      $                   SN
 *     ..
 *     .. Local Arrays ..
       LOGICAL            SELECT( 1 )
-      REAL               DUM( 1 )
+      REAL   DUM( 1 )
 *     ..
 *     .. External Subroutines ..
       EXTERNAL           SGEBAK, SGEBAL, SGEHRD, SHSEQR, SLABAD, SLACPY,
-     $                   SLARTG, SLASCL, SORGHR, SROT, SSCAL, STREVC,
+     $                   SLARTG, SLASCL, SORGHR, SROT, SSCAL, STREVC3,
      $                   XERBLA
 *     ..
 *     .. External Functions ..
       LOGICAL            LSAME
-      INTEGER            ILAENV, ISAMAX
-      REAL               SLAMCH, SLANGE, SLAPY2, SNRM2
-      EXTERNAL           LSAME, ILAENV, ISAMAX, SLAMCH, SLANGE, SLAPY2,
+      INTEGER            ISAMAX, ILAENV
+      REAL   SLAMCH, SLANGE, SLAPY2, SNRM2
+      EXTERNAL           LSAME, ISAMAX, ILAENV, SLAMCH, SLANGE, SLAPY2,
      $                   SNRM2
 *     ..
 *     .. Intrinsic Functions ..
                MAXWRK = MAX( MAXWRK, 2*N + ( N - 1 )*ILAENV( 1,
      $                       'SORGHR', ' ', N, 1, N, -1 ) )
                CALL SHSEQR( 'S', 'V', N, 1, N, A, LDA, WR, WI, VL, LDVL,
-     $                WORK, -1, INFO )
-               HSWORK = WORK( 1 )
+     $                      WORK, -1, INFO )
+               HSWORK = INT( WORK(1) )
                MAXWRK = MAX( MAXWRK, N + 1, N + HSWORK )
+               CALL STREVC3( 'L', 'B', SELECT, N, A, LDA,
+     $                       VL, LDVL, VR, LDVR, N, NOUT,
+     $                       WORK, -1, IERR )
+               LWORK_TREVC = INT( WORK(1) )
+               MAXWRK = MAX( MAXWRK, N + LWORK_TREVC )
                MAXWRK = MAX( MAXWRK, 4*N )
             ELSE IF( WANTVR ) THEN
                MINWRK = 4*N
                MAXWRK = MAX( MAXWRK, 2*N + ( N - 1 )*ILAENV( 1,
      $                       'SORGHR', ' ', N, 1, N, -1 ) )
                CALL SHSEQR( 'S', 'V', N, 1, N, A, LDA, WR, WI, VR, LDVR,
-     $                WORK, -1, INFO )
-               HSWORK = WORK( 1 )
+     $                      WORK, -1, INFO )
+               HSWORK = INT( WORK(1) )
                MAXWRK = MAX( MAXWRK, N + 1, N + HSWORK )
+               CALL STREVC3( 'R', 'B', SELECT, N, A, LDA,
+     $                       VL, LDVL, VR, LDVR, N, NOUT,
+     $                       WORK, -1, IERR )
+               LWORK_TREVC = INT( WORK(1) )
+               MAXWRK = MAX( MAXWRK, N + LWORK_TREVC )
                MAXWRK = MAX( MAXWRK, 4*N )
             ELSE 
                MINWRK = 3*N
                CALL SHSEQR( 'E', 'N', N, 1, N, A, LDA, WR, WI, VR, LDVR,
-     $                WORK, -1, INFO )
-               HSWORK = WORK( 1 )
+     $                      WORK, -1, INFO )
+               HSWORK = INT( WORK(1) )
                MAXWRK = MAX( MAXWRK, N + 1, N + HSWORK )
             END IF
             MAXWRK = MAX( MAXWRK, MINWRK )
       IF( WANTVL .OR. WANTVR ) THEN
 *
 *        Compute left and/or right eigenvectors
-*        (Workspace: need 4*N)
+*        (Workspace: need 4*N, prefer N + N + 2*N*NB)
 *
-         CALL STREVC( SIDE, 'B', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,
-     $                N, NOUT, WORK( IWRK ), IERR )
+         CALL STREVC3( SIDE, 'B', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,
+     $                 N, NOUT, WORK( IWRK ), LWORK-IWRK+1, IERR )
       END IF
 *
       IF( WANTVL ) THEN
index 821c080cd5f5a983f0dd95ef8f85eea3d5b0e9f1..db20e8bee2916efe181f6b349d56a71147082f91 100644 (file)
 *       .. Scalar Arguments ..
 *       CHARACTER          BALANC, JOBVL, JOBVR, SENSE
 *       INTEGER            IHI, ILO, INFO, LDA, LDVL, LDVR, LWORK, N
-*       REAL               ABNRM
+*       REAL   ABNRM
 *       ..
 *       .. Array Arguments ..
 *       INTEGER            IWORK( * )
-*       REAL               A( LDA, * ), RCONDE( * ), RCONDV( * ),
+*       REAL   A( LDA, * ), RCONDE( * ), RCONDV( * ),
 *      $                   SCALE( * ), VL( LDVL, * ), VR( LDVR, * ),
 *      $                   WI( * ), WORK( * ), WR( * )
 *       ..
 *> \verbatim
 *>          IHI is INTEGER
 *>          ILO and IHI are integer values determined when A was
-*>          balanced.  The balanced A(i,j) = 0 if I > J and 
+*>          balanced.  The balanced A(i,j) = 0 if I > J and
 *>          J = 1,...,ILO-1 or I = IHI+1,...,N.
 *> \endverbatim
 *>
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
+*
+*  @generated from dgeevx.f, fortran d -> s, Tue Apr 19 01:47:44 2016
 *
 *> \ingroup realGEeigen
 *
       SUBROUTINE SGEEVX( BALANC, JOBVL, JOBVR, SENSE, N, A, LDA, WR, WI,
      $                   VL, LDVL, VR, LDVR, ILO, IHI, SCALE, ABNRM,
      $                   RCONDE, RCONDV, WORK, LWORK, IWORK, INFO )
+      implicit none
 *
-*  -- LAPACK driver routine (version 3.4.2) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          BALANC, JOBVL, JOBVR, SENSE
       INTEGER            IHI, ILO, INFO, LDA, LDVL, LDVR, LWORK, N
-      REAL               ABNRM
+      REAL   ABNRM
 *     ..
 *     .. Array Arguments ..
       INTEGER            IWORK( * )
-      REAL               A( LDA, * ), RCONDE( * ), RCONDV( * ),
+      REAL   A( LDA, * ), RCONDE( * ), RCONDV( * ),
      $                   SCALE( * ), VL( LDVL, * ), VR( LDVR, * ),
      $                   WI( * ), WORK( * ), WR( * )
 *     ..
 *  =====================================================================
 *
 *     .. Parameters ..
-      REAL               ZERO, ONE
+      REAL   ZERO, ONE
       PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0 )
 *     ..
 *     .. Local Scalars ..
       LOGICAL            LQUERY, SCALEA, WANTVL, WANTVR, WNTSNB, WNTSNE,
      $                   WNTSNN, WNTSNV
       CHARACTER          JOB, SIDE
-      INTEGER            HSWORK, I, ICOND, IERR, ITAU, IWRK, K, MAXWRK,
-     $                   MINWRK, NOUT
-      REAL               ANRM, BIGNUM, CS, CSCALE, EPS, R, SCL, SMLNUM,
+      INTEGER            HSWORK, I, ICOND, IERR, ITAU, IWRK, K,
+     $                   LWORK_TREVC, MAXWRK, MINWRK, NOUT
+      REAL   ANRM, BIGNUM, CS, CSCALE, EPS, R, SCL, SMLNUM,
      $                   SN
 *     ..
 *     .. Local Arrays ..
       LOGICAL            SELECT( 1 )
-      REAL               DUM( 1 )
+      REAL   DUM( 1 )
 *     ..
 *     .. External Subroutines ..
       EXTERNAL           SGEBAK, SGEBAL, SGEHRD, SHSEQR, SLABAD, SLACPY,
-     $                   SLARTG, SLASCL, SORGHR, SROT, SSCAL, STREVC,
+     $                   SLARTG, SLASCL, SORGHR, SROT, SSCAL, STREVC3,
      $                   STRSNA, XERBLA
 *     ..
 *     .. External Functions ..
       LOGICAL            LSAME
-      INTEGER            ILAENV, ISAMAX
-      REAL               SLAMCH, SLANGE, SLAPY2, SNRM2
-      EXTERNAL           LSAME, ILAENV, ISAMAX, SLAMCH, SLANGE, SLAPY2,
+      INTEGER            ISAMAX, ILAENV
+      REAL   SLAMCH, SLANGE, SLAPY2, SNRM2
+      EXTERNAL           LSAME, ISAMAX, ILAENV, SLAMCH, SLANGE, SLAPY2,
      $                   SNRM2
 *     ..
 *     .. Intrinsic Functions ..
       WNTSNE = LSAME( SENSE, 'E' )
       WNTSNV = LSAME( SENSE, 'V' )
       WNTSNB = LSAME( SENSE, 'B' )
-      IF( .NOT.( LSAME( BALANC, 'N' ) .OR. LSAME( BALANC, 'S' ) .OR.
-     $    LSAME( BALANC, 'P' ) .OR. LSAME( BALANC, 'B' ) ) ) THEN
+      IF( .NOT.( LSAME( BALANC, 'N' ) .OR. LSAME( BALANC, 'S' )
+     $      .OR. LSAME( BALANC, 'P' ) .OR. LSAME( BALANC, 'B' ) ) )
+     $     THEN
          INFO = -1
       ELSE IF( ( .NOT.WANTVL ) .AND. ( .NOT.LSAME( JOBVL, 'N' ) ) ) THEN
          INFO = -2
             MAXWRK = N + N*ILAENV( 1, 'SGEHRD', ' ', N, 1, N, 0 )
 *
             IF( WANTVL ) THEN
+               CALL STREVC3( 'L', 'B', SELECT, N, A, LDA,
+     $                       VL, LDVL, VR, LDVR,
+     $                       N, NOUT, WORK, -1, IERR )
+               LWORK_TREVC = INT( WORK(1) )
+               MAXWRK = MAX( MAXWRK, N + LWORK_TREVC )
                CALL SHSEQR( 'S', 'V', N, 1, N, A, LDA, WR, WI, VL, LDVL,
      $                WORK, -1, INFO )
             ELSE IF( WANTVR ) THEN
+               CALL STREVC3( 'R', 'B', SELECT, N, A, LDA,
+     $                       VL, LDVL, VR, LDVR,
+     $                       N, NOUT, WORK, -1, IERR )
+               LWORK_TREVC = INT( WORK(1) )
+               MAXWRK = MAX( MAXWRK, N + LWORK_TREVC )
                CALL SHSEQR( 'S', 'V', N, 1, N, A, LDA, WR, WI, VR, LDVR,
      $                WORK, -1, INFO )
             ELSE
      $                LDVR, WORK, -1, INFO )
                END IF
             END IF
-            HSWORK = WORK( 1 )
+            HSWORK = INT( WORK(1) )
 *
             IF( ( .NOT.WANTVL ) .AND. ( .NOT.WANTVR ) ) THEN
                MINWRK = 2*N
      $                WORK( IWRK ), LWORK-IWRK+1, INFO )
       END IF
 *
-*     If INFO > 0 from SHSEQR, then quit
+*     If INFO .NE. 0 from SHSEQR, then quit
 *
-      IF( INFO.GT.0 )
+      IF( INFO.NE.0 )
      $   GO TO 50
 *
       IF( WANTVL .OR. WANTVR ) THEN
 *
 *        Compute left and/or right eigenvectors
-*        (Workspace: need 3*N)
+*        (Workspace: need 3*N, prefer N + 2*N*NB)
 *
-         CALL STREVC( SIDE, 'B', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,
-     $                N, NOUT, WORK( IWRK ), IERR )
+         CALL STREVC3( SIDE, 'B', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,
+     $                 N, NOUT, WORK( IWRK ), LWORK-IWRK+1, IERR )
       END IF
 *
 *     Compute condition numbers if desired
index 55bb59e126542c15b3edc8631c0177ac4456b1d1..7d80d4ec07b4531f095b4d321ae2c311baddf263 100644 (file)
@@ -53,7 +53,6 @@
 *> of [SIGMA] is computed and stored in the array SVA.
 *> SGEJSV can sometimes compute tiny singular values and their singular vectors much
 *> more accurately than other SVD routines, see below under Further Details.
-
 *> \endverbatim
 *
 *  Arguments:
 *>                         copied back to the V array. This 'W' option is just
 *>                         a reminder to the caller that in this case U is
 *>                         reserved as workspace of length N*N.
-*>          If JOBU = 'N'  U is not referenced.
+*>          If JOBU = 'N'  U is not referenced, unless JOBT='T'.
 *> \endverbatim
 *>
 *> \param[in] LDU
 *>                         copied back to the U array. This 'W' option is just
 *>                         a reminder to the caller that in this case V is
 *>                         reserved as workspace of length N*N.
-*>          If JOBV = 'N'  V is not referenced.
+*>          If JOBV = 'N'  V is not referenced, unless JOBT='T'.
 *> \endverbatim
 *>
 *> \param[in] LDV
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup realGEsing
 *
 *>     LAPACK Working note 170.
 *> [3] Z. Drmac and Z. Bujanovic: On the failure of rank-revealing QR
 *>     factorization software - a case study.
-*>     ACM Trans. math. Softw. Vol. 35, No 2 (2008), pp. 1-28.
+*>     ACM Trans. Math. Softw. Vol. 35, No 2 (2008), pp. 1-28.
 *>     LAPACK Working note 176.
 *> [4] Z. Drmac: SIGMA - mathematical software library for accurate SVD, PSV,
 *>     QSVD, (H,K)-SVD computations.
      $                   M, N, A, LDA, SVA, U, LDU, V, LDV,
      $                   WORK, LWORK, IWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       IMPLICIT    NONE
 *
 *     Quick return for void matrix (Y3K safe)
 * #:)
-      IF ( ( M .EQ. 0 ) .OR. ( N .EQ. 0 ) ) RETURN
+      IF ( ( M .EQ. 0 ) .OR. ( N .EQ. 0 ) ) THEN
+         IWORK(1:3) = 0
+         WORK(1:7) = 0
+         RETURN
+      ENDIF
 *
 *     Determine whether the matrix U should be M x N or M x M
 *
             IWORK(1) = 0
             IWORK(2) = 0
          END IF
+         IWORK(3) = 0
          IF ( ERREST ) WORK(3) = ONE
          IF ( LSVEC .AND. RSVEC ) THEN
             WORK(4) = ONE
index 86a43f67de8f415e819a996c6bd5ec43902f5e44..a0e1c2c18994cf80f1e85be7dd085f7f74d498de 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup realGEcomputational
 *
 *  =====================================================================
       RECURSIVE SUBROUTINE SGEQRT3( M, N, A, LDA, T, LDT, INFO )
 *
-*  -- LAPACK computational routine (version 3.4.2) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER   INFO, LDA, M, N, LDT
 *
 *        Compute Householder transform when N=1
 *
-         CALL SLARFG( M, A, A( MIN( 2, M ), 1 ), 1, T )
+         CALL SLARFG( M, A(1,1), A( MIN( 2, M ), 1 ), 1, T(1,1) )
 *         
       ELSE
 *
index 1bc7e8a4e92dbce9ede6d04f7a6ce4238090ec07..cae69939400b40de2d1c73e4855980751827c0e7 100644 (file)
@@ -18,8 +18,8 @@
 *  Definition:
 *  ===========
 *
-*       SUBROUTINE SGESDD( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK,
-*                          LWORK, IWORK, INFO )
+*       SUBROUTINE SGESDD( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT,
+*                          WORK, LWORK, IWORK, INFO )
 * 
 *       .. Scalar Arguments ..
 *       CHARACTER          JOBZ
@@ -27,7 +27,7 @@
 *       ..
 *       .. Array Arguments ..
 *       INTEGER            IWORK( * )
-*       REAL               A( LDA, * ), S( * ), U( LDU, * ),
+*       REAL   A( LDA, * ), S( * ), U( LDU, * ),
 *      $                   VT( LDVT, * ), WORK( * )
 *       ..
 *  
 *> \param[in] LDVT
 *> \verbatim
 *>          LDVT is INTEGER
-*>          The leading dimension of the array VT.  LDVT >= 1; if
-*>          JOBZ = 'A' or JOBZ = 'O' and M >= N, LDVT >= N;
+*>          The leading dimension of the array VT.  LDVT >= 1;
+*>          if JOBZ = 'A' or JOBZ = 'O' and M >= N, LDVT >= N;
 *>          if JOBZ = 'S', LDVT >= min(M,N).
 *> \endverbatim
 *>
 *> \verbatim
 *>          LWORK is INTEGER
 *>          The dimension of the array WORK. LWORK >= 1.
-*>          If JOBZ = 'N',
-*>            LWORK >= 3*min(M,N) + max(max(M,N),6*min(M,N)).
-*>          If JOBZ = 'O',
-*>            LWORK >= 3*min(M,N) + 
-*>                     max(max(M,N),5*min(M,N)*min(M,N)+4*min(M,N)).
-*>          If JOBZ = 'S' or 'A'
-*>            LWORK >= min(M,N)*(7+4*min(M,N))
-*>          For good performance, LWORK should generally be larger.
-*>          If LWORK = -1 but other input arguments are legal, WORK(1)
-*>          returns the optimal LWORK.
+*>          If LWORK = -1, a workspace query is assumed.  The optimal
+*>          size for the WORK array is calculated and stored in WORK(1),
+*>          and no other work except argument checking is performed.
+*>
+*>          Let mx = max(M,N) and mn = min(M,N).
+*>          If JOBZ = 'N', LWORK >= 3*mn + max( mx, 7*mn ).
+*>          If JOBZ = 'O', LWORK >= 3*mn + max( mx, 5*mn*mn + 4*mn ).
+*>          If JOBZ = 'S', LWORK >= 4*mn*mn + 7*mn.
+*>          If JOBZ = 'A', LWORK >= 4*mn*mn + 6*mn + mx.
+*>          These are not tight minimums in all cases; see comments inside code.
+*>          For good performance, LWORK should generally be larger;
+*>          a query is recommended.
 *> \endverbatim
 *>
 *> \param[out] IWORK
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup realGEsing
 *
 *>     California at Berkeley, USA
 *>
 *  =====================================================================
-      SUBROUTINE SGESDD( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK,
-     $                   LWORK, IWORK, INFO )
+      SUBROUTINE SGESDD( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT,
+     $                   WORK, LWORK, IWORK, INFO )
+      implicit none
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ
 *     ..
 *     .. Array Arguments ..
       INTEGER            IWORK( * )
-      REAL               A( LDA, * ), S( * ), U( LDU, * ),
+      REAL   A( LDA, * ), S( * ), U( LDU, * ),
      $                   VT( LDVT, * ), WORK( * )
 *     ..
 *
 *  =====================================================================
 *
 *     .. Parameters ..
-      REAL               ZERO, ONE
+      REAL   ZERO, ONE
       PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0 )
 *     ..
 *     .. Local Scalars ..
      $                   IR, ISCL, ITAU, ITAUP, ITAUQ, IU, IVT, LDWKVT,
      $                   LDWRKL, LDWRKR, LDWRKU, MAXWRK, MINMN, MINWRK,
      $                   MNTHR, NWORK, WRKBL
-      REAL               ANRM, BIGNUM, EPS, SMLNUM
+      INTEGER            LWORK_SGEBRD_MN, LWORK_SGEBRD_MM,
+     $                   LWORK_SGEBRD_NN, LWORK_SGELQF_MN,
+     $                   LWORK_SGEQRF_MN,
+     $                   LWORK_SORGBR_P_MM, LWORK_SORGBR_Q_NN,
+     $                   LWORK_SORGLQ_MN, LWORK_SORGLQ_NN,
+     $                   LWORK_SORGQR_MM, LWORK_SORGQR_MN,
+     $                   LWORK_SORMBR_PRT_MM, LWORK_SORMBR_QLN_MM,
+     $                   LWORK_SORMBR_PRT_MN, LWORK_SORMBR_QLN_MN,
+     $                   LWORK_SORMBR_PRT_NN, LWORK_SORMBR_QLN_NN
+      REAL   ANRM, BIGNUM, EPS, SMLNUM
 *     ..
 *     .. Local Arrays ..
       INTEGER            IDUM( 1 )
 *     ..
 *     .. External Functions ..
       LOGICAL            LSAME
-      INTEGER            ILAENV
       REAL               SLAMCH, SLANGE
-      EXTERNAL           ILAENV, LSAME, SLAMCH, SLANGE
+      EXTERNAL           SLAMCH, SLANGE, LSAME
 *     ..
 *     .. Intrinsic Functions ..
       INTRINSIC          INT, MAX, MIN, SQRT
 *
 *     Test the input arguments
 *
-      INFO = 0
-      MINMN = MIN( M, N )
-      WNTQA = LSAME( JOBZ, 'A' )
-      WNTQS = LSAME( JOBZ, 'S' )
+      INFO   = 0
+      MINMN  = MIN( M, N )
+      WNTQA  = LSAME( JOBZ, 'A' )
+      WNTQS  = LSAME( JOBZ, 'S' )
       WNTQAS = WNTQA .OR. WNTQS
-      WNTQO = LSAME( JOBZ, 'O' )
-      WNTQN = LSAME( JOBZ, 'N' )
+      WNTQO  = LSAME( JOBZ, 'O' )
+      WNTQN  = LSAME( JOBZ, 'N' )
       LQUERY = ( LWORK.EQ.-1 )
 *
       IF( .NOT.( WNTQA .OR. WNTQS .OR. WNTQO .OR. WNTQN ) ) THEN
       END IF
 *
 *     Compute workspace
-*      (Note: Comments in the code beginning "Workspace:" describe the
-*       minimal amount of workspace needed at that point in the code,
+*       Note: Comments in the code beginning "Workspace:" describe the
+*       minimal amount of workspace allocated at that point in the code,
 *       as well as the preferred amount for good performance.
 *       NB refers to the optimal block size for the immediately
-*       following subroutine, as returned by ILAENV.)
+*       following subroutine, as returned by ILAENV.
 *
       IF( INFO.EQ.0 ) THEN
          MINWRK = 1
          MAXWRK = 1
+         BDSPAC = 0
+         MNTHR  = INT( MINMN*11.0E0 / 6.0E0 )
          IF( M.GE.N .AND. MINMN.GT.0 ) THEN
 *
 *           Compute space needed for SBDSDC
 *
-            MNTHR = INT( MINMN*11.0E0 / 6.0E0 )
             IF( WNTQN ) THEN
+*              sbdsdc needs only 4*N (or 6*N for uplo=L for LAPACK <= 3.6)
+*              keep 7*N for backwards compatability.
                BDSPAC = 7*N
             ELSE
                BDSPAC = 3*N*N + 4*N
             END IF
+*
+*           Compute space preferred for each routine
+            CALL SGEBRD( M, N, DUM(1), M, DUM(1), DUM(1), DUM(1),
+     $                   DUM(1), DUM(1), -1, IERR )
+            LWORK_SGEBRD_MN = INT( DUM(1) )
+*
+            CALL SGEBRD( N, N, DUM(1), N, DUM(1), DUM(1), DUM(1),
+     $                   DUM(1), DUM(1), -1, IERR )
+            LWORK_SGEBRD_NN = INT( DUM(1) )
+*
+            CALL SGEQRF( M, N, DUM(1), M, DUM(1), DUM(1), -1, IERR )
+            LWORK_SGEQRF_MN = INT( DUM(1) )
+*
+            CALL SORGBR( 'Q', N, N, N, DUM(1), N, DUM(1), DUM(1), -1,
+     $                   IERR )
+            LWORK_SORGBR_Q_NN = INT( DUM(1) )
+*
+            CALL SORGQR( M, M, N, DUM(1), M, DUM(1), DUM(1), -1, IERR )
+            LWORK_SORGQR_MM = INT( DUM(1) )
+*
+            CALL SORGQR( M, N, N, DUM(1), M, DUM(1), DUM(1), -1, IERR )
+            LWORK_SORGQR_MN = INT( DUM(1) )
+*
+            CALL SORMBR( 'P', 'R', 'T', N, N, N, DUM(1), N,
+     $                   DUM(1), DUM(1), N, DUM(1), -1, IERR )
+            LWORK_SORMBR_PRT_NN = INT( DUM(1) )
+*
+            CALL SORMBR( 'Q', 'L', 'N', N, N, N, DUM(1), N,
+     $                   DUM(1), DUM(1), N, DUM(1), -1, IERR )
+            LWORK_SORMBR_QLN_NN = INT( DUM(1) )
+*
+            CALL SORMBR( 'Q', 'L', 'N', M, N, N, DUM(1), M,
+     $                   DUM(1), DUM(1), M, DUM(1), -1, IERR )
+            LWORK_SORMBR_QLN_MN = INT( DUM(1) )
+*
+            CALL SORMBR( 'Q', 'L', 'N', M, M, N, DUM(1), M,
+     $                   DUM(1), DUM(1), M, DUM(1), -1, IERR )
+            LWORK_SORMBR_QLN_MM = INT( DUM(1) )
+*
             IF( M.GE.MNTHR ) THEN
                IF( WNTQN ) THEN
 *
-*                 Path 1 (M much larger than N, JOBZ='N')
+*                 Path 1 (M >> N, JOBZ='N')
 *
-                  WRKBL = N + N*ILAENV( 1, 'SGEQRF', ' ', M, N, -1,
-     $                    -1 )
-                  WRKBL = MAX( WRKBL, 3*N+2*N*
-     $                    ILAENV( 1, 'SGEBRD', ' ', N, N, -1, -1 ) )
-                  MAXWRK = MAX( WRKBL, BDSPAC+N )
+                  WRKBL = N + LWORK_SGEQRF_MN
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_SGEBRD_NN )
+                  MAXWRK = MAX( WRKBL, BDSPAC + N )
                   MINWRK = BDSPAC + N
                ELSE IF( WNTQO ) THEN
 *
-*                 Path 2 (M much larger than N, JOBZ='O')
-*
-                  WRKBL = N + N*ILAENV( 1, 'SGEQRF', ' ', M, N, -1, -1 )
-                  WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'SORGQR', ' ', M,
-     $                    N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*N+2*N*
-     $                    ILAENV( 1, 'SGEBRD', ' ', N, N, -1, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*N+N*
-     $                    ILAENV( 1, 'SORMBR', 'QLN', N, N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*N+N*
-     $                    ILAENV( 1, 'SORMBR', 'PRT', N, N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, BDSPAC+3*N )
+*                 Path 2 (M >> N, JOBZ='O')
+*
+                  WRKBL = N + LWORK_SGEQRF_MN
+                  WRKBL = MAX( WRKBL,   N + LWORK_SORGQR_MN )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_SGEBRD_NN )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_SORMBR_QLN_NN )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_SORMBR_PRT_NN )
+                  WRKBL = MAX( WRKBL, 3*N + BDSPAC )
                   MAXWRK = WRKBL + 2*N*N
                   MINWRK = BDSPAC + 2*N*N + 3*N
                ELSE IF( WNTQS ) THEN
 *
-*                 Path 3 (M much larger than N, JOBZ='S')
-*
-                  WRKBL = N + N*ILAENV( 1, 'SGEQRF', ' ', M, N, -1, -1 )
-                  WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'SORGQR', ' ', M,
-     $                    N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*N+2*N*
-     $                    ILAENV( 1, 'SGEBRD', ' ', N, N, -1, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*N+N*
-     $                    ILAENV( 1, 'SORMBR', 'QLN', N, N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*N+N*
-     $                    ILAENV( 1, 'SORMBR', 'PRT', N, N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, BDSPAC+3*N )
+*                 Path 3 (M >> N, JOBZ='S')
+*
+                  WRKBL = N + LWORK_SGEQRF_MN
+                  WRKBL = MAX( WRKBL,   N + LWORK_SORGQR_MN )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_SGEBRD_NN )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_SORMBR_QLN_NN )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_SORMBR_PRT_NN )
+                  WRKBL = MAX( WRKBL, 3*N + BDSPAC )
                   MAXWRK = WRKBL + N*N
                   MINWRK = BDSPAC + N*N + 3*N
                ELSE IF( WNTQA ) THEN
 *
-*                 Path 4 (M much larger than N, JOBZ='A')
-*
-                  WRKBL = N + N*ILAENV( 1, 'SGEQRF', ' ', M, N, -1, -1 )
-                  WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'SORGQR', ' ', M,
-     $                    M, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*N+2*N*
-     $                    ILAENV( 1, 'SGEBRD', ' ', N, N, -1, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*N+N*
-     $                    ILAENV( 1, 'SORMBR', 'QLN', N, N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*N+N*
-     $                    ILAENV( 1, 'SORMBR', 'PRT', N, N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, BDSPAC+3*N )
+*                 Path 4 (M >> N, JOBZ='A')
+*
+                  WRKBL = N + LWORK_SGEQRF_MN
+                  WRKBL = MAX( WRKBL,   N + LWORK_SORGQR_MM )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_SGEBRD_NN )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_SORMBR_QLN_NN )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_SORMBR_PRT_NN )
+                  WRKBL = MAX( WRKBL, 3*N + BDSPAC )
                   MAXWRK = WRKBL + N*N
-                  MINWRK = BDSPAC + N*N + 2*N + M
+                  MINWRK = N*N + MAX( 3*N + BDSPAC, N + M )
                END IF
             ELSE
 *
-*              Path 5 (M at least N, but not much larger)
+*              Path 5 (M >= N, but not much larger)
 *
-               WRKBL = 3*N + ( M+N )*ILAENV( 1, 'SGEBRD', ' ', M, N, -1,
-     $                 -1 )
+               WRKBL = 3*N + LWORK_SGEBRD_MN
                IF( WNTQN ) THEN
-                  MAXWRK = MAX( WRKBL, BDSPAC+3*N )
+*                 Path 5n (M >= N, jobz='N')
+                  MAXWRK = MAX( WRKBL, 3*N + BDSPAC )
                   MINWRK = 3*N + MAX( M, BDSPAC )
                ELSE IF( WNTQO ) THEN
-                  WRKBL = MAX( WRKBL, 3*N+N*
-     $                    ILAENV( 1, 'SORMBR', 'QLN', M, N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*N+N*
-     $                    ILAENV( 1, 'SORMBR', 'PRT', N, N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, BDSPAC+3*N )
+*                 Path 5o (M >= N, jobz='O')
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_SORMBR_PRT_NN )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_SORMBR_QLN_MN )
+                  WRKBL = MAX( WRKBL, 3*N + BDSPAC )
                   MAXWRK = WRKBL + M*N
-                  MINWRK = 3*N + MAX( M, N*N+BDSPAC )
+                  MINWRK = 3*N + MAX( M, N*N + BDSPAC )
                ELSE IF( WNTQS ) THEN
-                  WRKBL = MAX( WRKBL, 3*N+N*
-     $                    ILAENV( 1, 'SORMBR', 'QLN', M, N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*N+N*
-     $                    ILAENV( 1, 'SORMBR', 'PRT', N, N, N, -1 ) )
-                  MAXWRK = MAX( WRKBL, BDSPAC+3*N )
+*                 Path 5s (M >= N, jobz='S')
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_SORMBR_QLN_MN )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_SORMBR_PRT_NN )
+                  MAXWRK = MAX( WRKBL, 3*N + BDSPAC )
                   MINWRK = 3*N + MAX( M, BDSPAC )
                ELSE IF( WNTQA ) THEN
-                  WRKBL = MAX( WRKBL, 3*N+M*
-     $                    ILAENV( 1, 'SORMBR', 'QLN', M, M, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*N+N*
-     $                    ILAENV( 1, 'SORMBR', 'PRT', N, N, N, -1 ) )
-                  MAXWRK = MAX( MAXWRK, BDSPAC+3*N )
+*                 Path 5a (M >= N, jobz='A')
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_SORMBR_QLN_MM )
+                  WRKBL = MAX( WRKBL, 3*N + LWORK_SORMBR_PRT_NN )
+                  MAXWRK = MAX( WRKBL, 3*N + BDSPAC )
                   MINWRK = 3*N + MAX( M, BDSPAC )
                END IF
             END IF
-         ELSE IF ( MINMN.GT.0 ) THEN
+         ELSE IF( MINMN.GT.0 ) THEN
 *
 *           Compute space needed for SBDSDC
 *
-            MNTHR = INT( MINMN*11.0E0 / 6.0E0 )
             IF( WNTQN ) THEN
+*              sbdsdc needs only 4*N (or 6*N for uplo=L for LAPACK <= 3.6)
+*              keep 7*N for backwards compatability.
                BDSPAC = 7*M
             ELSE
                BDSPAC = 3*M*M + 4*M
             END IF
+*
+*           Compute space preferred for each routine
+            CALL SGEBRD( M, N, DUM(1), M, DUM(1), DUM(1), DUM(1),
+     $                   DUM(1), DUM(1), -1, IERR )
+            LWORK_SGEBRD_MN = INT( DUM(1) )
+*
+            CALL SGEBRD( M, M, A, M, S, DUM(1), DUM(1),
+     $                   DUM(1), DUM(1), -1, IERR )
+            LWORK_SGEBRD_MM = INT( DUM(1) )
+*
+            CALL SGELQF( M, N, A, M, DUM(1), DUM(1), -1, IERR )
+            LWORK_SGELQF_MN = INT( DUM(1) )
+*
+            CALL SORGLQ( N, N, M, DUM(1), N, DUM(1), DUM(1), -1, IERR )
+            LWORK_SORGLQ_NN = INT( DUM(1) )
+*
+            CALL SORGLQ( M, N, M, A, M, DUM(1), DUM(1), -1, IERR )
+            LWORK_SORGLQ_MN = INT( DUM(1) )
+*
+            CALL SORGBR( 'P', M, M, M, A, N, DUM(1), DUM(1), -1, IERR )
+            LWORK_SORGBR_P_MM = INT( DUM(1) )
+*
+            CALL SORMBR( 'P', 'R', 'T', M, M, M, DUM(1), M,
+     $                   DUM(1), DUM(1), M, DUM(1), -1, IERR )
+            LWORK_SORMBR_PRT_MM = INT( DUM(1) )
+*
+            CALL SORMBR( 'P', 'R', 'T', M, N, M, DUM(1), M,
+     $                   DUM(1), DUM(1), M, DUM(1), -1, IERR )
+            LWORK_SORMBR_PRT_MN = INT( DUM(1) )
+*
+            CALL SORMBR( 'P', 'R', 'T', N, N, M, DUM(1), N,
+     $                   DUM(1), DUM(1), N, DUM(1), -1, IERR )
+            LWORK_SORMBR_PRT_NN = INT( DUM(1) )
+*
+            CALL SORMBR( 'Q', 'L', 'N', M, M, M, DUM(1), M,
+     $                   DUM(1), DUM(1), M, DUM(1), -1, IERR )
+            LWORK_SORMBR_QLN_MM = INT( DUM(1) )
+*
             IF( N.GE.MNTHR ) THEN
                IF( WNTQN ) THEN
 *
-*                 Path 1t (N much larger than M, JOBZ='N')
+*                 Path 1t (N >> M, JOBZ='N')
 *
-                  WRKBL = M + M*ILAENV( 1, 'SGELQF', ' ', M, N, -1,
-     $                    -1 )
-                  WRKBL = MAX( WRKBL, 3*M+2*M*
-     $                    ILAENV( 1, 'SGEBRD', ' ', M, M, -1, -1 ) )
-                  MAXWRK = MAX( WRKBL, BDSPAC+M )
+                  WRKBL = M + LWORK_SGELQF_MN
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_SGEBRD_MM )
+                  MAXWRK = MAX( WRKBL, BDSPAC + M )
                   MINWRK = BDSPAC + M
                ELSE IF( WNTQO ) THEN
 *
-*                 Path 2t (N much larger than M, JOBZ='O')
-*
-                  WRKBL = M + M*ILAENV( 1, 'SGELQF', ' ', M, N, -1, -1 )
-                  WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'SORGLQ', ' ', M,
-     $                    N, M, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*M+2*M*
-     $                    ILAENV( 1, 'SGEBRD', ' ', M, M, -1, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*M+M*
-     $                    ILAENV( 1, 'SORMBR', 'QLN', M, M, M, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*M+M*
-     $                    ILAENV( 1, 'SORMBR', 'PRT', M, M, M, -1 ) )
-                  WRKBL = MAX( WRKBL, BDSPAC+3*M )
+*                 Path 2t (N >> M, JOBZ='O')
+*
+                  WRKBL = M + LWORK_SGELQF_MN
+                  WRKBL = MAX( WRKBL,   M + LWORK_SORGLQ_MN )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_SGEBRD_MM )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_SORMBR_QLN_MM )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_SORMBR_PRT_MM )
+                  WRKBL = MAX( WRKBL, 3*M + BDSPAC )
                   MAXWRK = WRKBL + 2*M*M
                   MINWRK = BDSPAC + 2*M*M + 3*M
                ELSE IF( WNTQS ) THEN
 *
-*                 Path 3t (N much larger than M, JOBZ='S')
-*
-                  WRKBL = M + M*ILAENV( 1, 'SGELQF', ' ', M, N, -1, -1 )
-                  WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'SORGLQ', ' ', M,
-     $                    N, M, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*M+2*M*
-     $                    ILAENV( 1, 'SGEBRD', ' ', M, M, -1, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*M+M*
-     $                    ILAENV( 1, 'SORMBR', 'QLN', M, M, M, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*M+M*
-     $                    ILAENV( 1, 'SORMBR', 'PRT', M, M, M, -1 ) )
-                  WRKBL = MAX( WRKBL, BDSPAC+3*M )
+*                 Path 3t (N >> M, JOBZ='S')
+*
+                  WRKBL = M + LWORK_SGELQF_MN
+                  WRKBL = MAX( WRKBL,   M + LWORK_SORGLQ_MN )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_SGEBRD_MM )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_SORMBR_QLN_MM )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_SORMBR_PRT_MM )
+                  WRKBL = MAX( WRKBL, 3*M + BDSPAC )
                   MAXWRK = WRKBL + M*M
                   MINWRK = BDSPAC + M*M + 3*M
                ELSE IF( WNTQA ) THEN
 *
-*                 Path 4t (N much larger than M, JOBZ='A')
-*
-                  WRKBL = M + M*ILAENV( 1, 'SGELQF', ' ', M, N, -1, -1 )
-                  WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'SORGLQ', ' ', N,
-     $                    N, M, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*M+2*M*
-     $                    ILAENV( 1, 'SGEBRD', ' ', M, M, -1, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*M+M*
-     $                    ILAENV( 1, 'SORMBR', 'QLN', M, M, M, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*M+M*
-     $                    ILAENV( 1, 'SORMBR', 'PRT', M, M, M, -1 ) )
-                  WRKBL = MAX( WRKBL, BDSPAC+3*M )
+*                 Path 4t (N >> M, JOBZ='A')
+*
+                  WRKBL = M + LWORK_SGELQF_MN
+                  WRKBL = MAX( WRKBL,   M + LWORK_SORGLQ_NN )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_SGEBRD_MM )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_SORMBR_QLN_MM )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_SORMBR_PRT_MM )
+                  WRKBL = MAX( WRKBL, 3*M + BDSPAC )
                   MAXWRK = WRKBL + M*M
-                  MINWRK = BDSPAC + M*M + 3*M
+                  MINWRK = M*M + MAX( 3*M + BDSPAC, M + N )
                END IF
             ELSE
 *
-*              Path 5t (N greater than M, but not much larger)
+*              Path 5t (N > M, but not much larger)
 *
-               WRKBL = 3*M + ( M+N )*ILAENV( 1, 'SGEBRD', ' ', M, N, -1,
-     $                 -1 )
+               WRKBL = 3*M + LWORK_SGEBRD_MN
                IF( WNTQN ) THEN
-                  MAXWRK = MAX( WRKBL, BDSPAC+3*M )
+*                 Path 5tn (N > M, jobz='N')
+                  MAXWRK = MAX( WRKBL, 3*M + BDSPAC )
                   MINWRK = 3*M + MAX( N, BDSPAC )
                ELSE IF( WNTQO ) THEN
-                  WRKBL = MAX( WRKBL, 3*M+M*
-     $                    ILAENV( 1, 'SORMBR', 'QLN', M, M, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*M+M*
-     $                    ILAENV( 1, 'SORMBR', 'PRT', M, N, M, -1 ) )
-                  WRKBL = MAX( WRKBL, BDSPAC+3*M )
+*                 Path 5to (N > M, jobz='O')
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_SORMBR_QLN_MM )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_SORMBR_PRT_MN )
+                  WRKBL = MAX( WRKBL, 3*M + BDSPAC )
                   MAXWRK = WRKBL + M*N
-                  MINWRK = 3*M + MAX( N, M*M+BDSPAC )
+                  MINWRK = 3*M + MAX( N, M*M + BDSPAC )
                ELSE IF( WNTQS ) THEN
-                  WRKBL = MAX( WRKBL, 3*M+M*
-     $                    ILAENV( 1, 'SORMBR', 'QLN', M, M, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*M+M*
-     $                    ILAENV( 1, 'SORMBR', 'PRT', M, N, M, -1 ) )
-                  MAXWRK = MAX( WRKBL, BDSPAC+3*M )
+*                 Path 5ts (N > M, jobz='S')
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_SORMBR_QLN_MM )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_SORMBR_PRT_MN )
+                  MAXWRK = MAX( WRKBL, 3*M + BDSPAC )
                   MINWRK = 3*M + MAX( N, BDSPAC )
                ELSE IF( WNTQA ) THEN
-                  WRKBL = MAX( WRKBL, 3*M+M*
-     $                    ILAENV( 1, 'SORMBR', 'QLN', M, M, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 3*M+M*
-     $                    ILAENV( 1, 'SORMBR', 'PRT', N, N, M, -1 ) )
-                  MAXWRK = MAX( WRKBL, BDSPAC+3*M )
+*                 Path 5ta (N > M, jobz='A')
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_SORMBR_QLN_MM )
+                  WRKBL = MAX( WRKBL, 3*M + LWORK_SORMBR_PRT_NN )
+                  MAXWRK = MAX( WRKBL, 3*M + BDSPAC )
                   MINWRK = 3*M + MAX( N, BDSPAC )
                END IF
             END IF
          END IF
+         
          MAXWRK = MAX( MAXWRK, MINWRK )
          WORK( 1 ) = MAXWRK
 *
 *
             IF( WNTQN ) THEN
 *
-*              Path 1 (M much larger than N, JOBZ='N')
+*              Path 1 (M >> N, JOBZ='N')
 *              No singular vectors to be computed
 *
                ITAU = 1
                NWORK = ITAU + N
 *
 *              Compute A=Q*R
-*              (Workspace: need 2*N, prefer N+N*NB)
+*              Workspace: need   N [tau] + N    [work]
+*              Workspace: prefer N [tau] + N*NB [work]
 *
                CALL SGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
 *              Zero out below R
 *
                NWORK = ITAUP + N
 *
 *              Bidiagonalize R in A
-*              (Workspace: need 4*N, prefer 3*N+2*N*NB)
+*              Workspace: need   3*N [e, tauq, taup] + N      [work]
+*              Workspace: prefer 3*N [e, tauq, taup] + 2*N*NB [work]
 *
                CALL SGEBRD( N, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
      $                      WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
                NWORK = IE + N
 *
 *              Perform bidiagonal SVD, computing singular values only
-*              (Workspace: need N+BDSPAC)
+*              Workspace: need   N [e] + BDSPAC
 *
                CALL SBDSDC( 'U', 'N', N, S, WORK( IE ), DUM, 1, DUM, 1,
      $                      DUM, IDUM, WORK( NWORK ), IWORK, INFO )
 *
             ELSE IF( WNTQO ) THEN
 *
-*              Path 2 (M much larger than N, JOBZ = 'O')
+*              Path 2 (M >> N, JOBZ = 'O')
 *              N left singular vectors to be overwritten on A and
 *              N right singular vectors to be computed in VT
 *
 *
 *              WORK(IR) is LDWRKR by N
 *
-               IF( LWORK.GE.LDA*N+N*N+3*N+BDSPAC ) THEN
+               IF( LWORK .GE. LDA*N + N*N + 3*N + BDSPAC ) THEN
                   LDWRKR = LDA
                ELSE
-                  LDWRKR = ( LWORK-N*N-3*N-BDSPAC ) / N
+                  LDWRKR = ( LWORK - N*N - 3*N - BDSPAC ) / N
                END IF
                ITAU = IR + LDWRKR*N
                NWORK = ITAU + N
 *
 *              Compute A=Q*R
-*              (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*              Workspace: need   N*N [R] + N [tau] + N    [work]
+*              Workspace: prefer N*N [R] + N [tau] + N*NB [work]
 *
                CALL SGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
 *              Copy R to WORK(IR), zeroing out below it
 *
                CALL SLACPY( 'U', N, N, A, LDA, WORK( IR ), LDWRKR )
-               CALL SLASET( 'L', N-1, N-1, ZERO, ZERO, WORK( IR+1 ),
+               CALL SLASET( 'L', N - 1, N - 1, ZERO, ZERO, WORK(IR+1),
      $                      LDWRKR )
 *
 *              Generate Q in A
-*              (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*              Workspace: need   N*N [R] + N [tau] + N    [work]
+*              Workspace: prefer N*N [R] + N [tau] + N*NB [work]
 *
                CALL SORGQR( M, N, N, A, LDA, WORK( ITAU ),
-     $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
+     $                      WORK( NWORK ), LWORK - NWORK + 1, IERR )
                IE = ITAU
                ITAUQ = IE + N
                ITAUP = ITAUQ + N
                NWORK = ITAUP + N
 *
-*              Bidiagonalize R in VT, copying result to WORK(IR)
-*              (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
+*              Bidiagonalize R in WORK(IR)
+*              Workspace: need   N*N [R] + 3*N [e, tauq, taup] + N      [work]
+*              Workspace: prefer N*N [R] + 3*N [e, tauq, taup] + 2*N*NB [work]
 *
                CALL SGEBRD( N, N, WORK( IR ), LDWRKR, S, WORK( IE ),
      $                      WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
 *              WORK(IU) is N by N
 *
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in WORK(IU) and computing right
 *              singular vectors of bidiagonal matrix in VT
-*              (Workspace: need N+N*N+BDSPAC)
+*              Workspace: need   N*N [R] + 3*N [e, tauq, taup] + N*N [U] + BDSPAC
 *
                CALL SBDSDC( 'U', 'I', N, S, WORK( IE ), WORK( IU ), N,
      $                      VT, LDVT, DUM, IDUM, WORK( NWORK ), IWORK,
 *
 *              Overwrite WORK(IU) by left singular vectors of R
 *              and VT by right singular vectors of R
-*              (Workspace: need 2*N*N+3*N, prefer 2*N*N+2*N+N*NB)
+*              Workspace: need   N*N [R] + 3*N [e, tauq, taup] + N*N [U] + N    [work]
+*              Workspace: prefer N*N [R] + 3*N [e, tauq, taup] + N*N [U] + N*NB [work]
 *
                CALL SORMBR( 'Q', 'L', 'N', N, N, N, WORK( IR ), LDWRKR,
      $                      WORK( ITAUQ ), WORK( IU ), N, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
                CALL SORMBR( 'P', 'R', 'T', N, N, N, WORK( IR ), LDWRKR,
      $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
 *              Multiply Q in A by left singular vectors of R in
 *              WORK(IU), storing result in WORK(IR) and copying to A
-*              (Workspace: need 2*N*N, prefer N*N+M*N)
+*              Workspace: need   N*N [R] + 3*N [e, tauq, taup] + N*N [U]
+*              Workspace: prefer M*N [R] + 3*N [e, tauq, taup] + N*N [U]
 *
                DO 10 I = 1, M, LDWRKR
-                  CHUNK = MIN( M-I+1, LDWRKR )
+                  CHUNK = MIN( M - I + 1, LDWRKR )
                   CALL SGEMM( 'N', 'N', CHUNK, N, N, ONE, A( I, 1 ),
      $                        LDA, WORK( IU ), N, ZERO, WORK( IR ),
      $                        LDWRKR )
 *
             ELSE IF( WNTQS ) THEN
 *
-*              Path 3 (M much larger than N, JOBZ='S')
+*              Path 3 (M >> N, JOBZ='S')
 *              N left singular vectors to be computed in U and
 *              N right singular vectors to be computed in VT
 *
                NWORK = ITAU + N
 *
 *              Compute A=Q*R
-*              (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*              Workspace: need   N*N [R] + N [tau] + N    [work]
+*              Workspace: prefer N*N [R] + N [tau] + N*NB [work]
 *
                CALL SGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
 *              Copy R to WORK(IR), zeroing out below it
 *
                CALL SLACPY( 'U', N, N, A, LDA, WORK( IR ), LDWRKR )
-               CALL SLASET( 'L', N-1, N-1, ZERO, ZERO, WORK( IR+1 ),
+               CALL SLASET( 'L', N - 1, N - 1, ZERO, ZERO, WORK(IR+1),
      $                      LDWRKR )
 *
 *              Generate Q in A
-*              (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*              Workspace: need   N*N [R] + N [tau] + N    [work]
+*              Workspace: prefer N*N [R] + N [tau] + N*NB [work]
 *
                CALL SORGQR( M, N, N, A, LDA, WORK( ITAU ),
-     $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
+     $                      WORK( NWORK ), LWORK - NWORK + 1, IERR )
                IE = ITAU
                ITAUQ = IE + N
                ITAUP = ITAUQ + N
                NWORK = ITAUP + N
 *
 *              Bidiagonalize R in WORK(IR)
-*              (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
+*              Workspace: need   N*N [R] + 3*N [e, tauq, taup] + N      [work]
+*              Workspace: prefer N*N [R] + 3*N [e, tauq, taup] + 2*N*NB [work]
 *
                CALL SGEBRD( N, N, WORK( IR ), LDWRKR, S, WORK( IE ),
      $                      WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagoal matrix in U and computing right singular
 *              vectors of bidiagonal matrix in VT
-*              (Workspace: need N+BDSPAC)
+*              Workspace: need   N*N [R] + 3*N [e, tauq, taup] + BDSPAC
 *
                CALL SBDSDC( 'U', 'I', N, S, WORK( IE ), U, LDU, VT,
      $                      LDVT, DUM, IDUM, WORK( NWORK ), IWORK,
 *
 *              Overwrite U by left singular vectors of R and VT
 *              by right singular vectors of R
-*              (Workspace: need N*N+3*N, prefer N*N+2*N+N*NB)
+*              Workspace: need   N*N [R] + 3*N [e, tauq, taup] + N    [work]
+*              Workspace: prefer N*N [R] + 3*N [e, tauq, taup] + N*NB [work]
 *
                CALL SORMBR( 'Q', 'L', 'N', N, N, N, WORK( IR ), LDWRKR,
      $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
                CALL SORMBR( 'P', 'R', 'T', N, N, N, WORK( IR ), LDWRKR,
      $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
 *              Multiply Q in A by left singular vectors of R in
 *              WORK(IR), storing result in U
-*              (Workspace: need N*N)
+*              Workspace: need   N*N [R]
 *
                CALL SLACPY( 'F', N, N, U, LDU, WORK( IR ), LDWRKR )
                CALL SGEMM( 'N', 'N', M, N, N, ONE, A, LDA, WORK( IR ),
 *
             ELSE IF( WNTQA ) THEN
 *
-*              Path 4 (M much larger than N, JOBZ='A')
+*              Path 4 (M >> N, JOBZ='A')
 *              M left singular vectors to be computed in U and
 *              N right singular vectors to be computed in VT
 *
                NWORK = ITAU + N
 *
 *              Compute A=Q*R, copying result to U
-*              (Workspace: need N*N+N+M, prefer N*N+N+M*NB)
+*              Workspace: need   N*N [U] + N [tau] + N    [work]
+*              Workspace: prefer N*N [U] + N [tau] + N*NB [work]
 *
                CALL SGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
                CALL SLACPY( 'L', M, N, A, LDA, U, LDU )
 *
 *              Generate Q in U
-*              (Workspace: need N*N+N+M, prefer N*N+N+M*NB)
+*              Workspace: need   N*N [U] + N [tau] + M    [work]
+*              Workspace: prefer N*N [U] + N [tau] + M*NB [work]
                CALL SORGQR( M, M, N, U, LDU, WORK( ITAU ),
-     $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
+     $                      WORK( NWORK ), LWORK - NWORK + 1, IERR )
 *
 *              Produce R in A, zeroing out other entries
 *
                NWORK = ITAUP + N
 *
 *              Bidiagonalize R in A
-*              (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
+*              Workspace: need   N*N [U] + 3*N [e, tauq, taup] + N      [work]
+*              Workspace: prefer N*N [U] + 3*N [e, tauq, taup] + 2*N*NB [work]
 *
                CALL SGEBRD( N, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
      $                      WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in WORK(IU) and computing right
 *              singular vectors of bidiagonal matrix in VT
-*              (Workspace: need N+N*N+BDSPAC)
+*              Workspace: need   N*N [U] + 3*N [e, tauq, taup] + BDSPAC
 *
                CALL SBDSDC( 'U', 'I', N, S, WORK( IE ), WORK( IU ), N,
      $                      VT, LDVT, DUM, IDUM, WORK( NWORK ), IWORK,
 *
 *              Overwrite WORK(IU) by left singular vectors of R and VT
 *              by right singular vectors of R
-*              (Workspace: need N*N+3*N, prefer N*N+2*N+N*NB)
+*              Workspace: need   N*N [U] + 3*N [e, tauq, taup] + N    [work]
+*              Workspace: prefer N*N [U] + 3*N [e, tauq, taup] + N*NB [work]
 *
                CALL SORMBR( 'Q', 'L', 'N', N, N, N, A, LDA,
      $                      WORK( ITAUQ ), WORK( IU ), LDWRKU,
-     $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
+     $                      WORK( NWORK ), LWORK - NWORK + 1, IERR )
                CALL SORMBR( 'P', 'R', 'T', N, N, N, A, LDA,
      $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
 *              Multiply Q in U by left singular vectors of R in
 *              WORK(IU), storing result in A
-*              (Workspace: need N*N)
+*              Workspace: need   N*N [U]
 *
                CALL SGEMM( 'N', 'N', M, N, N, ONE, U, LDU, WORK( IU ),
      $                     LDWRKU, ZERO, A, LDA )
 *
 *           M .LT. MNTHR
 *
-*           Path 5 (M at least N, but not much larger)
+*           Path 5 (M >= N, but not much larger)
 *           Reduce to bidiagonal form without QR decomposition
 *
             IE = 1
             NWORK = ITAUP + N
 *
 *           Bidiagonalize A
-*           (Workspace: need 3*N+M, prefer 3*N+(M+N)*NB)
+*           Workspace: need   3*N [e, tauq, taup] + M        [work]
+*           Workspace: prefer 3*N [e, tauq, taup] + (M+N)*NB [work]
 *
             CALL SGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
      $                   WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
      $                   IERR )
             IF( WNTQN ) THEN
 *
+*              Path 5n (M >= N, JOBZ='N')
 *              Perform bidiagonal SVD, only computing singular values
-*              (Workspace: need N+BDSPAC)
+*              Workspace: need   3*N [e, tauq, taup] + BDSPAC
 *
                CALL SBDSDC( 'U', 'N', N, S, WORK( IE ), DUM, 1, DUM, 1,
      $                      DUM, IDUM, WORK( NWORK ), IWORK, INFO )
             ELSE IF( WNTQO ) THEN
+*              Path 5o (M >= N, JOBZ='O')
                IU = NWORK
-               IF( LWORK.GE.M*N+3*N+BDSPAC ) THEN
+               IF( LWORK .GE. M*N + 3*N + BDSPAC ) THEN
 *
 *                 WORK( IU ) is M by N
 *
                   NWORK = IU + LDWRKU*N
                   CALL SLASET( 'F', M, N, ZERO, ZERO, WORK( IU ),
      $                         LDWRKU )
+*                 IR is unused; silence compile warnings
+                  IR = -1
                ELSE
 *
 *                 WORK( IU ) is N by N
 *                 WORK(IR) is LDWRKR by N
 *
                   IR = NWORK
-                  LDWRKR = ( LWORK-N*N-3*N ) / N
+                  LDWRKR = ( LWORK - N*N - 3*N ) / N
                END IF
                NWORK = IU + LDWRKU*N
 *
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in WORK(IU) and computing right
 *              singular vectors of bidiagonal matrix in VT
-*              (Workspace: need N+N*N+BDSPAC)
+*              Workspace: need   3*N [e, tauq, taup] + N*N [U] + BDSPAC
 *
                CALL SBDSDC( 'U', 'I', N, S, WORK( IE ), WORK( IU ),
      $                      LDWRKU, VT, LDVT, DUM, IDUM, WORK( NWORK ),
      $                      IWORK, INFO )
 *
 *              Overwrite VT by right singular vectors of A
-*              (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*              Workspace: need   3*N [e, tauq, taup] + N*N [U] + N    [work]
+*              Workspace: prefer 3*N [e, tauq, taup] + N*N [U] + N*NB [work]
 *
                CALL SORMBR( 'P', 'R', 'T', N, N, N, A, LDA,
      $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
-               IF( LWORK.GE.M*N+3*N+BDSPAC ) THEN
+               IF( LWORK .GE. M*N + 3*N + BDSPAC ) THEN
 *
+*                 Path 5o-fast
 *                 Overwrite WORK(IU) by left singular vectors of A
-*                 (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                 Workspace: need   3*N [e, tauq, taup] + M*N [U] + N    [work]
+*                 Workspace: prefer 3*N [e, tauq, taup] + M*N [U] + N*NB [work]
 *
                   CALL SORMBR( 'Q', 'L', 'N', M, N, N, A, LDA,
      $                         WORK( ITAUQ ), WORK( IU ), LDWRKU,
-     $                         WORK( NWORK ), LWORK-NWORK+1, IERR )
+     $                         WORK( NWORK ), LWORK - NWORK + 1, IERR )
 *
 *                 Copy left singular vectors of A from WORK(IU) to A
 *
                   CALL SLACPY( 'F', M, N, WORK( IU ), LDWRKU, A, LDA )
                ELSE
 *
+*                 Path 5o-slow
 *                 Generate Q in A
-*                 (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
+*                 Workspace: need   3*N [e, tauq, taup] + N*N [U] + N    [work]
+*                 Workspace: prefer 3*N [e, tauq, taup] + N*N [U] + N*NB [work]
 *
                   CALL SORGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
-     $                         WORK( NWORK ), LWORK-NWORK+1, IERR )
+     $                         WORK( NWORK ), LWORK - NWORK + 1, IERR )
 *
 *                 Multiply Q in A by left singular vectors of
 *                 bidiagonal matrix in WORK(IU), storing result in
 *                 WORK(IR) and copying to A
-*                 (Workspace: need 2*N*N, prefer N*N+M*N)
+*                 Workspace: need   3*N [e, tauq, taup] + N*N [U] + NB*N [R]
+*                 Workspace: prefer 3*N [e, tauq, taup] + N*N [U] + M*N  [R]
 *
                   DO 20 I = 1, M, LDWRKR
-                     CHUNK = MIN( M-I+1, LDWRKR )
+                     CHUNK = MIN( M - I + 1, LDWRKR )
                      CALL SGEMM( 'N', 'N', CHUNK, N, N, ONE, A( I, 1 ),
      $                           LDA, WORK( IU ), LDWRKU, ZERO,
      $                           WORK( IR ), LDWRKR )
 *
             ELSE IF( WNTQS ) THEN
 *
+*              Path 5s (M >= N, JOBZ='S')
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in U and computing right singular
 *              vectors of bidiagonal matrix in VT
-*              (Workspace: need N+BDSPAC)
+*              Workspace: need   3*N [e, tauq, taup] + BDSPAC
 *
                CALL SLASET( 'F', M, N, ZERO, ZERO, U, LDU )
                CALL SBDSDC( 'U', 'I', N, S, WORK( IE ), U, LDU, VT,
 *
 *              Overwrite U by left singular vectors of A and VT
 *              by right singular vectors of A
-*              (Workspace: need 3*N, prefer 2*N+N*NB)
+*              Workspace: need   3*N [e, tauq, taup] + N    [work]
+*              Workspace: prefer 3*N [e, tauq, taup] + N*NB [work]
 *
                CALL SORMBR( 'Q', 'L', 'N', M, N, N, A, LDA,
      $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
                CALL SORMBR( 'P', 'R', 'T', N, N, N, A, LDA,
      $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
             ELSE IF( WNTQA ) THEN
 *
+*              Path 5a (M >= N, JOBZ='A')
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in U and computing right singular
 *              vectors of bidiagonal matrix in VT
-*              (Workspace: need N+BDSPAC)
+*              Workspace: need   3*N [e, tauq, taup] + BDSPAC
 *
                CALL SLASET( 'F', M, M, ZERO, ZERO, U, LDU )
                CALL SBDSDC( 'U', 'I', N, S, WORK( IE ), U, LDU, VT,
 *              Set the right corner of U to identity matrix
 *
                IF( M.GT.N ) THEN
-                  CALL SLASET( 'F', M-N, M-N, ZERO, ONE, U( N+1, N+1 ),
+                  CALL SLASET( 'F', M - N, M - N, ZERO, ONE, U(N+1,N+1),
      $                         LDU )
                END IF
 *
 *              Overwrite U by left singular vectors of A and VT
 *              by right singular vectors of A
-*              (Workspace: need N*N+2*N+M, prefer N*N+2*N+M*NB)
+*              Workspace: need   3*N [e, tauq, taup] + M    [work]
+*              Workspace: prefer 3*N [e, tauq, taup] + M*NB [work]
 *
                CALL SORMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
      $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
                CALL SORMBR( 'P', 'R', 'T', N, N, M, A, LDA,
      $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
             END IF
 *
          END IF
 *
             IF( WNTQN ) THEN
 *
-*              Path 1t (N much larger than M, JOBZ='N')
+*              Path 1t (N >> M, JOBZ='N')
 *              No singular vectors to be computed
 *
                ITAU = 1
                NWORK = ITAU + M
 *
 *              Compute A=L*Q
-*              (Workspace: need 2*M, prefer M+M*NB)
+*              Workspace: need   M [tau] + M [work]
+*              Workspace: prefer M [tau] + M*NB [work]
 *
                CALL SGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
 *              Zero out above L
 *
                NWORK = ITAUP + M
 *
 *              Bidiagonalize L in A
-*              (Workspace: need 4*M, prefer 3*M+2*M*NB)
+*              Workspace: need   3*M [e, tauq, taup] + M      [work]
+*              Workspace: prefer 3*M [e, tauq, taup] + 2*M*NB [work]
 *
                CALL SGEBRD( M, M, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
      $                      WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
                NWORK = IE + M
 *
 *              Perform bidiagonal SVD, computing singular values only
-*              (Workspace: need M+BDSPAC)
+*              Workspace: need   M [e] + BDSPAC
 *
                CALL SBDSDC( 'U', 'N', M, S, WORK( IE ), DUM, 1, DUM, 1,
      $                      DUM, IDUM, WORK( NWORK ), IWORK, INFO )
 *
             ELSE IF( WNTQO ) THEN
 *
-*              Path 2t (N much larger than M, JOBZ='O')
+*              Path 2t (N >> M, JOBZ='O')
 *              M right singular vectors to be overwritten on A and
 *              M left singular vectors to be computed in U
 *
                IVT = 1
 *
-*              IVT is M by M
+*              WORK(IVT) is M by M
+*              WORK(IL)  is M by M; it is later resized to M by chunk for gemm
 *
                IL = IVT + M*M
-               IF( LWORK.GE.M*N+M*M+3*M+BDSPAC ) THEN
-*
-*                 WORK(IL) is M by N
-*
+               IF( LWORK .GE. M*N + M*M + 3*M + BDSPAC ) THEN
                   LDWRKL = M
                   CHUNK = N
                ELSE
                   LDWRKL = M
-                  CHUNK = ( LWORK-M*M ) / M
+                  CHUNK = ( LWORK - M*M ) / M
                END IF
                ITAU = IL + LDWRKL*M
                NWORK = ITAU + M
 *
 *              Compute A=L*Q
-*              (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*              Workspace: need   M*M [VT] + M*M [L] + M [tau] + M    [work]
+*              Workspace: prefer M*M [VT] + M*M [L] + M [tau] + M*NB [work]
 *
                CALL SGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
 *              Copy L to WORK(IL), zeroing about above it
 *
                CALL SLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWRKL )
-               CALL SLASET( 'U', M-1, M-1, ZERO, ZERO,
-     $                      WORK( IL+LDWRKL ), LDWRKL )
+               CALL SLASET( 'U', M - 1, M - 1, ZERO, ZERO,
+     $                      WORK( IL + LDWRKL ), LDWRKL )
 *
 *              Generate Q in A
-*              (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*              Workspace: need   M*M [VT] + M*M [L] + M [tau] + M    [work]
+*              Workspace: prefer M*M [VT] + M*M [L] + M [tau] + M*NB [work]
 *
                CALL SORGLQ( M, N, M, A, LDA, WORK( ITAU ),
-     $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
+     $                      WORK( NWORK ), LWORK - NWORK + 1, IERR )
                IE = ITAU
                ITAUQ = IE + M
                ITAUP = ITAUQ + M
                NWORK = ITAUP + M
 *
 *              Bidiagonalize L in WORK(IL)
-*              (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
+*              Workspace: need   M*M [VT] + M*M [L] + 3*M [e, tauq, taup] + M      [work]
+*              Workspace: prefer M*M [VT] + M*M [L] + 3*M [e, tauq, taup] + 2*M*NB [work]
 *
                CALL SGEBRD( M, M, WORK( IL ), LDWRKL, S, WORK( IE ),
      $                      WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in U, and computing right singular
 *              vectors of bidiagonal matrix in WORK(IVT)
-*              (Workspace: need M+M*M+BDSPAC)
+*              Workspace: need   M*M [VT] + M*M [L] + 3*M [e, tauq, taup] + BDSPAC
 *
                CALL SBDSDC( 'U', 'I', M, S, WORK( IE ), U, LDU,
      $                      WORK( IVT ), M, DUM, IDUM, WORK( NWORK ),
 *
 *              Overwrite U by left singular vectors of L and WORK(IVT)
 *              by right singular vectors of L
-*              (Workspace: need 2*M*M+3*M, prefer 2*M*M+2*M+M*NB)
+*              Workspace: need   M*M [VT] + M*M [L] + 3*M [e, tauq, taup] + M    [work]
+*              Workspace: prefer M*M [VT] + M*M [L] + 3*M [e, tauq, taup] + M*NB [work]
 *
                CALL SORMBR( 'Q', 'L', 'N', M, M, M, WORK( IL ), LDWRKL,
      $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
                CALL SORMBR( 'P', 'R', 'T', M, M, M, WORK( IL ), LDWRKL,
      $                      WORK( ITAUP ), WORK( IVT ), M,
-     $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
+     $                      WORK( NWORK ), LWORK - NWORK + 1, IERR )
 *
 *              Multiply right singular vectors of L in WORK(IVT) by Q
 *              in A, storing result in WORK(IL) and copying to A
-*              (Workspace: need 2*M*M, prefer M*M+M*N)
+*              Workspace: need   M*M [VT] + M*M [L]
+*              Workspace: prefer M*M [VT] + M*N [L]
+*              At this point, L is resized as M by chunk.
 *
                DO 30 I = 1, N, CHUNK
-                  BLK = MIN( N-I+1, CHUNK )
+                  BLK = MIN( N - I + 1, CHUNK )
                   CALL SGEMM( 'N', 'N', M, BLK, M, ONE, WORK( IVT ), M,
      $                        A( 1, I ), LDA, ZERO, WORK( IL ), LDWRKL )
                   CALL SLACPY( 'F', M, BLK, WORK( IL ), LDWRKL,
 *
             ELSE IF( WNTQS ) THEN
 *
-*              Path 3t (N much larger than M, JOBZ='S')
+*              Path 3t (N >> M, JOBZ='S')
 *              M right singular vectors to be computed in VT and
 *              M left singular vectors to be computed in U
 *
                NWORK = ITAU + M
 *
 *              Compute A=L*Q
-*              (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*              Workspace: need   M*M [L] + M [tau] + M    [work]
+*              Workspace: prefer M*M [L] + M [tau] + M*NB [work]
 *
                CALL SGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
 *              Copy L to WORK(IL), zeroing out above it
 *
                CALL SLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWRKL )
-               CALL SLASET( 'U', M-1, M-1, ZERO, ZERO,
-     $                      WORK( IL+LDWRKL ), LDWRKL )
+               CALL SLASET( 'U', M - 1, M - 1, ZERO, ZERO,
+     $                      WORK( IL + LDWRKL ), LDWRKL )
 *
 *              Generate Q in A
-*              (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*              Workspace: need   M*M [L] + M [tau] + M    [work]
+*              Workspace: prefer M*M [L] + M [tau] + M*NB [work]
 *
                CALL SORGLQ( M, N, M, A, LDA, WORK( ITAU ),
-     $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
+     $                      WORK( NWORK ), LWORK - NWORK + 1, IERR )
                IE = ITAU
                ITAUQ = IE + M
                ITAUP = ITAUQ + M
                NWORK = ITAUP + M
 *
-*              Bidiagonalize L in WORK(IU), copying result to U
-*              (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
+*              Bidiagonalize L in WORK(IU).
+*              Workspace: need   M*M [L] + 3*M [e, tauq, taup] + M      [work]
+*              Workspace: prefer M*M [L] + 3*M [e, tauq, taup] + 2*M*NB [work]
 *
                CALL SGEBRD( M, M, WORK( IL ), LDWRKL, S, WORK( IE ),
      $                      WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in U and computing right singular
 *              vectors of bidiagonal matrix in VT
-*              (Workspace: need M+BDSPAC)
+*              Workspace: need   M*M [L] + 3*M [e, tauq, taup] + BDSPAC
 *
                CALL SBDSDC( 'U', 'I', M, S, WORK( IE ), U, LDU, VT,
      $                      LDVT, DUM, IDUM, WORK( NWORK ), IWORK,
 *
 *              Overwrite U by left singular vectors of L and VT
 *              by right singular vectors of L
-*              (Workspace: need M*M+3*M, prefer M*M+2*M+M*NB)
+*              Workspace: need   M*M [L] + 3*M [e, tauq, taup] + M    [work]
+*              Workspace: prefer M*M [L] + 3*M [e, tauq, taup] + M*NB [work]
 *
                CALL SORMBR( 'Q', 'L', 'N', M, M, M, WORK( IL ), LDWRKL,
      $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
                CALL SORMBR( 'P', 'R', 'T', M, M, M, WORK( IL ), LDWRKL,
      $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
 *              Multiply right singular vectors of L in WORK(IL) by
 *              Q in A, storing result in VT
-*              (Workspace: need M*M)
+*              Workspace: need   M*M [L]
 *
                CALL SLACPY( 'F', M, M, VT, LDVT, WORK( IL ), LDWRKL )
                CALL SGEMM( 'N', 'N', M, N, M, ONE, WORK( IL ), LDWRKL,
 *
             ELSE IF( WNTQA ) THEN
 *
-*              Path 4t (N much larger than M, JOBZ='A')
+*              Path 4t (N >> M, JOBZ='A')
 *              N right singular vectors to be computed in VT and
 *              M left singular vectors to be computed in U
 *
                NWORK = ITAU + M
 *
 *              Compute A=L*Q, copying result to VT
-*              (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*              Workspace: need   M*M [VT] + M [tau] + M    [work]
+*              Workspace: prefer M*M [VT] + M [tau] + M*NB [work]
 *
                CALL SGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
                CALL SLACPY( 'U', M, N, A, LDA, VT, LDVT )
 *
 *              Generate Q in VT
-*              (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*              Workspace: need   M*M [VT] + M [tau] + N    [work]
+*              Workspace: prefer M*M [VT] + M [tau] + N*NB [work]
 *
                CALL SORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
-     $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
+     $                      WORK( NWORK ), LWORK - NWORK + 1, IERR )
 *
 *              Produce L in A, zeroing out other entries
 *
                NWORK = ITAUP + M
 *
 *              Bidiagonalize L in A
-*              (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
+*              Workspace: need   M*M [VT] + 3*M [e, tauq, taup] + M      [work]
+*              Workspace: prefer M*M [VT] + 3*M [e, tauq, taup] + 2*M*NB [work]
 *
                CALL SGEBRD( M, M, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
      $                      WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in U and computing right singular
 *              vectors of bidiagonal matrix in WORK(IVT)
-*              (Workspace: need M+M*M+BDSPAC)
+*              Workspace: need   M*M [VT] + 3*M [e, tauq, taup] + BDSPAC
 *
                CALL SBDSDC( 'U', 'I', M, S, WORK( IE ), U, LDU,
      $                      WORK( IVT ), LDWKVT, DUM, IDUM,
 *
 *              Overwrite U by left singular vectors of L and WORK(IVT)
 *              by right singular vectors of L
-*              (Workspace: need M*M+3*M, prefer M*M+2*M+M*NB)
+*              Workspace: need   M*M [VT] + 3*M [e, tauq, taup]+ M    [work]
+*              Workspace: prefer M*M [VT] + 3*M [e, tauq, taup]+ M*NB [work]
 *
                CALL SORMBR( 'Q', 'L', 'N', M, M, M, A, LDA,
      $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
                CALL SORMBR( 'P', 'R', 'T', M, M, M, A, LDA,
      $                      WORK( ITAUP ), WORK( IVT ), LDWKVT,
-     $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
+     $                      WORK( NWORK ), LWORK - NWORK + 1, IERR )
 *
 *              Multiply right singular vectors of L in WORK(IVT) by
 *              Q in VT, storing result in A
-*              (Workspace: need M*M)
+*              Workspace: need   M*M [VT]
 *
                CALL SGEMM( 'N', 'N', M, N, M, ONE, WORK( IVT ), LDWKVT,
      $                     VT, LDVT, ZERO, A, LDA )
 *
 *           N .LT. MNTHR
 *
-*           Path 5t (N greater than M, but not much larger)
+*           Path 5t (N > M, but not much larger)
 *           Reduce to bidiagonal form without LQ decomposition
 *
             IE = 1
             NWORK = ITAUP + M
 *
 *           Bidiagonalize A
-*           (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB)
+*           Workspace: need   3*M [e, tauq, taup] + N        [work]
+*           Workspace: prefer 3*M [e, tauq, taup] + (M+N)*NB [work]
 *
             CALL SGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
      $                   WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
      $                   IERR )
             IF( WNTQN ) THEN
 *
+*              Path 5tn (N > M, JOBZ='N')
 *              Perform bidiagonal SVD, only computing singular values
-*              (Workspace: need M+BDSPAC)
+*              Workspace: need   3*M [e, tauq, taup] + BDSPAC
 *
                CALL SBDSDC( 'L', 'N', M, S, WORK( IE ), DUM, 1, DUM, 1,
      $                      DUM, IDUM, WORK( NWORK ), IWORK, INFO )
             ELSE IF( WNTQO ) THEN
+*              Path 5to (N > M, JOBZ='O')
                LDWKVT = M
                IVT = NWORK
-               IF( LWORK.GE.M*N+3*M+BDSPAC ) THEN
+               IF( LWORK .GE. M*N + 3*M + BDSPAC ) THEN
 *
 *                 WORK( IVT ) is M by N
 *
                   CALL SLASET( 'F', M, N, ZERO, ZERO, WORK( IVT ),
      $                         LDWKVT )
                   NWORK = IVT + LDWKVT*N
+*                 IL is unused; silence compile warnings
+                  IL = -1
                ELSE
 *
 *                 WORK( IVT ) is M by M
 *
 *                 WORK(IL) is M by CHUNK
 *
-                  CHUNK = ( LWORK-M*M-3*M ) / M
+                  CHUNK = ( LWORK - M*M - 3*M ) / M
                END IF
 *
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in U and computing right singular
 *              vectors of bidiagonal matrix in WORK(IVT)
-*              (Workspace: need M*M+BDSPAC)
+*              Workspace: need   3*M [e, tauq, taup] + M*M [VT] + BDSPAC
 *
                CALL SBDSDC( 'L', 'I', M, S, WORK( IE ), U, LDU,
      $                      WORK( IVT ), LDWKVT, DUM, IDUM,
      $                      WORK( NWORK ), IWORK, INFO )
 *
 *              Overwrite U by left singular vectors of A
-*              (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*              Workspace: need   3*M [e, tauq, taup] + M*M [VT] + M    [work]
+*              Workspace: prefer 3*M [e, tauq, taup] + M*M [VT] + M*NB [work]
 *
                CALL SORMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
      $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
 *
-               IF( LWORK.GE.M*N+3*M+BDSPAC ) THEN
+               IF( LWORK .GE. M*N + 3*M + BDSPAC ) THEN
 *
+*                 Path 5to-fast
 *                 Overwrite WORK(IVT) by left singular vectors of A
-*                 (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                 Workspace: need   3*M [e, tauq, taup] + M*N [VT] + M    [work]
+*                 Workspace: prefer 3*M [e, tauq, taup] + M*N [VT] + M*NB [work]
 *
                   CALL SORMBR( 'P', 'R', 'T', M, N, M, A, LDA,
      $                         WORK( ITAUP ), WORK( IVT ), LDWKVT,
-     $                         WORK( NWORK ), LWORK-NWORK+1, IERR )
+     $                         WORK( NWORK ), LWORK - NWORK + 1, IERR )
 *
 *                 Copy right singular vectors of A from WORK(IVT) to A
 *
                   CALL SLACPY( 'F', M, N, WORK( IVT ), LDWKVT, A, LDA )
                ELSE
 *
+*                 Path 5to-slow
 *                 Generate P**T in A
-*                 (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
+*                 Workspace: need   3*M [e, tauq, taup] + M*M [VT] + M    [work]
+*                 Workspace: prefer 3*M [e, tauq, taup] + M*M [VT] + M*NB [work]
 *
                   CALL SORGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
-     $                         WORK( NWORK ), LWORK-NWORK+1, IERR )
+     $                         WORK( NWORK ), LWORK - NWORK + 1, IERR )
 *
 *                 Multiply Q in A by right singular vectors of
 *                 bidiagonal matrix in WORK(IVT), storing result in
 *                 WORK(IL) and copying to A
-*                 (Workspace: need 2*M*M, prefer M*M+M*N)
+*                 Workspace: need   3*M [e, tauq, taup] + M*M [VT] + M*NB [L]
+*                 Workspace: prefer 3*M [e, tauq, taup] + M*M [VT] + M*N  [L]
 *
                   DO 40 I = 1, N, CHUNK
-                     BLK = MIN( N-I+1, CHUNK )
+                     BLK = MIN( N - I + 1, CHUNK )
                      CALL SGEMM( 'N', 'N', M, BLK, M, ONE, WORK( IVT ),
      $                           LDWKVT, A( 1, I ), LDA, ZERO,
      $                           WORK( IL ), M )
                END IF
             ELSE IF( WNTQS ) THEN
 *
+*              Path 5ts (N > M, JOBZ='S')
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in U and computing right singular
 *              vectors of bidiagonal matrix in VT
-*              (Workspace: need M+BDSPAC)
+*              Workspace: need   3*M [e, tauq, taup] + BDSPAC
 *
                CALL SLASET( 'F', M, N, ZERO, ZERO, VT, LDVT )
                CALL SBDSDC( 'L', 'I', M, S, WORK( IE ), U, LDU, VT,
 *
 *              Overwrite U by left singular vectors of A and VT
 *              by right singular vectors of A
-*              (Workspace: need 3*M, prefer 2*M+M*NB)
+*              Workspace: need   3*M [e, tauq, taup] + M    [work]
+*              Workspace: prefer 3*M [e, tauq, taup] + M*NB [work]
 *
                CALL SORMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
      $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
                CALL SORMBR( 'P', 'R', 'T', M, N, M, A, LDA,
      $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
             ELSE IF( WNTQA ) THEN
 *
+*              Path 5ta (N > M, JOBZ='A')
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in U and computing right singular
 *              vectors of bidiagonal matrix in VT
-*              (Workspace: need M+BDSPAC)
+*              Workspace: need   3*M [e, tauq, taup] + BDSPAC
 *
                CALL SLASET( 'F', N, N, ZERO, ZERO, VT, LDVT )
                CALL SBDSDC( 'L', 'I', M, S, WORK( IE ), U, LDU, VT,
 *              Set the right corner of VT to identity matrix
 *
                IF( N.GT.M ) THEN
-                  CALL SLASET( 'F', N-M, N-M, ZERO, ONE, VT( M+1, M+1 ),
+                  CALL SLASET( 'F', N-M, N-M, ZERO, ONE, VT(M+1,M+1),
      $                         LDVT )
                END IF
 *
 *              Overwrite U by left singular vectors of A and VT
 *              by right singular vectors of A
-*              (Workspace: need 2*M+N, prefer 2*M+N*NB)
+*              Workspace: need   3*M [e, tauq, taup] + N    [work]
+*              Workspace: prefer 3*M [e, tauq, taup] + N*NB [work]
 *
                CALL SORMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
      $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
                CALL SORMBR( 'P', 'R', 'T', N, N, M, A, LDA,
      $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
-     $                      LWORK-NWORK+1, IERR )
+     $                      LWORK - NWORK + 1, IERR )
             END IF
 *
          END IF
index 263548b077e3f2fec93f85b882a56be9b6d883a6..4e37528ba8ce1348c8c6e779504e7690f21f1dba 100644 (file)
       SUBROUTINE SGESVD( JOBU, JOBVT, M, N, A, LDA, S, U, LDU, VT, LDVT,
      $                   WORK, LWORK, INFO )
 *
-*  -- LAPACK driver routine (version 3.4.1) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     April 2012
             BDSPAC = 5*N
 *           Compute space needed for SGEQRF
             CALL SGEQRF( M, N, A, LDA, DUM(1), DUM(1), -1, IERR )
-            LWORK_SGEQRF=DUM(1)
+            LWORK_SGEQRF = INT( DUM(1) )
 *           Compute space needed for SORGQR
             CALL SORGQR( M, N, N, A, LDA, DUM(1), DUM(1), -1, IERR )
-            LWORK_SORGQR_N=DUM(1)
+            LWORK_SORGQR_N = INT( DUM(1) )
             CALL SORGQR( M, M, N, A, LDA, DUM(1), DUM(1), -1, IERR )
-            LWORK_SORGQR_M=DUM(1)
+            LWORK_SORGQR_M = INT( DUM(1) )
 *           Compute space needed for SGEBRD
             CALL SGEBRD( N, N, A, LDA, S, DUM(1), DUM(1),
      $                   DUM(1), DUM(1), -1, IERR )
-            LWORK_SGEBRD=DUM(1)
+            LWORK_SGEBRD = INT( DUM(1) )
 *           Compute space needed for SORGBR P
             CALL SORGBR( 'P', N, N, N, A, LDA, DUM(1),
      $                   DUM(1), -1, IERR )
-            LWORK_SORGBR_P=DUM(1)
+            LWORK_SORGBR_P = INT( DUM(1) )
 *           Compute space needed for SORGBR Q
             CALL SORGBR( 'Q', N, N, N, A, LDA, DUM(1),
      $                   DUM(1), -1, IERR )
-            LWORK_SORGBR_Q=DUM(1)
+            LWORK_SORGBR_Q = INT( DUM(1) )
 *
             IF( M.GE.MNTHR ) THEN
                IF( WNTUN ) THEN
 *
                CALL SGEBRD( M, N, A, LDA, S, DUM(1), DUM(1),
      $                   DUM(1), DUM(1), -1, IERR )
-               LWORK_SGEBRD=DUM(1)
+               LWORK_SGEBRD = INT( DUM(1) )
                MAXWRK = 3*N + LWORK_SGEBRD
                IF( WNTUS .OR. WNTUO ) THEN
                   CALL SORGBR( 'Q', M, N, N, A, LDA, DUM(1),
      $                   DUM(1), -1, IERR )
-                  LWORK_SORGBR_Q=DUM(1)
+                  LWORK_SORGBR_Q = INT( DUM(1) )
                   MAXWRK = MAX( MAXWRK, 3*N+LWORK_SORGBR_Q )
                END IF
                IF( WNTUA ) THEN
                   CALL SORGBR( 'Q', M, M, N, A, LDA, DUM(1),
      $                   DUM(1), -1, IERR )
-                  LWORK_SORGBR_Q=DUM(1)
+                  LWORK_SORGBR_Q = INT( DUM(1) )
                   MAXWRK = MAX( MAXWRK, 3*N+LWORK_SORGBR_Q )
                END IF
                IF( .NOT.WNTVN ) THEN
             BDSPAC = 5*M
 *           Compute space needed for SGELQF
             CALL SGELQF( M, N, A, LDA, DUM(1), DUM(1), -1, IERR )
-            LWORK_SGELQF=DUM(1)
+            LWORK_SGELQF = INT( DUM(1) )
 *           Compute space needed for SORGLQ
             CALL SORGLQ( N, N, M, DUM(1), N, DUM(1), DUM(1), -1, IERR )
-            LWORK_SORGLQ_N=DUM(1)
+            LWORK_SORGLQ_N = INT( DUM(1) )
             CALL SORGLQ( M, N, M, A, LDA, DUM(1), DUM(1), -1, IERR )
-            LWORK_SORGLQ_M=DUM(1)
+            LWORK_SORGLQ_M = INT( DUM(1) )
 *           Compute space needed for SGEBRD
             CALL SGEBRD( M, M, A, LDA, S, DUM(1), DUM(1),
      $                   DUM(1), DUM(1), -1, IERR )
-            LWORK_SGEBRD=DUM(1)
+            LWORK_SGEBRD = INT( DUM(1) )
 *            Compute space needed for SORGBR P
             CALL SORGBR( 'P', M, M, M, A, N, DUM(1),
      $                   DUM(1), -1, IERR )
-            LWORK_SORGBR_P=DUM(1)
+            LWORK_SORGBR_P = INT( DUM(1) )
 *           Compute space needed for SORGBR Q
             CALL SORGBR( 'Q', M, M, M, A, N, DUM(1),
      $                   DUM(1), -1, IERR )
-            LWORK_SORGBR_Q=DUM(1)
+            LWORK_SORGBR_Q = INT( DUM(1) )
             IF( N.GE.MNTHR ) THEN
                IF( WNTVN ) THEN
 *
 *
                CALL SGEBRD( M, N, A, LDA, S, DUM(1), DUM(1),
      $                   DUM(1), DUM(1), -1, IERR )
-               LWORK_SGEBRD=DUM(1)
+               LWORK_SGEBRD = INT( DUM(1) )
                MAXWRK = 3*M + LWORK_SGEBRD
                IF( WNTVS .OR. WNTVO ) THEN
 *                Compute space needed for SORGBR P
                  CALL SORGBR( 'P', M, N, M, A, N, DUM(1),
      $                   DUM(1), -1, IERR )
-                 LWORK_SORGBR_P=DUM(1)
+                 LWORK_SORGBR_P = INT( DUM(1) )
                  MAXWRK = MAX( MAXWRK, 3*M+LWORK_SORGBR_P )
                END IF
                IF( WNTVA ) THEN
                  CALL SORGBR( 'P', N, N, M, A, N, DUM(1),
      $                   DUM(1), -1, IERR )
-                 LWORK_SORGBR_P=DUM(1)
+                 LWORK_SORGBR_P = INT( DUM(1) )
                  MAXWRK = MAX( MAXWRK, 3*M+LWORK_SORGBR_P )
                END IF
                IF( .NOT.WNTUN ) THEN
 *
 *              Zero out below R
 *
-               CALL SLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ), LDA )
+               IF( N .GT. 1 ) THEN
+                  CALL SLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),
+     $                         LDA )
+               END IF
                IE = 1
                ITAUQ = IE + N
                ITAUP = ITAUQ + N
 *
 *                    Zero out below R in A
 *
-                     CALL SLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),
-     $                            LDA )
+                     IF( N .GT. 1 ) THEN
+                        CALL SLASET( 'L', N-1, N-1, ZERO, ZERO,
+     $                               A( 2, 1 ), LDA )
+                     END IF
 *
 *                    Bidiagonalize R in A
 *                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
 *
 *                    Zero out below R in A
 *
-                     CALL SLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),
-     $                            LDA )
+                     IF( N .GT. 1 ) THEN
+                        CALL SLASET( 'L', N-1, N-1, ZERO, ZERO,
+     $                               A( 2, 1 ), LDA )
+                     END IF
 *
 *                    Bidiagonalize R in A
 *                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
 *
 *                    Zero out below R in A
 *
-                     CALL SLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),
-     $                            LDA )
+                     IF( N .GT. 1 ) THEN
+                        CALL SLASET( 'L', N-1, N-1, ZERO, ZERO,
+     $                               A( 2, 1 ), LDA )
+                     END IF
 *
 *                    Bidiagonalize R in A
 *                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
 *
 *                    Zero out below R in A
 *
-                     CALL SLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),
-     $                            LDA )
+                     IF( N .GT. 1 ) THEN
+                        CALL SLASET( 'L', N-1, N-1, ZERO, ZERO,
+     $                               A( 2, 1 ), LDA )
+                     END IF
 *
 *                    Bidiagonalize R in A
 *                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
index aae8b07640da1a64d607f06cc2ea3a2b278a1dea..8a2fc9b0cf6701b7b223d610a986230f30667aa6 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is REAL
-*>          VL >=0.
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for singular values. VU > VL.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is REAL
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for singular values. VU > VL.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest singular value to be returned.
+*>          1 <= IL <= IU <= min(M,N), if min(M,N) > 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest singular values to be returned.
+*>          If RANGE='I', the index of the
+*>          largest singular value to be returned.
 *>          1 <= IL <= IU <= min(M,N), if min(M,N) > 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>          vectors, stored columnwise) as specified by RANGE; if 
 *>          JOBU = 'N', U is not referenced.
 *>          Note: The user must ensure that UCOL >= NS; if RANGE = 'V', 
-*>          the exact value of NS is not known ILQFin advance and an upper 
+*>          the exact value of NS is not known in advance and an upper
 *>          bound must be used.
 *> \endverbatim
 *>
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup realGEsing
 *
      $                    IL, IU, NS, S, U, LDU, VT, LDVT, WORK, 
      $                    LWORK, IWORK, INFO )
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBU, JOBVT, RANGE
          IF( INFO.EQ.0 ) THEN
             IF( WANTU .AND. LDU.LT.M ) THEN
                INFO = -15
-            ELSE IF( WANTVT .AND. LDVT.LT.MINMN ) THEN
-               INFO = -16
+            ELSE IF( WANTVT ) THEN
+               IF( INDS ) THEN
+                   IF( LDVT.LT.IU-IL+1 ) THEN
+                       INFO = -17
+                   END IF
+               ELSE IF( LDVT.LT.MINMN ) THEN
+                   INFO = -17
+               END IF
             END IF
          END IF
       END IF
 *
 *                 Path 1 (M much larger than N)
 *
-                  MAXWRK = N*(N*2+16) + 
+                  MAXWRK = N + 
      $                     N*ILAENV( 1, 'SGEQRF', ' ', M, N, -1, -1 )
-                  MAXWRK = MAX( MAXWRK, N*(N*2+20) + 2*N*
+                  MAXWRK = MAX( MAXWRK, N*(N+5) + 2*N*
      $                     ILAENV( 1, 'SGEBRD', ' ', N, N, -1, -1 ) )
-                  MINWRK = N*(N*2+21)
+                  IF (WANTU) THEN
+                      MAXWRK = MAX(MAXWRK,N*(N*3+6)+N*
+     $                     ILAENV( 1, 'SORMQR', ' ', N, N, -1, -1 ) )
+                  END IF
+                  IF (WANTVT) THEN
+                      MAXWRK = MAX(MAXWRK,N*(N*3+6)+N*
+     $                     ILAENV( 1, 'SORMLQ', ' ', N, N, -1, -1 ) )
+                  END IF
+                  MINWRK = N*(N*3+20)
                ELSE
 *
 *                 Path 2 (M at least N, but not much larger)
 *
-                  MAXWRK = N*(N*2+19) + ( M+N )*
+                  MAXWRK = 4*N + ( M+N )*
      $                     ILAENV( 1, 'SGEBRD', ' ', M, N, -1, -1 )
-                  MINWRK = N*(N*2+20) + M
+                  IF (WANTU) THEN
+                      MAXWRK = MAX(MAXWRK,N*(N*2+5)+N*
+     $                     ILAENV( 1, 'SORMQR', ' ', N, N, -1, -1 ) )
+                  END IF
+                  IF (WANTVT) THEN
+                      MAXWRK = MAX(MAXWRK,N*(N*2+5)+N*
+     $                     ILAENV( 1, 'SORMLQ', ' ', N, N, -1, -1 ) )
+                  END IF
+                  MINWRK = MAX(N*(N*2+19),4*N+M)
                END IF
             ELSE
                MNTHR = ILAENV( 6, 'SGESVD', JOBU // JOBVT, M, N, 0, 0 )
 *
 *                 Path 1t (N much larger than M)
 *
-                  MAXWRK = M*(M*2+16) + 
+                  MAXWRK = M + 
      $                     M*ILAENV( 1, 'SGELQF', ' ', M, N, -1, -1 )
-                  MAXWRK = MAX( MAXWRK, M*(M*2+20) + 2*M*
+                  MAXWRK = MAX( MAXWRK, M*(M+5) + 2*M*
      $                     ILAENV( 1, 'SGEBRD', ' ', M, M, -1, -1 ) )
-                  MINWRK = M*(M*2+21)
+                  IF (WANTU) THEN
+                      MAXWRK = MAX(MAXWRK,M*(M*3+6)+M*
+     $                     ILAENV( 1, 'SORMQR', ' ', M, M, -1, -1 ) )
+                  END IF
+                  IF (WANTVT) THEN
+                      MAXWRK = MAX(MAXWRK,M*(M*3+6)+M*
+     $                     ILAENV( 1, 'SORMLQ', ' ', M, M, -1, -1 ) )
+                  END IF
+                  MINWRK = M*(M*3+20)
                ELSE
 *
-*                 Path 2t (N greater than M, but not much larger)
+*                 Path 2t (N at least M, but not much larger)
 *
-                  MAXWRK = M*(M*2+19) + ( M+N )*
+                  MAXWRK = 4*M + ( M+N )*
      $                     ILAENV( 1, 'SGEBRD', ' ', M, N, -1, -1 )
-                  MINWRK = M*(M*2+20) + N
+                  IF (WANTU) THEN
+                      MAXWRK = MAX(MAXWRK,M*(M*2+5)+M*
+     $                     ILAENV( 1, 'SORMQR', ' ', M, M, -1, -1 ) )
+                  END IF
+                  IF (WANTVT) THEN
+                      MAXWRK = MAX(MAXWRK,M*(M*2+5)+M*
+     $                     ILAENV( 1, 'SORMLQ', ' ', M, M, -1, -1 ) )
+                  END IF
+                  MINWRK = MAX(M*(M*2+19),4*M+N)
                END IF
             END IF
          END IF
                   CALL SCOPY( N, WORK( J ), 1, U( 1,I ), 1 )
                   J = J + N*2
                END DO
-               CALL SLASET( 'A', M-N, N, ZERO, ZERO, U( N+1,1 ), LDU )
+               CALL SLASET( 'A', M-N, NS, ZERO, ZERO, U( N+1,1 ), LDU )
 *
 *              Call SORMBR to compute QB*UB.
 *              (Workspace in WORK( ITEMP ): need N, prefer N*NB)
                   CALL SCOPY( N, WORK( J ), 1, U( 1,I ), 1 )
                   J = J + N*2
                END DO
-               CALL SLASET( 'A', M-N, N, ZERO, ZERO, U( N+1,1 ), LDU )
+               CALL SLASET( 'A', M-N, NS, ZERO, ZERO, U( N+1,1 ), LDU )
 *
 *              Call SORMBR to compute QB*UB.
 *              (Workspace in WORK( ITEMP ): need N, prefer N*NB)
                   CALL SCOPY( M, WORK( J ), 1, VT( I,1 ), LDVT )
                   J = J + M*2
                END DO
-               CALL SLASET( 'A', M, N-M, ZERO, ZERO, VT( 1,M+1 ), LDVT )
+               CALL SLASET( 'A', NS, N-M, ZERO, ZERO, VT( 1,M+1 ), LDVT)
 *
 *              Call SORMBR to compute (VB**T)*(PB**T)
 *              (Workspace in WORK( ITEMP ): need M, prefer M*NB)
                   CALL SCOPY( M, WORK( J ), 1, VT( I,1 ), LDVT )
                   J = J + M*2
                END DO
-               CALL SLASET( 'A', M, N-M, ZERO, ZERO, VT( 1,M+1 ), LDVT )
+               CALL SLASET( 'A', NS, N-M, ZERO, ZERO, VT( 1,M+1 ), LDVT)
 *
 *              Call SORMBR to compute VB**T * PB**T
 *              (Workspace in WORK( ITEMP ): need M, prefer M*NB)
index 5984465195c4a0ba0faa90314426af420abc8f91..ce6a5b3927870acd63261e83a62222178ade17ec 100644 (file)
@@ -98,7 +98,7 @@
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2013
+*> \date June 2016
 *
 *> \ingroup realGEauxiliary
 *
 *  =====================================================================
       SUBROUTINE SGETC2( N, A, LDA, IPIV, JPIV, INFO )
 *
-*  -- LAPACK auxiliary routine (version 3.5.0) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2013
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            INFO, LDA, N
index 068710b779a1c246520352d51358938ffd2e482f..02b6c345484626c0bcfd2de897736ae6ebe8b1cd 100644 (file)
@@ -37,7 +37,7 @@
 *> 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)
+*>    A = [ -----|----- ]  with n1 = min(m,n)/2
 *         [  A21 | A22  ]       n2 = n-n1
 *>            
 *>                                       [ A11 ]
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup realGEcomputational
 *
 *  =====================================================================
       RECURSIVE SUBROUTINE SGETRF2( M, N, A, LDA, IPIV, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            INFO, LDA, M, N
index 3c58aea786350a4fcad683b9d525aa816d0eee80..758f4b5c7d13c8729b8e621d3e67f4688ea99345 100644 (file)
       SUBROUTINE SGGHD3( COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB, Q,
      $                   LDQ, Z, LDZ, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     January 2015
 *
       INFO = 0
       NB = ILAENV( 1, 'SGGHD3', ' ', N, ILO, IHI, -1 )
-      LWKOPT = 6*N*NB
+      LWKOPT = MAX( 6*N*NB, 1 )
       WORK( 1 ) = REAL( LWKOPT )
       INITQ = LSAME( COMPQ, 'I' )
       WANTQ = INITQ .OR. LSAME( COMPQ, 'V' )
index f54962462b9ec32607a20eaf4d00281ac506e04a..595afab13ff68484faa37df1fe95cb23610ccc1f 100644 (file)
 *>
 *> \param[out] WORK
 *> \verbatim
-*>          WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))
+*>          WORK is REAL array, dimension (MAX(1,LWORK))
 *>          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
 *> \endverbatim
 *>
      $                    TOLA, TOLB, K, L, U, LDU, V, LDV, Q, LDQ,
      $                    IWORK, TAU, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     August 2015
index 254e65fcf7512880bad8ff04ad8777f4f6cd4f30..6d55c5563e803118ccddbc92029a26f233cf358a 100644 (file)
 *> \param[in,out] Q
 *> \verbatim
 *>          Q is REAL array, dimension (LDQ, N)
-*>          On entry, if COMPZ = 'V', the orthogonal matrix Q1 used in
+*>          On entry, if COMPQ = 'V', the orthogonal matrix Q1 used in
 *>          the reduction of (A,B) to generalized Hessenberg form.
-*>          On exit, if COMPZ = 'I', the orthogonal matrix of left Schur
-*>          vectors of (H,T), and if COMPZ = 'V', the orthogonal matrix
+*>          On exit, if COMPQ = 'I', the orthogonal matrix of left Schur
+*>          vectors of (H,T), and if COMPQ = 'V', the orthogonal matrix
 *>          of left Schur vectors of (A,B).
-*>          Not referenced if COMPZ = 'N'.
+*>          Not referenced if COMPQ = 'N'.
 *> \endverbatim
 *>
 *> \param[in] LDQ
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2013
+*> \date June 2016
 *
 *> \ingroup realGEcomputational
 *
      $                   ALPHAR, ALPHAI, BETA, Q, LDQ, Z, LDZ, WORK,
      $                   LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.5.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2013
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          COMPQ, COMPZ, JOB
index 74eeb6330bae71137b231865fa5d82af7b1eba9b..c6f52d0fdf3c443b7aae55c9feb7a803f9c68cb0 100644 (file)
@@ -54,7 +54,7 @@
 *>
 *>       The first stage consists of deflating the size of the problem
 *>       when there are multiple eigenvalues or if there is a zero in
-*>       the Z vector.  For each such occurence the dimension of the
+*>       the Z vector.  For each such occurrence the dimension of the
 *>       secular equation problem is reduced by one.  This stage is
 *>       performed by the routine SLAED2.
 *>
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup auxOTHERcomputational
 *
       SUBROUTINE SLAED1( N, D, Q, LDQ, INDXQ, RHO, CUTPNT, WORK, IWORK,
      $                   INFO )
 *
-*  -- LAPACK computational routine (version 3.4.2) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            CUTPNT, INFO, LDQ, N
index 3d3d629286297e10a448b9693794f9c9ed985f23..f6615e039e1445ff87f0e54dcddb31e83c536e92 100644 (file)
@@ -59,7 +59,7 @@
 *>
 *>       The first stage consists of deflating the size of the problem
 *>       when there are multiple eigenvalues or if there is a zero in
-*>       the Z vector.  For each such occurence the dimension of the
+*>       the Z vector.  For each such occurrence the dimension of the
 *>       secular equation problem is reduced by one.  This stage is
 *>       performed by the routine SLAED8.
 *>
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup auxOTHERcomputational
 *
      $                   PERM, GIVPTR, GIVCOL, GIVNUM, WORK, IWORK,
      $                   INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            CURLVL, CURPBM, CUTPNT, ICOMPQ, INFO, LDQ, N,
index ad04333a081a7df2d99e44faf82fc0c481f26c45..da18f6b2311df31fdc60239c98d917954826a20e 100644 (file)
@@ -99,7 +99,7 @@
 *>          will always be positive.  If the eigenvalues are real, then
 *>          the first (real) eigenvalue is  WR1 / SCALE1 , but this may
 *>          overflow or underflow, and in fact, SCALE1 may be zero or
-*>          less than the underflow threshhold if the exact eigenvalue
+*>          less than the underflow threshold if the exact eigenvalue
 *>          is sufficiently large.
 *> \endverbatim
 *>
 *>          eigenvalues are real, then the second (real) eigenvalue is
 *>          WR2 / SCALE2 , but this may overflow or underflow, and in
 *>          fact, SCALE2 may be zero or less than the underflow
-*>          threshhold if the exact eigenvalue is sufficiently large.
+*>          threshold if the exact eigenvalue is sufficiently large.
 *> \endverbatim
 *>
 *> \param[out] WR1
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup realOTHERauxiliary
 *
       SUBROUTINE SLAG2( A, LDA, B, LDB, SAFMIN, SCALE1, SCALE2, WR1,
      $                  WR2, WI )
 *
-*  -- LAPACK auxiliary routine (version 3.4.2) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            LDA, LDB
 *     Note: the test of R in the following IF is to cover the case when
 *           DISCR is small and negative and is flushed to zero during
 *           the calculation of R.  On machines which have a consistent
-*           flush-to-zero threshhold and handle numbers above that
-*           threshhold correctly, it would not be necessary.
+*           flush-to-zero threshold and handle numbers above that
+*           threshold correctly, it would not be necessary.
 *
       IF( DISCR.GE.ZERO .OR. R.EQ.ZERO ) THEN
          SUM = PP + SIGN( R, PP )
index 6229abd6a83d55fb8762af816ec7dd2e384ca331..7f171cbe92bf4b772d7d53cdacfd9d0e8d000475 100644 (file)
@@ -50,7 +50,7 @@
 *> \param[in] N2
 *> \verbatim
 *>          N2 is INTEGER
-*>         These arguements contain the respective lengths of the two
+*>         These arguments contain the respective lengths of the two
 *>         sorted lists to be merged.
 *> \endverbatim
 *>
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup auxOTHERcomputational
 *
 *  =====================================================================
       SUBROUTINE SLAMRG( N1, N2, A, STRD1, STRD2, INDEX )
 *
-*  -- LAPACK computational routine (version 3.4.2) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            N1, N2, STRD1, STRD2
index 150febd433b6b3bee2952ed8b737d602ffa40e4a..b80b27af5088c57b6c5d5984c677f946340e0fbc 100644 (file)
 *>          Z is REAL array, dimension (LDZ,N)
 *>          IF WANTZ is .TRUE., then on output, the orthogonal
 *>          similarity transformation mentioned above has been
-*>          accumulated into Z(ILOZ:IHIZ,ILO:IHI) from the right.
+*>          accumulated into Z(ILOZ:IHIZ,ILOZ:IHIZ) from the right.
 *>          If WANTZ is .FALSE., then Z is unreferenced.
 *> \endverbatim
 *>
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup realOTHERauxiliary
 *
      $                   IHIZ, Z, LDZ, NS, ND, SR, SI, V, LDV, NH, T,
      $                   LDT, NV, WV, LDWV, WORK, LWORK )
 *
-*  -- LAPACK auxiliary routine (version 3.4.2) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            IHIZ, ILOZ, KBOT, KTOP, LDH, LDT, LDV, LDWV,
index 6a29974178558c0e391c95f2d277b521f8a4fd7b..d9ed7922df936017abae2f302273e13cee138956 100644 (file)
 *>
 *> \param[in,out] Z
 *> \verbatim
-*>          Z is REAL array of size (LDZ,IHI)
+*>          Z is REAL array of size (LDZ,IHIZ)
 *>             If WANTZ = .TRUE., then the QR Sweep orthogonal
 *>             similarity transformation is accumulated into
-*>             Z(ILOZ:IHIZ,ILO:IHI) from the right.
+*>             Z(ILOZ:IHIZ,ILOZ:IHIZ) from the right.
 *>             If WANTZ = .FALSE., then Z is unreferenced.
 *> \endverbatim
 *>
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup realOTHERauxiliary
 *
      $                   SR, SI, H, LDH, ILOZ, IHIZ, Z, LDZ, V, LDV, U,
      $                   LDU, NV, WV, LDWV, NH, WH, LDWH )
 *
-*  -- LAPACK auxiliary routine (version 3.4.2) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            IHIZ, ILOZ, KACC22, KBOT, KTOP, LDH, LDU, LDV,
index 7812ca5537fe13290958dad0c28ad9a2e1971883..ec9c252c21e295aa2399caf610019c1660d442c6 100644 (file)
 *>
 *> \param[in] VL
 *> \verbatim
-*>          VL is DOUBLE PRECISION
+*>          VL is REAL
+*>          The lower bound for the eigenvalues.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
-*>          VU is DOUBLE PRECISION
-*>          The lower and upper bounds for the eigenvalues.
+*>          VU is REAL
+*>          The upper bound for the eigenvalues.
 *> \endverbatim
 *>
 *> \param[in] D
 *> \verbatim
-*>          D is DOUBLE PRECISION array, dimension (N)
+*>          D is REAL array, dimension (N)
 *>          JOBT = 'T': The N diagonal elements of the tridiagonal matrix T.
 *>          JOBT = 'L': The N diagonal elements of the diagonal matrix D.
 *> \endverbatim
 *>
 *> \param[in] E
 *> \verbatim
-*>          E is DOUBLE PRECISION array, dimension (N)
+*>          E is REAL array, dimension (N)
 *>          JOBT = 'T': The N-1 offdiagonal elements of the matrix T.
 *>          JOBT = 'L': The N-1 offdiagonal elements of the matrix L.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup auxOTHERauxiliary
 *
       SUBROUTINE SLARRC( JOBT, N, VL, VU, D, E, PIVMIN,
      $                            EIGCNT, LCNT, RCNT, INFO )
 *
-*  -- LAPACK auxiliary routine (version 3.4.2) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBT
index 7d17210c3338cc415510c07cc061c664a6ea6702..5ac428e2a25ecfd7be184acc380423b357e225ec 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is REAL
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues.  Eigenvalues less than or equal
+*>          to VL, or greater than VU, will not be returned.  VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is REAL
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues.  Eigenvalues less than or equal
 *>          to VL, or greater than VU, will not be returned.  VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup auxOTHERauxiliary
 *
      $                    M, W, WERR, WL, WU, IBLOCK, INDEXW,
      $                    WORK, IWORK, INFO )
 *
-*  -- LAPACK auxiliary routine (version 3.4.2) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          ORDER, RANGE
index a5b9f2fd69442b1fc0391cf770c4140433182230..bf56986c0c86a1b26a5860f5591660e6ba460178 100644 (file)
 *> \param[in,out] VL
 *> \verbatim
 *>          VL is REAL
+*>          If RANGE='V', the lower bound for the eigenvalues.
+*>          Eigenvalues less than or equal to VL, or greater than VU,
+*>          will not be returned.  VL < VU.
+*>          If RANGE='I' or ='A', SLARRE computes bounds on the desired
+*>          part of the spectrum.
 *> \endverbatim
 *>
 *> \param[in,out] VU
 *> \verbatim
 *>          VU is REAL
-*>          If RANGE='V', the lower and upper bounds for the eigenvalues.
+*>          If RANGE='V', the upper bound for the eigenvalues.
 *>          Eigenvalues less than or equal to VL, or greater than VU,
 *>          will not be returned.  VL < VU.
 *>          If RANGE='I' or ='A', SLARRE computes bounds on the desired
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N.
 *> \endverbatim
 *>
 *> \verbatim
 *>          INFO is INTEGER
 *>          = 0:  successful exit
-*>          > 0:  A problem occured in SLARRE.
+*>          > 0:  A problem occurred in SLARRE.
 *>          < 0:  One of the called subroutines signaled an internal problem.
 *>                Needs inspection of the corresponding parameter IINFO
 *>                for further information.
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup auxOTHERauxiliary
 *
      $                    W, WERR, WGAP, IBLOCK, INDEXW, GERS, PIVMIN,
      $                    WORK, IWORK, INFO )
 *
-*  -- LAPACK auxiliary routine (version 3.4.2) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          RANGE
index 058e5027c286a95b279d68c897e13f272f611240..f686018d1d8dc5c13d5e99fc8bd1c7383e24e298 100644 (file)
@@ -51,7 +51,7 @@
 *> \param[in] N
 *> \verbatim
 *>          N is INTEGER
-*>          The order of the matrix (subblock, if the matrix splitted).
+*>          The order of the matrix (subblock, if the matrix split).
 *> \endverbatim
 *>
 *> \param[in] D
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup auxOTHERauxiliary
 *
      $                   SPDIAM, CLGAPL, CLGAPR, PIVMIN, SIGMA,
      $                   DPLUS, LPLUS, WORK, INFO )
 *
-*  -- LAPACK auxiliary routine (version 3.6.0) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            CLSTRT, CLEND, INFO, N
index 73847f39429baa1071df4ec028a991d3c50896a8..b098c3d11a73cee4650eab66581e66d6b107c4f8 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is REAL
+*>          Lower bound of the interval that contains the desired
+*>          eigenvalues. VL < VU. Needed to compute gaps on the left or right
+*>          end of the extremal eigenvalues in the desired RANGE.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is REAL
-*>          Lower and upper bounds of the interval that contains the desired
+*>          Upper bound of the interval that contains the desired
 *>          eigenvalues. VL < VU. Needed to compute gaps on the left or right
 *>          end of the extremal eigenvalues in the desired RANGE.
 *> \endverbatim
@@ -81,7 +84,7 @@
 *>          L is REAL array, dimension (N)
 *>          On entry, the (N-1) subdiagonal elements of the unit
 *>          bidiagonal matrix L are in elements 1 to N-1 of L
-*>          (if the matrix is not splitted.) At the end of each block
+*>          (if the matrix is not split.) At the end of each block
 *>          is stored the corresponding shift as given by SLARRE.
 *>          On exit, L is overwritten.
 *> \endverbatim
 *>          INFO is INTEGER
 *>          = 0:  successful exit
 *>
-*>          > 0:  A problem occured in SLARRV.
+*>          > 0:  A problem occurred in SLARRV.
 *>          < 0:  One of the called subroutines signaled an internal problem.
 *>                Needs inspection of the corresponding parameter IINFO
 *>                for further information.
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup realOTHERauxiliary
 *
      $                   IBLOCK, INDEXW, GERS, Z, LDZ, ISUPPZ,
      $                   WORK, IWORK, INFO )
 *
-*  -- LAPACK auxiliary routine (version 3.6.0) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            DOL, DOU, INFO, LDZ, M, N
index df7ede2c8b512201b44598275b859645477711ea..3f51d722d98be551bb17b85e37e5422fd854537c 100644 (file)
@@ -72,7 +72,7 @@
 *> \param[in] LDX
 *> \verbatim
 *>          LDX is INTEGER
-*>     The leading dimension of the vector X. LDX >= 0.
+*>     The leading dimension of the vector X. LDX >= M.
 *> \endverbatim
 *
 *  Authors:
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup realOTHERcomputational
 *
 *  =====================================================================
       SUBROUTINE SLARSCL2 ( M, N, D, X, LDX )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            M, N, LDX
index bacf86ed49a8e984fb358ccad4855bc11750ef9d..d67ea0f09f437c4c457297397c65ea872fc9fef7 100644 (file)
 *> \param[in] LDA
 *> \verbatim
 *>          LDA is INTEGER
-*>          The leading dimension of the array A.  LDA >= max(1,M).
+*>          The leading dimension of the array A.
+*>          If TYPE = 'G', 'L', 'U', 'H', LDA >= max(1,M);
+*>             TYPE = 'B', LDA >= KL+1;
+*>             TYPE = 'Q', LDA >= KU+1;
+*>             TYPE = 'Z', LDA >= 2*KL+KU+1.
 *> \endverbatim
 *>
 *> \param[out] INFO
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup auxOTHERauxiliary
 *
 *  =====================================================================
       SUBROUTINE SLASCL( TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO )
 *
-*  -- LAPACK auxiliary routine (version 3.4.2) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          TYPE
index a44a3c8fddb5ffec80639451529fd8e3b8485084..bb2f960b86d29d3977c92831f8ba3d6a1b6279e2 100644 (file)
@@ -72,7 +72,7 @@
 *> \param[in] LDX
 *> \verbatim
 *>          LDX is INTEGER
-*>     The leading dimension of the vector X. LDX >= 0.
+*>     The leading dimension of the vector X. LDX >= M.
 *> \endverbatim
 *
 *  Authors:
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup realOTHERcomputational
 *
 *  =====================================================================
       SUBROUTINE SLASCL2 ( M, N, D, X, LDX )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            M, N, LDX
index ae076a0f505e047262d3a782aba15bfd6cc9cb89..63d878be562ca349f5c9ba518e999d81462a1e54 100644 (file)
@@ -60,7 +60,7 @@
 *>
 *>    The first stage consists of deflating the size of the problem
 *>    when there are multiple singular values or when there are zeros in
-*>    the Z vector.  For each such occurence the dimension of the
+*>    the Z vector.  For each such occurrence the dimension of the
 *>    secular equation problem is reduced by one.  This stage is
 *>    performed by the routine SLASD2.
 *>
 *>         The leading dimension of the array VT.  LDVT >= max( 1, M ).
 *> \endverbatim
 *>
-*> \param[out] IDXQ
+*> \param[in,out] IDXQ
 *> \verbatim
 *>          IDXQ is INTEGER array, dimension (N)
 *>         This contains the permutation which will reintegrate the
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup auxOTHERauxiliary
 *
       SUBROUTINE SLASD1( NL, NR, SQRE, D, ALPHA, BETA, U, LDU, VT, LDVT,
      $                   IDXQ, IWORK, WORK, INFO )
 *
-*  -- LAPACK auxiliary routine (version 3.6.0) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            INFO, LDU, LDVT, NL, NR, SQRE
index f79a06d03f1c224de094e00867120f8a6050e162..9f31e6ccf4ed4f534a8c3ceebcf630bd86a426ee 100644 (file)
@@ -74,7 +74,7 @@
 *>
 *>       The first stage consists of deflating the size of the problem
 *>       when there are multiple singular values or if there is a zero
-*>       in the Z vector. For each such occurence the dimension of the
+*>       in the Z vector. For each such occurrence the dimension of the
 *>       secular equation problem is reduced by one. This stage is
 *>       performed by the routine SLASD7.
 *>
 *> \param[out] DIFR
 *> \verbatim
 *>          DIFR is REAL array,
-*>                  dimension ( LDGNUM, 2 ) if ICOMPQ = 1 and
-*>                  dimension ( N ) if ICOMPQ = 0.
-*>         On exit, DIFR(I, 1) is the distance between I-th updated
-*>         (undeflated) singular value and the I+1-th (undeflated) old
-*>         singular value.
+*>                   dimension ( LDDIFR, 2 ) if ICOMPQ = 1 and
+*>                   dimension ( K ) if ICOMPQ = 0.
+*>          On exit, DIFR(I,1) = D(I) - DSIGMA(I+1), DIFR(K,1) is not
+*>          defined and will not be referenced.
 *>
-*>         If ICOMPQ = 1, DIFR(1:K,2) is an array containing the
-*>         normalizing factors for the right singular vector matrix.
+*>          If ICOMPQ = 1, DIFR(1:K,2) is an array containing the
+*>          normalizing factors for the right singular vector matrix.
 *>
 *>         See SLASD8 for details on DIFL and DIFR.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup auxOTHERauxiliary
 *
      $                   LDGNUM, POLES, DIFL, DIFR, Z, K, C, S, WORK,
      $                   IWORK, INFO )
 *
-*  -- LAPACK auxiliary routine (version 3.6.0) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            GIVPTR, ICOMPQ, INFO, K, LDGCOL, LDGNUM, NL,
index 289ed855c09df55bcb28bf0906d0c61fd0460d63..7b72fb98fb790dcee67efd560801a01bc83dd32e 100644 (file)
@@ -59,7 +59,7 @@
 *> \verbatim
 *>          UPLO is CHARACTER*1
 *>        On entry, UPLO specifies whether the input bidiagonal matrix
-*>        is upper or lower bidiagonal, and wether it is square are
+*>        is upper or lower bidiagonal, and whether it is square are
 *>        not.
 *>           UPLO = 'U' or 'u'   B is upper bidiagonal.
 *>           UPLO = 'L' or 'l'   B is lower bidiagonal.
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup auxOTHERauxiliary
 *
       SUBROUTINE SLASDQ( UPLO, SQRE, N, NCVT, NRU, NCC, D, E, VT, LDVT,
      $                   U, LDU, C, LDC, WORK, INFO )
 *
-*  -- LAPACK auxiliary routine (version 3.4.2) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          UPLO
index 4187a943e9e7324a26d4b2d31db3da62d99ff9ac..879fdfbbd06ce7bc90c9303ea1ac0b9f6e8cf720 100644 (file)
@@ -60,7 +60,7 @@
 *>
 *> \param[in,out] Z
 *> \verbatim
-*>          Z is REAL array, dimension ( 4*N )
+*>          Z is REAL array, dimension ( 4*N0 )
 *>         Z holds the qd array.
 *> \endverbatim
 *>
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup auxOTHERcomputational
 *
      $                   ITER, NDIV, IEEE, TTYPE, DMIN1, DMIN2, DN, DN1,
      $                   DN2, G, TAU )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       LOGICAL            IEEE
index bdd24f32c97c53729f2725c739f168c52c6e9141..1ad5a91185c01b33abd897f0d17ecfafb0d76f61 100644 (file)
@@ -56,7 +56,7 @@
 *>
 *> \param[in] Z
 *> \verbatim
-*>          Z is REAL array, dimension ( 4*N )
+*>          Z is REAL array, dimension ( 4*N0 )
 *>        Z holds the qd array.
 *> \endverbatim
 *>
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup auxOTHERcomputational
 *
       SUBROUTINE SLASQ4( I0, N0, Z, PP, N0IN, DMIN, DMIN1, DMIN2, DN,
      $                   DN1, DN2, TAU, TTYPE, G )
 *
-*  -- LAPACK computational routine (version 3.4.2) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            I0, N0, N0IN, PP, TTYPE
index e93c0d6db1fb26972f37faae3909cf1e4ba024aa..d3aa129218207492565c90660ddcb21ebf159c42 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup auxOTHERcomputational
 *
 *  =====================================================================
       SUBROUTINE SLASRT( ID, N, D, INFO )
 *
-*  -- LAPACK computational routine (version 3.4.2) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          ID
 *     ..
 *     .. Executable Statements ..
 *
-*     Test the input paramters.
+*     Test the input parameters.
 *
       INFO = 0
       DIR = -1
index 5684a119f28c44655a0a40fa27ff5fe074200494..ed34a823ea247c23310b291ffeaffaf08721f329 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup realSYauxiliary
 *
       SUBROUTINE SLASY2( LTRANL, LTRANR, ISGN, N1, N2, TL, LDTL, TR,
      $                   LDTR, B, LDB, SCALE, X, LDX, XNORM, INFO )
 *
-*  -- LAPACK auxiliary routine (version 3.4.2) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       LOGICAL            LTRANL, LTRANR
    80       CONTINUE
    90    CONTINUE
   100 CONTINUE
-      IF( ABS( T16( 4, 4 ) ).LT.SMIN )
-     $   T16( 4, 4 ) = SMIN
+      IF( ABS( T16( 4, 4 ) ).LT.SMIN ) THEN
+         INFO = 1
+         T16( 4, 4 ) = SMIN
+      END IF
       SCALE = ONE
       IF( ( EIGHT*SMLNUM )*ABS( BTMP( 1 ) ).GT.ABS( T16( 1, 1 ) ) .OR.
      $    ( EIGHT*SMLNUM )*ABS( BTMP( 2 ) ).GT.ABS( T16( 2, 2 ) ) .OR.
index 51773d4e5cb7a0970418231dca43f2415082dc43..dc5e2b74947f3c9a80566c814347349bffc4dd56 100644 (file)
@@ -58,7 +58,7 @@
 *>              Zx = +-e - f with the sign giving the greater value
 *>              of 2-norm(x). About 5 times as expensive as Default.
 *>          IJOB .ne. 2: Local look ahead strategy where all entries of
-*>              the r.h.s. b is choosen as either +1 or -1 (Default).
+*>              the r.h.s. b is chosen as either +1 or -1 (Default).
 *> \endverbatim
 *>
 *> \param[in] N
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup realOTHERauxiliary
 *
       SUBROUTINE SLATDF( IJOB, N, Z, LDZ, RHS, RDSUM, RDSCAL, IPIV,
      $                   JPIV )
 *
-*  -- LAPACK auxiliary routine (version 3.4.2) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            IJOB, LDZ, N
index b1f5f4628c32100b4ef53fcd8bc14b0dd1f452bc..a8c2e96bd6bb7cc13bf333c86f1e967b5361d73e 100644 (file)
       SUBROUTINE SORBDB1( M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI,
      $                    TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.5.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     July 2012
      $                  X11(I+1,I+1), LDX11, WORK(ILARF) )
             CALL SLARF( 'R', M-P-I, Q-I, X21(I,I+1), LDX21, TAUQ1(I),
      $                  X21(I+1,I+1), LDX21, WORK(ILARF) )
-            C = SQRT( SNRM2( P-I, X11(I+1,I+1), 1, X11(I+1,I+1),
-     $          1 )**2 + SNRM2( M-P-I, X21(I+1,I+1), 1, X21(I+1,I+1),
-     $          1 )**2 )
+            C = SQRT( SNRM2( P-I, X11(I+1,I+1), 1 )**2
+     $              + SNRM2( M-P-I, X21(I+1,I+1), 1 )**2 )
             PHI(I) = ATAN2( S, C )
             CALL SORBDB5( P-I, M-P-I, Q-I-1, X11(I+1,I+1), 1,
      $                    X21(I+1,I+1), 1, X11(I+1,I+2), LDX11,
index 582540e34b9ad2c32832949f228034b94efd5a64..c9919a174ecd5d8fabdd594cf5bc48f345887fe6 100644 (file)
       SUBROUTINE SORBDB2( M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI,
      $                    TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.5.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     July 2012
      $               X11(I+1,I), LDX11, WORK(ILARF) )
          CALL SLARF( 'R', M-P-I+1, Q-I+1, X11(I,I), LDX11, TAUQ1(I),
      $               X21(I,I), LDX21, WORK(ILARF) )
-         S = SQRT( SNRM2( P-I, X11(I+1,I), 1, X11(I+1,I),
-     $       1 )**2 + SNRM2( M-P-I+1, X21(I,I), 1, X21(I,I), 1 )**2 )
+         S = SQRT( SNRM2( P-I, X11(I+1,I), 1 )**2
+     $           + SNRM2( M-P-I+1, X21(I,I), 1 )**2 )
          THETA(I) = ATAN2( S, C )
 *
          CALL SORBDB5( P-I, M-P-I+1, Q-I, X11(I+1,I), 1, X21(I,I), 1,
index ea52f4db3fea1b2be5e5a7eabaa506e18fdc40ca..8ce74d40790cb7896bf675809782084d4487c425 100644 (file)
       SUBROUTINE SORBDB3( M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI,
      $                    TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.5.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     July 2012
      $               X11(I,I), LDX11, WORK(ILARF) )
          CALL SLARF( 'R', M-P-I, Q-I+1, X21(I,I), LDX21, TAUQ1(I),
      $               X21(I+1,I), LDX21, WORK(ILARF) )
-         C = SQRT( SNRM2( P-I+1, X11(I,I), 1, X11(I,I),
-     $       1 )**2 + SNRM2( M-P-I, X21(I+1,I), 1, X21(I+1,I), 1 )**2 )
+         C = SQRT( SNRM2( P-I+1, X11(I,I), 1 )**2
+     $           + SNRM2( M-P-I, X21(I+1,I), 1 )**2 )
          THETA(I) = ATAN2( S, C )
 *
          CALL SORBDB5( P-I+1, M-P-I, Q-I, X11(I,I), 1, X21(I+1,I), 1,
index 9ed16a714e7816e9d9e1ada6b2ca83141d4ad20d..1efe146b16af2154bb55d825a00ed11cd9cb00bc 100644 (file)
      $                    TAUP1, TAUP2, TAUQ1, PHANTOM, WORK, LWORK,
      $                    INFO )
 *
-*  -- LAPACK computational routine (version 3.5.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     July 2012
          CALL SLARF( 'R', M-P-I, Q-I+1, X21(I,I), LDX21, TAUQ1(I),
      $               X21(I+1,I), LDX21, WORK(ILARF) )
          IF( I .LT. M-Q ) THEN
-            S = SQRT( SNRM2( P-I, X11(I+1,I), 1, X11(I+1,I),
-     $          1 )**2 + SNRM2( M-P-I, X21(I+1,I), 1, X21(I+1,I),
-     $          1 )**2 )
+            S = SQRT( SNRM2( P-I, X11(I+1,I), 1 )**2
+     $              + SNRM2( M-P-I, X21(I+1,I), 1 )**2 )
             PHI(I) = ATAN2( S, C )
          END IF
 *
index b2401af190b4b0769e7e080b138606e2006b20e8..3354d091cbb502c434f53f5bb43818da66b7f733 100644 (file)
      $                       X21, LDX21, THETA, U1, LDU1, U2, LDU2, V1T,
      $                       LDV1T, WORK, LWORK, IWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     July 2012
      $                   LWORKMIN, LWORKOPT, R
       LOGICAL            LQUERY, WANTU1, WANTU2, WANTV1T
 *     ..
+*     .. Local Arrays ..
+      REAL               DUM1(1), DUM2(1,1)
+*     ..
 *     .. External Subroutines ..
       EXTERNAL           SBBCSD, SCOPY, SLACPY, SLAPMR, SLAPMT, SORBDB1,
      $                   SORBDB2, SORBDB3, SORBDB4, SORGLQ, SORGQR,
          INFO = -8
       ELSE IF( LDX21 .LT. MAX( 1, M-P ) ) THEN
          INFO = -10
-      ELSE IF( WANTU1 .AND. LDU1 .LT. P ) THEN
+      ELSE IF( WANTU1 .AND. LDU1 .LT. MAX( 1, P ) ) THEN
          INFO = -13
-      ELSE IF( WANTU2 .AND. LDU2 .LT. M - P ) THEN
+      ELSE IF( WANTU2 .AND. LDU2 .LT. MAX( 1, M - P ) ) THEN
          INFO = -15
-      ELSE IF( WANTV1T .AND. LDV1T .LT. Q ) THEN
+      ELSE IF( WANTV1T .AND. LDV1T .LT. MAX( 1, Q ) ) THEN
          INFO = -17
       END IF
 *
          IORBDB = ITAUQ1 + MAX( 1, Q )
          IORGQR = ITAUQ1 + MAX( 1, Q )
          IORGLQ = ITAUQ1 + MAX( 1, Q )
+         LORGQRMIN = 1
+         LORGQROPT = 1
+         LORGLQMIN = 1
+         LORGLQOPT = 1
          IF( R .EQ. Q ) THEN
-            CALL SORBDB1( M, P, Q, X11, LDX11, X21, LDX21, THETA, 0, 0,
-     $                    0, 0, WORK, -1, CHILDINFO )
+            CALL SORBDB1( M, P, Q, X11, LDX11, X21, LDX21, THETA,
+     $                    DUM1, DUM1, DUM1, DUM1, WORK, -1,
+     $                    CHILDINFO )
             LORBDB = INT( WORK(1) )
-            IF( P .GE. M-P ) THEN
-               CALL SORGQR( P, P, Q, U1, LDU1, 0, WORK(1), -1,
+            IF( WANTU1 .AND. P .GT. 0 ) THEN
+               CALL SORGQR( P, P, Q, U1, LDU1, DUM1, WORK(1), -1,
      $                      CHILDINFO )
-               LORGQRMIN = MAX( 1, P )
-               LORGQROPT = INT( WORK(1) )
-            ELSE
-               CALL SORGQR( M-P, M-P, Q, U2, LDU2, 0, WORK(1), -1,
+               LORGQRMIN = MAX( LORGQRMIN, P )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            ENDIF
+            IF( WANTU2 .AND. M-P .GT. 0 ) THEN
+               CALL SORGQR( M-P, M-P, Q, U2, LDU2, DUM1, WORK(1), -1,
      $                      CHILDINFO )
-               LORGQRMIN = MAX( 1, M-P )
-               LORGQROPT = INT( WORK(1) )
+               LORGQRMIN = MAX( LORGQRMIN, M-P )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            END IF
+            IF( WANTV1T .AND. Q .GT. 0 ) THEN
+               CALL SORGLQ( Q-1, Q-1, Q-1, V1T, LDV1T,
+     $                      DUM1, WORK(1), -1, CHILDINFO )
+               LORGLQMIN = MAX( LORGLQMIN, Q-1 )
+               LORGLQOPT = MAX( LORGLQOPT, INT( WORK(1) ) )
             END IF
-            CALL SORGLQ( MAX(0,Q-1), MAX(0,Q-1), MAX(0,Q-1), V1T, LDV1T,
-     $                   0, WORK(1), -1, CHILDINFO )
-            LORGLQMIN = MAX( 1, Q-1 )
-            LORGLQOPT = INT( WORK(1) )
             CALL SBBCSD( JOBU1, JOBU2, JOBV1T, 'N', 'N', M, P, Q, THETA,
-     $                   0, U1, LDU1, U2, LDU2, V1T, LDV1T, 0, 1, 0, 0,
-     $                   0, 0, 0, 0, 0, 0, WORK(1), -1, CHILDINFO )
+     $                   DUM1, U1, LDU1, U2, LDU2, V1T, LDV1T, DUM2,
+     $                   1, DUM1, DUM1, DUM1, DUM1, DUM1,
+     $                   DUM1, DUM1, DUM1, WORK(1), -1, CHILDINFO
+     $                 )
             LBBCSD = INT( WORK(1) )
          ELSE IF( R .EQ. P ) THEN
-            CALL SORBDB2( M, P, Q, X11, LDX11, X21, LDX21, THETA, 0, 0,
-     $                    0, 0, WORK(1), -1, CHILDINFO )
+            CALL SORBDB2( M, P, Q, X11, LDX11, X21, LDX21, THETA,
+     $                    DUM1, DUM1, DUM1, DUM1, WORK(1), -1,
+     $                    CHILDINFO )
             LORBDB = INT( WORK(1) )
-            IF( P-1 .GE. M-P ) THEN
-               CALL SORGQR( P-1, P-1, P-1, U1(2,2), LDU1, 0, WORK(1),
-     $                      -1, CHILDINFO )
-               LORGQRMIN = MAX( 1, P-1 )
-               LORGQROPT = INT( WORK(1) )
-            ELSE
-               CALL SORGQR( M-P, M-P, Q, U2, LDU2, 0, WORK(1), -1,
+            IF( WANTU1 .AND. P .GT. 0 ) THEN
+               CALL SORGQR( P-1, P-1, P-1, U1(2,2), LDU1, DUM1,
+     $                      WORK(1), -1, CHILDINFO )
+               LORGQRMIN = MAX( LORGQRMIN, P-1 )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            END IF
+            IF( WANTU2 .AND. M-P .GT. 0 ) THEN
+               CALL SORGQR( M-P, M-P, Q, U2, LDU2, DUM1, WORK(1), -1,
      $                      CHILDINFO )
-               LORGQRMIN = MAX( 1, M-P )
-               LORGQROPT = INT( WORK(1) )
+               LORGQRMIN = MAX( LORGQRMIN, M-P )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            END IF
+            IF( WANTV1T .AND. Q .GT. 0 ) THEN
+               CALL SORGLQ( Q, Q, R, V1T, LDV1T, DUM1, WORK(1), -1,
+     $                      CHILDINFO )
+               LORGLQMIN = MAX( LORGLQMIN, Q )
+               LORGLQOPT = MAX( LORGLQOPT, INT( WORK(1) ) )
             END IF
-            CALL SORGLQ( Q, Q, R, V1T, LDV1T, 0, WORK(1), -1,
-     $                   CHILDINFO )
-            LORGLQMIN = MAX( 1, Q )
-            LORGLQOPT = INT( WORK(1) )
             CALL SBBCSD( JOBV1T, 'N', JOBU1, JOBU2, 'T', M, Q, P, THETA,
-     $                   0, V1T, LDV1T, 0, 1, U1, LDU1, U2, LDU2, 0, 0,
-     $                   0, 0, 0, 0, 0, 0, WORK(1), -1, CHILDINFO )
+     $                   DUM1, V1T, LDV1T, DUM2, 1, U1, LDU1, U2,
+     $                   LDU2, DUM1, DUM1, DUM1, DUM1, DUM1,
+     $                   DUM1, DUM1, DUM1, WORK(1), -1, CHILDINFO
+     $                 )
             LBBCSD = INT( WORK(1) )
          ELSE IF( R .EQ. M-P ) THEN
-            CALL SORBDB3( M, P, Q, X11, LDX11, X21, LDX21, THETA, 0, 0,
-     $                    0, 0, WORK(1), -1, CHILDINFO )
+            CALL SORBDB3( M, P, Q, X11, LDX11, X21, LDX21, THETA,
+     $                    DUM1, DUM1, DUM1, DUM1, WORK(1), -1,
+     $                    CHILDINFO )
             LORBDB = INT( WORK(1) )
-            IF( P .GE. M-P-1 ) THEN
-               CALL SORGQR( P, P, Q, U1, LDU1, 0, WORK(1), -1,
+            IF( WANTU1 .AND. P .GT. 0 ) THEN
+               CALL SORGQR( P, P, Q, U1, LDU1, DUM1, WORK(1), -1,
      $                      CHILDINFO )
-               LORGQRMIN = MAX( 1, P )
-               LORGQROPT = INT( WORK(1) )
-            ELSE
-               CALL SORGQR( M-P-1, M-P-1, M-P-1, U2(2,2), LDU2, 0,
+               LORGQRMIN = MAX( LORGQRMIN, P )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            END IF
+            IF( WANTU2 .AND. M-P .GT. 0 ) THEN
+               CALL SORGQR( M-P-1, M-P-1, M-P-1, U2(2,2), LDU2, DUM1,
      $                      WORK(1), -1, CHILDINFO )
-               LORGQRMIN = MAX( 1, M-P-1 )
-               LORGQROPT = INT( WORK(1) )
+               LORGQRMIN = MAX( LORGQRMIN, M-P-1 )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            END IF
+            IF( WANTV1T .AND. Q .GT. 0 ) THEN
+               CALL SORGLQ( Q, Q, R, V1T, LDV1T, DUM1, WORK(1), -1,
+     $                      CHILDINFO )
+               LORGLQMIN = MAX( LORGLQMIN, Q )
+               LORGLQOPT = MAX( LORGLQOPT, INT( WORK(1) ) )
             END IF
-            CALL SORGLQ( Q, Q, R, V1T, LDV1T, 0, WORK(1), -1,
-     $                   CHILDINFO )
-            LORGLQMIN = MAX( 1, Q )
-            LORGLQOPT = INT( WORK(1) )
             CALL SBBCSD( 'N', JOBV1T, JOBU2, JOBU1, 'T', M, M-Q, M-P,
-     $                   THETA, 0, 0, 1, V1T, LDV1T, U2, LDU2, U1, LDU1,
-     $                   0, 0, 0, 0, 0, 0, 0, 0, WORK(1), -1,
+     $                   THETA, DUM1, DUM2, 1, V1T, LDV1T, U2, LDU2,
+     $                   U1, LDU1, DUM1, DUM1, DUM1, DUM1,
+     $                   DUM1, DUM1, DUM1, DUM1, WORK(1), -1,
      $                   CHILDINFO )
             LBBCSD = INT( WORK(1) )
          ELSE
-            CALL SORBDB4( M, P, Q, X11, LDX11, X21, LDX21, THETA, 0, 0,
-     $                    0, 0, 0, WORK(1), -1, CHILDINFO )
+            CALL SORBDB4( M, P, Q, X11, LDX11, X21, LDX21, THETA,
+     $                    DUM1, DUM1, DUM1, DUM1, DUM1,
+     $                    WORK(1), -1, CHILDINFO )
             LORBDB = M + INT( WORK(1) )
-            IF( P .GE. M-P ) THEN
-               CALL SORGQR( P, P, M-Q, U1, LDU1, 0, WORK(1), -1,
+            IF( WANTU1 .AND. P .GT. 0 ) THEN
+               CALL SORGQR( P, P, M-Q, U1, LDU1, DUM1, WORK(1), -1,
      $                      CHILDINFO )
-               LORGQRMIN = MAX( 1, P )
-               LORGQROPT = INT( WORK(1) )
-            ELSE
-               CALL SORGQR( M-P, M-P, M-Q, U2, LDU2, 0, WORK(1), -1,
+               LORGQRMIN = MAX( LORGQRMIN, P )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            END IF
+            IF( WANTU2 .AND. M-P .GT. 0 ) THEN
+               CALL SORGQR( M-P, M-P, M-Q, U2, LDU2, DUM1, WORK(1),
+     $                      -1, CHILDINFO )
+               LORGQRMIN = MAX( LORGQRMIN, M-P )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            END IF
+            IF( WANTV1T .AND. Q .GT. 0 ) THEN
+               CALL SORGLQ( Q, Q, Q, V1T, LDV1T, DUM1, WORK(1), -1,
      $                      CHILDINFO )
-               LORGQRMIN = MAX( 1, M-P )
-               LORGQROPT = INT( WORK(1) )
+               LORGLQMIN = MAX( LORGLQMIN, Q )
+               LORGLQOPT = MAX( LORGLQOPT, INT( WORK(1) ) )
             END IF
-            CALL SORGLQ( Q, Q, Q, V1T, LDV1T, 0, WORK(1), -1,
-     $                   CHILDINFO )
-            LORGLQMIN = MAX( 1, Q )
-            LORGLQOPT = INT( WORK(1) )
             CALL SBBCSD( JOBU2, JOBU1, 'N', JOBV1T, 'N', M, M-P, M-Q,
-     $                   THETA, 0, U2, LDU2, U1, LDU1, 0, 1, V1T, LDV1T,
-     $                   0, 0, 0, 0, 0, 0, 0, 0, WORK(1), -1,
+     $                   THETA, DUM1, U2, LDU2, U1, LDU1, DUM2, 1,
+     $                   V1T, LDV1T, DUM1, DUM1, DUM1, DUM1,
+     $                   DUM1, DUM1, DUM1, DUM1, WORK(1), -1,
      $                   CHILDINFO )
             LBBCSD = INT( WORK(1) )
          END IF
 *        Simultaneously diagonalize X11 and X21.
 *   
          CALL SBBCSD( JOBU1, JOBU2, JOBV1T, 'N', 'N', M, P, Q, THETA,
-     $                WORK(IPHI), U1, LDU1, U2, LDU2, V1T, LDV1T, 0, 1,
-     $                WORK(IB11D), WORK(IB11E), WORK(IB12D),
+     $                WORK(IPHI), U1, LDU1, U2, LDU2, V1T, LDV1T,
+     $                DUM2, 1, WORK(IB11D), WORK(IB11E), WORK(IB12D),
      $                WORK(IB12E), WORK(IB21D), WORK(IB21E),
      $                WORK(IB22D), WORK(IB22E), WORK(IBBCSD), LBBCSD,
      $                CHILDINFO )
 *        Simultaneously diagonalize X11 and X21.
 *   
          CALL SBBCSD( JOBV1T, 'N', JOBU1, JOBU2, 'T', M, Q, P, THETA,
-     $                WORK(IPHI), V1T, LDV1T, 0, 1, U1, LDU1, U2, LDU2,
-     $                WORK(IB11D), WORK(IB11E), WORK(IB12D),
+     $                WORK(IPHI), V1T, LDV1T, DUM1, 1, U1, LDU1, U2,
+     $                LDU2, WORK(IB11D), WORK(IB11E), WORK(IB12D),
      $                WORK(IB12E), WORK(IB21D), WORK(IB21E),
      $                WORK(IB22D), WORK(IB22E), WORK(IBBCSD), LBBCSD,
      $                CHILDINFO )
 *        Simultaneously diagonalize X11 and X21.
 *   
          CALL SBBCSD( 'N', JOBV1T, JOBU2, JOBU1, 'T', M, M-Q, M-P,
-     $                THETA, WORK(IPHI), 0, 1, V1T, LDV1T, U2, LDU2, U1,
-     $                LDU1, WORK(IB11D), WORK(IB11E), WORK(IB12D),
-     $                WORK(IB12E), WORK(IB21D), WORK(IB21E),
-     $                WORK(IB22D), WORK(IB22E), WORK(IBBCSD), LBBCSD,
-     $                CHILDINFO )
+     $                THETA, WORK(IPHI), DUM1, 1, V1T, LDV1T, U2,
+     $                LDU2, U1, LDU1, WORK(IB11D), WORK(IB11E),
+     $                WORK(IB12D), WORK(IB12E), WORK(IB21D),
+     $                WORK(IB21E), WORK(IB22D), WORK(IB22E),
+     $                WORK(IBBCSD), LBBCSD, CHILDINFO )
 *   
 *        Permute rows and columns to place identity submatrices in
 *        preferred positions
 *        Simultaneously diagonalize X11 and X21.
 *   
          CALL SBBCSD( JOBU2, JOBU1, 'N', JOBV1T, 'N', M, M-P, M-Q,
-     $                THETA, WORK(IPHI), U2, LDU2, U1, LDU1, 0, 1, V1T,
-     $                LDV1T, WORK(IB11D), WORK(IB11E), WORK(IB12D),
+     $                THETA, WORK(IPHI), U2, LDU2, U1, LDU1, DUM1, 1,
+     $                V1T, LDV1T, WORK(IB11D), WORK(IB11E), WORK(IB12D),
      $                WORK(IB12E), WORK(IB21D), WORK(IB21E),
      $                WORK(IB22D), WORK(IB22E), WORK(IBBCSD), LBBCSD,
      $                CHILDINFO )
index 0fa1ac45f66de9989293e5256d9f1f05426e1c5f..a03c4a4157f49cf83926460b9fc34190c92fd584 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is REAL
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is REAL
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup realOTHEReigen
 *
      $                   VU, IL, IU, ABSTOL, M, W, Z, LDZ, WORK, IWORK,
      $                   IFAIL, INFO )
 *
-*  -- LAPACK driver routine (version 3.4.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE, UPLO
index b0d48ae93b23489cf41ad07d516798cb7fc90c78..fac2baadc0f37a036a75a380eea389b59fc984b6 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup realOTHEReigen
 *
       SUBROUTINE SSBGVD( JOBZ, UPLO, N, KA, KB, AB, LDAB, BB, LDBB, W,
      $                   Z, LDZ, WORK, LWORK, IWORK, LIWORK, INFO )
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, UPLO
       INDWK2 = INDWRK + N*N
       LLWRK2 = LWORK - INDWK2 + 1
       CALL SSBGST( JOBZ, UPLO, N, KA, KB, AB, LDAB, BB, LDBB, Z, LDZ,
-     $             WORK( INDWRK ), IINFO )
+     $             WORK, IINFO )
 *
 *     Reduce to tridiagonal form.
 *
index b35a7b323b61098be75179f1de0f96f86b24d1fa..2b27f023f680daf3d2a220ffe22c9819eb7676b1 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is REAL
+*>
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is REAL
 *>
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
 *>
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup realOTHEReigen
 *
      $                   LDBB, Q, LDQ, VL, VU, IL, IU, ABSTOL, M, W, Z,
      $                   LDZ, WORK, IWORK, IFAIL, INFO )
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE, UPLO
index 565aedf31937f747037471fbe89864a0b56d55a9..c2bbaf717edae88073754441f85bb970c83ab182 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is REAL
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is REAL
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup realOTHEReigen
 *
      $                   ABSTOL, M, W, Z, LDZ, WORK, IWORK, IFAIL,
      $                   INFO )
 *
-*  -- LAPACK driver routine (version 3.4.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE, UPLO
index c95139a62be7773a0c2c843f2ced4a3392f5ed3b..8f8ed9a8f6fc872240fed3a30b67a7fed2e94289 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is REAL
+*>
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is REAL
 *>
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
 *>
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup realOTHEReigen
 *
      $                   IL, IU, ABSTOL, M, W, Z, LDZ, WORK, IWORK,
      $                   IFAIL, INFO )
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE, UPLO
index c5263651aaa80930572d76cf3441b81290eae912..1e231ec89af1ab297b340d1ff5977f9517673684 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is REAL
+*>
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues.  Eigenvalues less than or equal
+*>          to VL, or greater than VU, will not be returned.  VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is REAL
 *>
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues.  Eigenvalues less than or equal
 *>          to VL, or greater than VU, will not be returned.  VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
 *>
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup auxOTHERcomputational
 *
      $                   M, NSPLIT, W, IBLOCK, ISPLIT, WORK, IWORK,
      $                   INFO )
 *
-*  -- LAPACK computational routine (version 3.4.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          ORDER, RANGE
index d98c451feffdfb470e1e5bcbfdee80c59c4407bf..4c8350e6b9d8425fe56c6c00bf6cda77d4b7e8e5 100644 (file)
@@ -48,7 +48,7 @@
 *> either an interval (VL,VU] or a range of indices IL:IU for the desired
 *> eigenvalues.
 *>
-*> SSTEGR is a compatability wrapper around the improved SSTEMR routine.
+*> SSTEGR is a compatibility wrapper around the improved SSTEMR routine.
 *> See SSTEMR for further details.
 *>
 *> One important change is that the ABSTOL parameter no longer provides any
 *> \param[in] VL
 *> \verbatim
 *>          VL is REAL
+*>
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is REAL
 *>
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
 *>
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup realOTHERcomputational
 *
      $           ABSTOL, M, W, Z, LDZ, ISUPPZ, WORK, LWORK, IWORK,
      $           LIWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.4.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE
index 2e995802ec1b928b5b0f6928bcb45257629e9b0f..5ffe96d435de45f96687cfaaa08fc6206e90086d 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is REAL
+*>
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is REAL
 *>
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
 *>
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2013
+*> \date June 2016
 *
 *> \ingroup realOTHERcomputational
 *
      $                   M, W, Z, LDZ, NZC, ISUPPZ, TRYRAC, WORK, LWORK,
      $                   IWORK, LIWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.5.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2013
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE
index e8b52a2210ee469f2c05cd3aeb69f70476c4929d..2dec8695d3f9a36da25b50117f27d00c6381f3c0 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is REAL
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is REAL
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup realOTHEReigen
 *
      $                   M, W, Z, LDZ, ISUPPZ, WORK, LWORK, IWORK,
      $                   LIWORK, INFO )
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE
index 58f86f2e3361218166a2499f750084de197560ce..427ad742bbe5c5315612f3649619c5465d59b943 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is REAL
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is REAL
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup realOTHEReigen
 *
       SUBROUTINE SSTEVX( JOBZ, RANGE, N, D, E, VL, VU, IL, IU, ABSTOL,
      $                   M, W, Z, LDZ, WORK, IWORK, IFAIL, INFO )
 *
-*  -- LAPACK driver routine (version 3.4.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE
index bfe4258c7eeb8b150e3b1a322c78a48676b04b53..7e274b4e6e20b97883695f7931828b6cf14a43e5 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is REAL
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is REAL
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup realSYeigen
 *
      $                   ABSTOL, M, W, Z, LDZ, ISUPPZ, WORK, LWORK,
      $                   IWORK, LIWORK, INFO )
 *
-*  -- LAPACK driver routine (version 3.4.2) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE, UPLO
index cbc8b1d0e1fe32779201e1f7448e3da5d807a512..611f4f243c36ba24606e830bf25f18ab31ec7a38 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is REAL
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is REAL
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup realSYeigen
 *
      $                   ABSTOL, M, W, Z, LDZ, WORK, LWORK, IWORK,
      $                   IFAIL, INFO )
 *
-*  -- LAPACK driver routine (version 3.4.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE, UPLO
index bbe9222018f34dd27496af25298bb6a95e30cc74..8c909946dcb59832a0b4777f2245565f95ef8407 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is REAL
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is REAL
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup realSYeigen
 *
      $                   VL, VU, IL, IU, ABSTOL, M, W, Z, LDZ, WORK,
      $                   LWORK, IWORK, IFAIL, INFO )
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE, UPLO
index 6467be45790c96764f0f5004d6d4191216076884..3281fbe7ff9281a436c7d1ce3ea347a8954cde97 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup realSYcomputational
 *
 *>
 *> \verbatim
 *>
-*>   November 2015, Igor Kozachenko,
+*>   June 2016, Igor Kozachenko,
 *>                  Computer Science Division,
 *>                  University of California, Berkeley
 *>
 *  =====================================================================
       SUBROUTINE SSYTRF_ROOK( UPLO, N, A, LDA, IPIV, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          UPLO
 *        Determine the block size
 *
          NB = ILAENV( 1, 'SSYTRF_ROOK', UPLO, N, -1, -1, -1 )
-         LWKOPT = N*NB
+         LWKOPT = MAX( 1, N*NB )
          WORK( 1 ) = LWKOPT
       END IF
 *
index 90e1d945113d3d0a0ddd3bc691d2df967d8b03bd..13997be31020cc46a18790b3bfe00c974e72577c 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup realOTHERcomputational
 *
      $                   ALPHAR, ALPHAI, BETA, Q, LDQ, Z, LDZ, M, PL,
      $                   PR, DIF, WORK, LWORK, IWORK, LIWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.4.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       LOGICAL            WANTQ, WANTZ
 *
       M = 0
       PAIR = .FALSE.
+      IF( .NOT.LQUERY .OR. IJOB.NE.0 ) THEN
       DO 10 K = 1, N
          IF( PAIR ) THEN
             PAIR = .FALSE.
             END IF
          END IF
    10 CONTINUE
+      END IF
 *
       IF( IJOB.EQ.1 .OR. IJOB.EQ.2 .OR. IJOB.EQ.4 ) THEN
          LWMIN = MAX( 1, 4*N+16, 2*M*(N-M) )
diff --git a/lapack-netlib/SRC/strevc3.f b/lapack-netlib/SRC/strevc3.f
new file mode 100644 (file)
index 0000000..95ac0f6
--- /dev/null
@@ -0,0 +1,1303 @@
+*> \brief \b STREVC3
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at 
+*            http://www.netlib.org/lapack/explore-html/ 
+*
+*> \htmlonly
+*> Download STREVC3 + dependencies 
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/strevc3.f"> 
+*> [TGZ]</a> 
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/strevc3.f"> 
+*> [ZIP]</a> 
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/strevc3.f"> 
+*> [TXT]</a>
+*> \endhtmlonly 
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE STREVC3( SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL,
+*                           VR, LDVR, MM, M, WORK, LWORK, INFO )
+*
+*       .. Scalar Arguments ..
+*       CHARACTER          HOWMNY, SIDE
+*       INTEGER            INFO, LDT, LDVL, LDVR, LWORK, M, MM, N
+*       ..
+*       .. Array Arguments ..
+*       LOGICAL            SELECT( * )
+*       REAL   T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ),
+*      $                   WORK( * )
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> STREVC3 computes some or all of the right and/or left eigenvectors of
+*> a real upper quasi-triangular matrix T.
+*> Matrices of this type are produced by the Schur factorization of
+*> a real general matrix:  A = Q*T*Q**T, as computed by SHSEQR.
+*>
+*> The right eigenvector x and the left eigenvector y of T corresponding
+*> to an eigenvalue w are defined by:
+*>
+*>    T*x = w*x,     (y**T)*T = w*(y**T)
+*>
+*> where y**T denotes the transpose of the vector y.
+*> The eigenvalues are not input to this routine, but are read directly
+*> from the diagonal blocks of T.
+*>
+*> This routine returns the matrices X and/or Y of right and left
+*> eigenvectors of T, or the products Q*X and/or Q*Y, where Q is an
+*> input matrix. If Q is the orthogonal factor that reduces a matrix
+*> A to Schur form T, then Q*X and Q*Y are the matrices of right and
+*> left eigenvectors of A.
+*>
+*> This uses a Level 3 BLAS version of the back transformation.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] SIDE
+*> \verbatim
+*>          SIDE is CHARACTER*1
+*>          = 'R':  compute right eigenvectors only;
+*>          = 'L':  compute left eigenvectors only;
+*>          = 'B':  compute both right and left eigenvectors.
+*> \endverbatim
+*>
+*> \param[in] HOWMNY
+*> \verbatim
+*>          HOWMNY is CHARACTER*1
+*>          = 'A':  compute all right and/or left eigenvectors;
+*>          = 'B':  compute all right and/or left eigenvectors,
+*>                  backtransformed by the matrices in VR and/or VL;
+*>          = 'S':  compute selected right and/or left eigenvectors,
+*>                  as indicated by the logical array SELECT.
+*> \endverbatim
+*>
+*> \param[in,out] SELECT
+*> \verbatim
+*>          SELECT is LOGICAL array, dimension (N)
+*>          If HOWMNY = 'S', SELECT specifies the eigenvectors to be
+*>          computed.
+*>          If w(j) is a real eigenvalue, the corresponding real
+*>          eigenvector is computed if SELECT(j) is .TRUE..
+*>          If w(j) and w(j+1) are the real and imaginary parts of a
+*>          complex eigenvalue, the corresponding complex eigenvector is
+*>          computed if either SELECT(j) or SELECT(j+1) is .TRUE., and
+*>          on exit SELECT(j) is set to .TRUE. and SELECT(j+1) is set to
+*>          .FALSE..
+*>          Not referenced if HOWMNY = 'A' or 'B'.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>          The order of the matrix T. N >= 0.
+*> \endverbatim
+*>
+*> \param[in] T
+*> \verbatim
+*>          T is REAL array, dimension (LDT,N)
+*>          The upper quasi-triangular matrix T in Schur canonical form.
+*> \endverbatim
+*>
+*> \param[in] LDT
+*> \verbatim
+*>          LDT is INTEGER
+*>          The leading dimension of the array T. LDT >= max(1,N).
+*> \endverbatim
+*>
+*> \param[in,out] VL
+*> \verbatim
+*>          VL is REAL array, dimension (LDVL,MM)
+*>          On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL must
+*>          contain an N-by-N matrix Q (usually the orthogonal matrix Q
+*>          of Schur vectors returned by SHSEQR).
+*>          On exit, if SIDE = 'L' or 'B', VL contains:
+*>          if HOWMNY = 'A', the matrix Y of left eigenvectors of T;
+*>          if HOWMNY = 'B', the matrix Q*Y;
+*>          if HOWMNY = 'S', the left eigenvectors of T specified by
+*>                           SELECT, stored consecutively in the columns
+*>                           of VL, in the same order as their
+*>                           eigenvalues.
+*>          A complex eigenvector corresponding to a complex eigenvalue
+*>          is stored in two consecutive columns, the first holding the
+*>          real part, and the second the imaginary part.
+*>          Not referenced if SIDE = 'R'.
+*> \endverbatim
+*>
+*> \param[in] LDVL
+*> \verbatim
+*>          LDVL is INTEGER
+*>          The leading dimension of the array VL.
+*>          LDVL >= 1, and if SIDE = 'L' or 'B', LDVL >= N.
+*> \endverbatim
+*>
+*> \param[in,out] VR
+*> \verbatim
+*>          VR is REAL array, dimension (LDVR,MM)
+*>          On entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', VR must
+*>          contain an N-by-N matrix Q (usually the orthogonal matrix Q
+*>          of Schur vectors returned by SHSEQR).
+*>          On exit, if SIDE = 'R' or 'B', VR contains:
+*>          if HOWMNY = 'A', the matrix X of right eigenvectors of T;
+*>          if HOWMNY = 'B', the matrix Q*X;
+*>          if HOWMNY = 'S', the right eigenvectors of T specified by
+*>                           SELECT, stored consecutively in the columns
+*>                           of VR, in the same order as their
+*>                           eigenvalues.
+*>          A complex eigenvector corresponding to a complex eigenvalue
+*>          is stored in two consecutive columns, the first holding the
+*>          real part and the second the imaginary part.
+*>          Not referenced if SIDE = 'L'.
+*> \endverbatim
+*>
+*> \param[in] LDVR
+*> \verbatim
+*>          LDVR is INTEGER
+*>          The leading dimension of the array VR.
+*>          LDVR >= 1, and if SIDE = 'R' or 'B', LDVR >= N.
+*> \endverbatim
+*>
+*> \param[in] MM
+*> \verbatim
+*>          MM is INTEGER
+*>          The number of columns in the arrays VL and/or VR. MM >= M.
+*> \endverbatim
+*>
+*> \param[out] M
+*> \verbatim
+*>          M is INTEGER
+*>          The number of columns in the arrays VL and/or VR actually
+*>          used to store the eigenvectors.
+*>          If HOWMNY = 'A' or 'B', M is set to N.
+*>          Each selected real eigenvector occupies one column and each
+*>          selected complex eigenvector occupies two columns.
+*> \endverbatim
+*>
+*> \param[out] WORK
+*> \verbatim
+*>          WORK is REAL array, dimension (MAX(1,LWORK))
+*> \endverbatim
+*>
+*> \param[in] LWORK
+*> \verbatim
+*>          LWORK is INTEGER
+*>          The dimension of array WORK. LWORK >= max(1,3*N).
+*>          For optimum performance, LWORK >= N + 2*N*NB, where NB is
+*>          the optimal blocksize.
+*>
+*>          If LWORK = -1, then a workspace query is assumed; the routine
+*>          only calculates the optimal size of the WORK array, returns
+*>          this value as the first entry of the WORK array, and no error
+*>          message related to LWORK is issued by XERBLA.
+*> \endverbatim
+*>
+*> \param[out] INFO
+*> \verbatim
+*>          INFO is INTEGER
+*>          = 0:  successful exit
+*>          < 0:  if INFO = -i, the i-th argument had an illegal value
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date November 2011
+*
+*  @generated from dtrevc3.f, fortran d -> s, Tue Apr 19 01:47:44 2016
+*
+*> \ingroup realOTHERcomputational
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  The algorithm used in this program is basically backward (forward)
+*>  substitution, with scaling to make the the code robust against
+*>  possible overflow.
+*>
+*>  Each eigenvector is normalized so that the element of largest
+*>  magnitude has magnitude 1; here the magnitude of a complex number
+*>  (x,y) is taken to be |x| + |y|.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE STREVC3( SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL,
+     $                    VR, LDVR, MM, M, WORK, LWORK, INFO )
+      IMPLICIT NONE
+*
+*  -- LAPACK computational routine (version 3.4.0) --
+*  -- LAPACK is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     November 2011
+*
+*     .. Scalar Arguments ..
+      CHARACTER          HOWMNY, SIDE
+      INTEGER            INFO, LDT, LDVL, LDVR, LWORK, M, MM, N
+*     ..
+*     .. Array Arguments ..
+      LOGICAL            SELECT( * )
+      REAL   T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ),
+     $                   WORK( * )
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
+      INTEGER            NBMIN, NBMAX
+      PARAMETER          ( NBMIN = 8, NBMAX = 128 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            ALLV, BOTHV, LEFTV, LQUERY, OVER, PAIR,
+     $                   RIGHTV, SOMEV
+      INTEGER            I, IERR, II, IP, IS, J, J1, J2, JNXT, K, KI,
+     $                   IV, MAXWRK, NB, KI2
+      REAL   BETA, BIGNUM, EMAX, OVFL, REC, REMAX, SCALE,
+     $                   SMIN, SMLNUM, ULP, UNFL, VCRIT, VMAX, WI, WR,
+     $                   XNORM
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ISAMAX, ILAENV
+      REAL   SDOT, SLAMCH
+      EXTERNAL           LSAME, ISAMAX, ILAENV, SDOT, SLAMCH
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           SAXPY, SCOPY, SGEMV, SLALN2, SSCAL, XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, MAX, SQRT
+*     ..
+*     .. Local Arrays ..
+      REAL   X( 2, 2 )
+      INTEGER            ISCOMPLEX( NBMAX )
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode and test the input parameters
+*
+      BOTHV  = LSAME( SIDE, 'B' )
+      RIGHTV = LSAME( SIDE, 'R' ) .OR. BOTHV
+      LEFTV  = LSAME( SIDE, 'L' ) .OR. BOTHV
+*
+      ALLV  = LSAME( HOWMNY, 'A' )
+      OVER  = LSAME( HOWMNY, 'B' )
+      SOMEV = LSAME( HOWMNY, 'S' )
+*
+      INFO = 0
+      NB = ILAENV( 1, 'STREVC', SIDE // HOWMNY, N, -1, -1, -1 )
+      MAXWRK = N + 2*N*NB
+      WORK(1) = MAXWRK
+      LQUERY = ( LWORK.EQ.-1 )
+      IF( .NOT.RIGHTV .AND. .NOT.LEFTV ) THEN
+         INFO = -1
+      ELSE IF( .NOT.ALLV .AND. .NOT.OVER .AND. .NOT.SOMEV ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDT.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      ELSE IF( LDVL.LT.1 .OR. ( LEFTV .AND. LDVL.LT.N ) ) THEN
+         INFO = -8
+      ELSE IF( LDVR.LT.1 .OR. ( RIGHTV .AND. LDVR.LT.N ) ) THEN
+         INFO = -10
+      ELSE IF( LWORK.LT.MAX( 1, 3*N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -14
+      ELSE
+*
+*        Set M to the number of columns required to store the selected
+*        eigenvectors, standardize the array SELECT if necessary, and
+*        test MM.
+*
+         IF( SOMEV ) THEN
+            M = 0
+            PAIR = .FALSE.
+            DO 10 J = 1, N
+               IF( PAIR ) THEN
+                  PAIR = .FALSE.
+                  SELECT( J ) = .FALSE.
+               ELSE
+                  IF( J.LT.N ) THEN
+                     IF( T( J+1, J ).EQ.ZERO ) THEN
+                        IF( SELECT( J ) )
+     $                     M = M + 1
+                     ELSE
+                        PAIR = .TRUE.
+                        IF( SELECT( J ) .OR. SELECT( J+1 ) ) THEN
+                           SELECT( J ) = .TRUE.
+                           M = M + 2
+                        END IF
+                     END IF
+                  ELSE
+                     IF( SELECT( N ) )
+     $                  M = M + 1
+                  END IF
+               END IF
+   10       CONTINUE
+         ELSE
+            M = N
+         END IF
+*
+         IF( MM.LT.M ) THEN
+            INFO = -11
+         END IF
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'STREVC3', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Use blocked version of back-transformation if sufficient workspace.
+*     Zero-out the workspace to avoid potential NaN propagation.
+*
+      IF( OVER .AND. LWORK .GE. N + 2*N*NBMIN ) THEN
+         NB = (LWORK - N) / (2*N)
+         NB = MIN( NB, NBMAX )
+         CALL SLASET( 'F', N, 1+2*NB, ZERO, ZERO, WORK, N )
+      ELSE
+         NB = 1
+      END IF
+*
+*     Set the constants to control overflow.
+*
+      UNFL = SLAMCH( 'Safe minimum' )
+      OVFL = ONE / UNFL
+      CALL SLABAD( UNFL, OVFL )
+      ULP = SLAMCH( 'Precision' )
+      SMLNUM = UNFL*( N / ULP )
+      BIGNUM = ( ONE-ULP ) / SMLNUM
+*
+*     Compute 1-norm of each column of strictly upper triangular
+*     part of T to control overflow in triangular solver.
+*
+      WORK( 1 ) = ZERO
+      DO 30 J = 2, N
+         WORK( J ) = ZERO
+         DO 20 I = 1, J - 1
+            WORK( J ) = WORK( J ) + ABS( T( I, J ) )
+   20    CONTINUE
+   30 CONTINUE
+*
+*     Index IP is used to specify the real or complex eigenvalue:
+*       IP = 0, real eigenvalue,
+*            1, first  of conjugate complex pair: (wr,wi)
+*           -1, second of conjugate complex pair: (wr,wi)
+*       ISCOMPLEX array stores IP for each column in current block.
+*
+      IF( RIGHTV ) THEN
+*
+*        ============================================================
+*        Compute right eigenvectors.
+*
+*        IV is index of column in current block.
+*        For complex right vector, uses IV-1 for real part and IV for complex part.
+*        Non-blocked version always uses IV=2;
+*        blocked     version starts with IV=NB, goes down to 1 or 2.
+*        (Note the "0-th" column is used for 1-norms computed above.)
+         IV = 2
+         IF( NB.GT.2 ) THEN
+            IV = NB
+         END IF
+         
+         IP = 0
+         IS = M
+         DO 140 KI = N, 1, -1
+            IF( IP.EQ.-1 ) THEN
+*              previous iteration (ki+1) was second of conjugate pair,
+*              so this ki is first of conjugate pair; skip to end of loop
+               IP = 1
+               GO TO 140
+            ELSE IF( KI.EQ.1 ) THEN
+*              last column, so this ki must be real eigenvalue
+               IP = 0
+            ELSE IF( T( KI, KI-1 ).EQ.ZERO ) THEN
+*              zero on sub-diagonal, so this ki is real eigenvalue
+               IP = 0
+            ELSE
+*              non-zero on sub-diagonal, so this ki is second of conjugate pair
+               IP = -1
+            END IF
+
+            IF( SOMEV ) THEN
+               IF( IP.EQ.0 ) THEN
+                  IF( .NOT.SELECT( KI ) )
+     $               GO TO 140
+               ELSE
+                  IF( .NOT.SELECT( KI-1 ) )
+     $               GO TO 140
+               END IF
+            END IF
+*
+*           Compute the KI-th eigenvalue (WR,WI).
+*
+            WR = T( KI, KI )
+            WI = ZERO
+            IF( IP.NE.0 )
+     $         WI = SQRT( ABS( T( KI, KI-1 ) ) )*
+     $              SQRT( ABS( T( KI-1, KI ) ) )
+            SMIN = MAX( ULP*( ABS( WR )+ABS( WI ) ), SMLNUM )
+*
+            IF( IP.EQ.0 ) THEN
+*
+*              --------------------------------------------------------
+*              Real right eigenvector
+*
+               WORK( KI + IV*N ) = ONE
+*
+*              Form right-hand side.
+*
+               DO 50 K = 1, KI - 1
+                  WORK( K + IV*N ) = -T( K, KI )
+   50          CONTINUE
+*
+*              Solve upper quasi-triangular system:
+*              [ T(1:KI-1,1:KI-1) - WR ]*X = SCALE*WORK.
+*
+               JNXT = KI - 1
+               DO 60 J = KI - 1, 1, -1
+                  IF( J.GT.JNXT )
+     $               GO TO 60
+                  J1 = J
+                  J2 = J
+                  JNXT = J - 1
+                  IF( J.GT.1 ) THEN
+                     IF( T( J, J-1 ).NE.ZERO ) THEN
+                        J1   = J - 1
+                        JNXT = J - 2
+                     END IF
+                  END IF
+*
+                  IF( J1.EQ.J2 ) THEN
+*
+*                    1-by-1 diagonal block
+*
+                     CALL SLALN2( .FALSE., 1, 1, SMIN, ONE, T( J, J ),
+     $                            LDT, ONE, ONE, WORK( J+IV*N ), N, WR,
+     $                            ZERO, X, 2, SCALE, XNORM, IERR )
+*
+*                    Scale X(1,1) to avoid overflow when updating
+*                    the right-hand side.
+*
+                     IF( XNORM.GT.ONE ) THEN
+                        IF( WORK( J ).GT.BIGNUM / XNORM ) THEN
+                           X( 1, 1 ) = X( 1, 1 ) / XNORM
+                           SCALE = SCALE / XNORM
+                        END IF
+                     END IF
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE )
+     $                  CALL SSCAL( KI, SCALE, WORK( 1+IV*N ), 1 )
+                     WORK( J+IV*N ) = X( 1, 1 )
+*
+*                    Update right-hand side
+*
+                     CALL SAXPY( J-1, -X( 1, 1 ), T( 1, J ), 1,
+     $                           WORK( 1+IV*N ), 1 )
+*
+                  ELSE
+*
+*                    2-by-2 diagonal block
+*
+                     CALL SLALN2( .FALSE., 2, 1, SMIN, ONE,
+     $                            T( J-1, J-1 ), LDT, ONE, ONE,
+     $                            WORK( J-1+IV*N ), N, WR, ZERO, X, 2,
+     $                            SCALE, XNORM, IERR )
+*
+*                    Scale X(1,1) and X(2,1) to avoid overflow when
+*                    updating the right-hand side.
+*
+                     IF( XNORM.GT.ONE ) THEN
+                        BETA = MAX( WORK( J-1 ), WORK( J ) )
+                        IF( BETA.GT.BIGNUM / XNORM ) THEN
+                           X( 1, 1 ) = X( 1, 1 ) / XNORM
+                           X( 2, 1 ) = X( 2, 1 ) / XNORM
+                           SCALE = SCALE / XNORM
+                        END IF
+                     END IF
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE )
+     $                  CALL SSCAL( KI, SCALE, WORK( 1+IV*N ), 1 )
+                     WORK( J-1+IV*N ) = X( 1, 1 )
+                     WORK( J  +IV*N ) = X( 2, 1 )
+*
+*                    Update right-hand side
+*
+                     CALL SAXPY( J-2, -X( 1, 1 ), T( 1, J-1 ), 1,
+     $                           WORK( 1+IV*N ), 1 )
+                     CALL SAXPY( J-2, -X( 2, 1 ), T( 1, J ), 1,
+     $                           WORK( 1+IV*N ), 1 )
+                  END IF
+   60          CONTINUE
+*
+*              Copy the vector x or Q*x to VR and normalize.
+*
+               IF( .NOT.OVER ) THEN
+*                 ------------------------------
+*                 no back-transform: copy x to VR and normalize.
+                  CALL SCOPY( KI, WORK( 1 + IV*N ), 1, VR( 1, IS ), 1 )
+*
+                  II = ISAMAX( KI, VR( 1, IS ), 1 )
+                  REMAX = ONE / ABS( VR( II, IS ) )
+                  CALL SSCAL( KI, REMAX, VR( 1, IS ), 1 )
+*
+                  DO 70 K = KI + 1, N
+                     VR( K, IS ) = ZERO
+   70             CONTINUE
+*
+               ELSE IF( NB.EQ.1 ) THEN
+*                 ------------------------------
+*                 version 1: back-transform each vector with GEMV, Q*x.
+                  IF( KI.GT.1 )
+     $               CALL SGEMV( 'N', N, KI-1, ONE, VR, LDVR,
+     $                           WORK( 1 + IV*N ), 1, WORK( KI + IV*N ),
+     $                           VR( 1, KI ), 1 )
+*
+                  II = ISAMAX( N, VR( 1, KI ), 1 )
+                  REMAX = ONE / ABS( VR( II, KI ) )
+                  CALL SSCAL( N, REMAX, VR( 1, KI ), 1 )
+*
+               ELSE
+*                 ------------------------------
+*                 version 2: back-transform block of vectors with GEMM
+*                 zero out below vector
+                  DO K = KI + 1, N
+                     WORK( K + IV*N ) = ZERO
+                  END DO
+                  ISCOMPLEX( IV ) = IP
+*                 back-transform and normalization is done below
+               END IF
+            ELSE
+*
+*              --------------------------------------------------------
+*              Complex right eigenvector.
+*
+*              Initial solve
+*              [ ( T(KI-1,KI-1) T(KI-1,KI) ) - (WR + I*WI) ]*X = 0.
+*              [ ( T(KI,  KI-1) T(KI,  KI) )               ]
+*
+               IF( ABS( T( KI-1, KI ) ).GE.ABS( T( KI, KI-1 ) ) ) THEN
+                  WORK( KI-1 + (IV-1)*N ) = ONE
+                  WORK( KI   + (IV  )*N ) = WI / T( KI-1, KI )
+               ELSE
+                  WORK( KI-1 + (IV-1)*N ) = -WI / T( KI, KI-1 )
+                  WORK( KI   + (IV  )*N ) = ONE
+               END IF
+               WORK( KI   + (IV-1)*N ) = ZERO
+               WORK( KI-1 + (IV  )*N ) = ZERO
+*
+*              Form right-hand side.
+*
+               DO 80 K = 1, KI - 2
+                  WORK( K+(IV-1)*N ) = -WORK( KI-1+(IV-1)*N )*T(K,KI-1)
+                  WORK( K+(IV  )*N ) = -WORK( KI  +(IV  )*N )*T(K,KI  )
+   80          CONTINUE
+*
+*              Solve upper quasi-triangular system:
+*              [ T(1:KI-2,1:KI-2) - (WR+i*WI) ]*X = SCALE*(WORK+i*WORK2)
+*
+               JNXT = KI - 2
+               DO 90 J = KI - 2, 1, -1
+                  IF( J.GT.JNXT )
+     $               GO TO 90
+                  J1 = J
+                  J2 = J
+                  JNXT = J - 1
+                  IF( J.GT.1 ) THEN
+                     IF( T( J, J-1 ).NE.ZERO ) THEN
+                        J1   = J - 1
+                        JNXT = J - 2
+                     END IF
+                  END IF
+*
+                  IF( J1.EQ.J2 ) THEN
+*
+*                    1-by-1 diagonal block
+*
+                     CALL SLALN2( .FALSE., 1, 2, SMIN, ONE, T( J, J ),
+     $                            LDT, ONE, ONE, WORK( J+(IV-1)*N ), N,
+     $                            WR, WI, X, 2, SCALE, XNORM, IERR )
+*
+*                    Scale X(1,1) and X(1,2) to avoid overflow when
+*                    updating the right-hand side.
+*
+                     IF( XNORM.GT.ONE ) THEN
+                        IF( WORK( J ).GT.BIGNUM / XNORM ) THEN
+                           X( 1, 1 ) = X( 1, 1 ) / XNORM
+                           X( 1, 2 ) = X( 1, 2 ) / XNORM
+                           SCALE = SCALE / XNORM
+                        END IF
+                     END IF
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE ) THEN
+                        CALL SSCAL( KI, SCALE, WORK( 1+(IV-1)*N ), 1 )
+                        CALL SSCAL( KI, SCALE, WORK( 1+(IV  )*N ), 1 )
+                     END IF
+                     WORK( J+(IV-1)*N ) = X( 1, 1 )
+                     WORK( J+(IV  )*N ) = X( 1, 2 )
+*
+*                    Update the right-hand side
+*
+                     CALL SAXPY( J-1, -X( 1, 1 ), T( 1, J ), 1,
+     $                           WORK( 1+(IV-1)*N ), 1 )
+                     CALL SAXPY( J-1, -X( 1, 2 ), T( 1, J ), 1,
+     $                           WORK( 1+(IV  )*N ), 1 )
+*
+                  ELSE
+*
+*                    2-by-2 diagonal block
+*
+                     CALL SLALN2( .FALSE., 2, 2, SMIN, ONE,
+     $                            T( J-1, J-1 ), LDT, ONE, ONE,
+     $                            WORK( J-1+(IV-1)*N ), N, WR, WI, X, 2,
+     $                            SCALE, XNORM, IERR )
+*
+*                    Scale X to avoid overflow when updating
+*                    the right-hand side.
+*
+                     IF( XNORM.GT.ONE ) THEN
+                        BETA = MAX( WORK( J-1 ), WORK( J ) )
+                        IF( BETA.GT.BIGNUM / XNORM ) THEN
+                           REC = ONE / XNORM
+                           X( 1, 1 ) = X( 1, 1 )*REC
+                           X( 1, 2 ) = X( 1, 2 )*REC
+                           X( 2, 1 ) = X( 2, 1 )*REC
+                           X( 2, 2 ) = X( 2, 2 )*REC
+                           SCALE = SCALE*REC
+                        END IF
+                     END IF
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE ) THEN
+                        CALL SSCAL( KI, SCALE, WORK( 1+(IV-1)*N ), 1 )
+                        CALL SSCAL( KI, SCALE, WORK( 1+(IV  )*N ), 1 )
+                     END IF
+                     WORK( J-1+(IV-1)*N ) = X( 1, 1 )
+                     WORK( J  +(IV-1)*N ) = X( 2, 1 )
+                     WORK( J-1+(IV  )*N ) = X( 1, 2 )
+                     WORK( J  +(IV  )*N ) = X( 2, 2 )
+*
+*                    Update the right-hand side
+*
+                     CALL SAXPY( J-2, -X( 1, 1 ), T( 1, J-1 ), 1,
+     $                           WORK( 1+(IV-1)*N   ), 1 )
+                     CALL SAXPY( J-2, -X( 2, 1 ), T( 1, J ), 1,
+     $                           WORK( 1+(IV-1)*N   ), 1 )
+                     CALL SAXPY( J-2, -X( 1, 2 ), T( 1, J-1 ), 1,
+     $                           WORK( 1+(IV  )*N ), 1 )
+                     CALL SAXPY( J-2, -X( 2, 2 ), T( 1, J ), 1,
+     $                           WORK( 1+(IV  )*N ), 1 )
+                  END IF
+   90          CONTINUE
+*
+*              Copy the vector x or Q*x to VR and normalize.
+*
+               IF( .NOT.OVER ) THEN
+*                 ------------------------------
+*                 no back-transform: copy x to VR and normalize.
+                  CALL SCOPY( KI, WORK( 1+(IV-1)*N ), 1, VR(1,IS-1), 1 )
+                  CALL SCOPY( KI, WORK( 1+(IV  )*N ), 1, VR(1,IS  ), 1 )
+*
+                  EMAX = ZERO
+                  DO 100 K = 1, KI
+                     EMAX = MAX( EMAX, ABS( VR( K, IS-1 ) )+
+     $                                 ABS( VR( K, IS   ) ) )
+  100             CONTINUE
+                  REMAX = ONE / EMAX
+                  CALL SSCAL( KI, REMAX, VR( 1, IS-1 ), 1 )
+                  CALL SSCAL( KI, REMAX, VR( 1, IS   ), 1 )
+*
+                  DO 110 K = KI + 1, N
+                     VR( K, IS-1 ) = ZERO
+                     VR( K, IS   ) = ZERO
+  110             CONTINUE
+*
+               ELSE IF( NB.EQ.1 ) THEN
+*                 ------------------------------
+*                 version 1: back-transform each vector with GEMV, Q*x.
+                  IF( KI.GT.2 ) THEN
+                     CALL SGEMV( 'N', N, KI-2, ONE, VR, LDVR,
+     $                           WORK( 1    + (IV-1)*N ), 1,
+     $                           WORK( KI-1 + (IV-1)*N ), VR(1,KI-1), 1)
+                     CALL SGEMV( 'N', N, KI-2, ONE, VR, LDVR,
+     $                           WORK( 1  + (IV)*N ), 1,
+     $                           WORK( KI + (IV)*N ), VR( 1, KI ), 1 )
+                  ELSE
+                     CALL SSCAL( N, WORK(KI-1+(IV-1)*N), VR(1,KI-1), 1)
+                     CALL SSCAL( N, WORK(KI  +(IV  )*N), VR(1,KI  ), 1)
+                  END IF
+*
+                  EMAX = ZERO
+                  DO 120 K = 1, N
+                     EMAX = MAX( EMAX, ABS( VR( K, KI-1 ) )+
+     $                                 ABS( VR( K, KI   ) ) )
+  120             CONTINUE
+                  REMAX = ONE / EMAX
+                  CALL SSCAL( N, REMAX, VR( 1, KI-1 ), 1 )
+                  CALL SSCAL( N, REMAX, VR( 1, KI   ), 1 )
+*
+               ELSE
+*                 ------------------------------
+*                 version 2: back-transform block of vectors with GEMM
+*                 zero out below vector
+                  DO K = KI + 1, N
+                     WORK( K + (IV-1)*N ) = ZERO
+                     WORK( K + (IV  )*N ) = ZERO
+                  END DO
+                  ISCOMPLEX( IV-1 ) = -IP
+                  ISCOMPLEX( IV   ) =  IP
+                  IV = IV - 1
+*                 back-transform and normalization is done below
+               END IF
+            END IF
+            
+            IF( NB.GT.1 ) THEN
+*              --------------------------------------------------------
+*              Blocked version of back-transform
+*              For complex case, KI2 includes both vectors (KI-1 and KI)
+               IF( IP.EQ.0 ) THEN
+                  KI2 = KI
+               ELSE
+                  KI2 = KI - 1
+               END IF
+
+*              Columns IV:NB of work are valid vectors.
+*              When the number of vectors stored reaches NB-1 or NB,
+*              or if this was last vector, do the GEMM
+               IF( (IV.LE.2) .OR. (KI2.EQ.1) ) THEN
+                  CALL SGEMM( 'N', 'N', N, NB-IV+1, KI2+NB-IV, ONE,
+     $                        VR, LDVR,
+     $                        WORK( 1 + (IV)*N    ), N,
+     $                        ZERO,
+     $                        WORK( 1 + (NB+IV)*N ), N )
+*                 normalize vectors
+                  DO K = IV, NB
+                     IF( ISCOMPLEX(K).EQ.0 ) THEN
+*                       real eigenvector
+                        II = ISAMAX( N, WORK( 1 + (NB+K)*N ), 1 )
+                        REMAX = ONE / ABS( WORK( II + (NB+K)*N ) )
+                     ELSE IF( ISCOMPLEX(K).EQ.1 ) THEN
+*                       first eigenvector of conjugate pair
+                        EMAX = ZERO
+                        DO II = 1, N
+                           EMAX = MAX( EMAX,
+     $                                 ABS( WORK( II + (NB+K  )*N ) )+
+     $                                 ABS( WORK( II + (NB+K+1)*N ) ) )
+                        END DO
+                        REMAX = ONE / EMAX
+*                    else if ISCOMPLEX(K).EQ.-1
+*                       second eigenvector of conjugate pair
+*                       reuse same REMAX as previous K
+                     END IF
+                     CALL SSCAL( N, REMAX, WORK( 1 + (NB+K)*N ), 1 )
+                  END DO
+                  CALL SLACPY( 'F', N, NB-IV+1,
+     $                         WORK( 1 + (NB+IV)*N ), N,
+     $                         VR( 1, KI2 ), LDVR )
+                  IV = NB
+               ELSE
+                  IV = IV - 1
+               END IF
+            END IF ! blocked back-transform
+*
+            IS = IS - 1
+            IF( IP.NE.0 )
+     $         IS = IS - 1
+  140    CONTINUE
+      END IF
+
+      IF( LEFTV ) THEN
+*
+*        ============================================================
+*        Compute left eigenvectors.
+*
+*        IV is index of column in current block.
+*        For complex left vector, uses IV for real part and IV+1 for complex part.
+*        Non-blocked version always uses IV=1;
+*        blocked     version starts with IV=1, goes up to NB-1 or NB.
+*        (Note the "0-th" column is used for 1-norms computed above.)
+         IV = 1
+         IP = 0
+         IS = 1
+         DO 260 KI = 1, N
+            IF( IP.EQ.1 ) THEN
+*              previous iteration (ki-1) was first of conjugate pair,
+*              so this ki is second of conjugate pair; skip to end of loop
+               IP = -1
+               GO TO 260
+            ELSE IF( KI.EQ.N ) THEN
+*              last column, so this ki must be real eigenvalue
+               IP = 0
+            ELSE IF( T( KI+1, KI ).EQ.ZERO ) THEN
+*              zero on sub-diagonal, so this ki is real eigenvalue
+               IP = 0
+            ELSE
+*              non-zero on sub-diagonal, so this ki is first of conjugate pair
+               IP = 1
+            END IF
+*
+            IF( SOMEV ) THEN
+               IF( .NOT.SELECT( KI ) )
+     $            GO TO 260
+            END IF
+*
+*           Compute the KI-th eigenvalue (WR,WI).
+*
+            WR = T( KI, KI )
+            WI = ZERO
+            IF( IP.NE.0 )
+     $         WI = SQRT( ABS( T( KI, KI+1 ) ) )*
+     $              SQRT( ABS( T( KI+1, KI ) ) )
+            SMIN = MAX( ULP*( ABS( WR )+ABS( WI ) ), SMLNUM )
+*
+            IF( IP.EQ.0 ) THEN
+*
+*              --------------------------------------------------------
+*              Real left eigenvector
+*
+               WORK( KI + IV*N ) = ONE
+*
+*              Form right-hand side.
+*
+               DO 160 K = KI + 1, N
+                  WORK( K + IV*N ) = -T( KI, K )
+  160          CONTINUE
+*
+*              Solve transposed quasi-triangular system:
+*              [ T(KI+1:N,KI+1:N) - WR ]**T * X = SCALE*WORK
+*
+               VMAX = ONE
+               VCRIT = BIGNUM
+*
+               JNXT = KI + 1
+               DO 170 J = KI + 1, N
+                  IF( J.LT.JNXT )
+     $               GO TO 170
+                  J1 = J
+                  J2 = J
+                  JNXT = J + 1
+                  IF( J.LT.N ) THEN
+                     IF( T( J+1, J ).NE.ZERO ) THEN
+                        J2 = J + 1
+                        JNXT = J + 2
+                     END IF
+                  END IF
+*
+                  IF( J1.EQ.J2 ) THEN
+*
+*                    1-by-1 diagonal block
+*
+*                    Scale if necessary to avoid overflow when forming
+*                    the right-hand side.
+*
+                     IF( WORK( J ).GT.VCRIT ) THEN
+                        REC = ONE / VMAX
+                        CALL SSCAL( N-KI+1, REC, WORK( KI+IV*N ), 1 )
+                        VMAX = ONE
+                        VCRIT = BIGNUM
+                     END IF
+*
+                     WORK( J+IV*N ) = WORK( J+IV*N ) -
+     $                                SDOT( J-KI-1, T( KI+1, J ), 1,
+     $                                      WORK( KI+1+IV*N ), 1 )
+*
+*                    Solve [ T(J,J) - WR ]**T * X = WORK
+*
+                     CALL SLALN2( .FALSE., 1, 1, SMIN, ONE, T( J, J ),
+     $                            LDT, ONE, ONE, WORK( J+IV*N ), N, WR,
+     $                            ZERO, X, 2, SCALE, XNORM, IERR )
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE )
+     $                  CALL SSCAL( N-KI+1, SCALE, WORK( KI+IV*N ), 1 )
+                     WORK( J+IV*N ) = X( 1, 1 )
+                     VMAX = MAX( ABS( WORK( J+IV*N ) ), VMAX )
+                     VCRIT = BIGNUM / VMAX
+*
+                  ELSE
+*
+*                    2-by-2 diagonal block
+*
+*                    Scale if necessary to avoid overflow when forming
+*                    the right-hand side.
+*
+                     BETA = MAX( WORK( J ), WORK( J+1 ) )
+                     IF( BETA.GT.VCRIT ) THEN
+                        REC = ONE / VMAX
+                        CALL SSCAL( N-KI+1, REC, WORK( KI+IV*N ), 1 )
+                        VMAX = ONE
+                        VCRIT = BIGNUM
+                     END IF
+*
+                     WORK( J+IV*N ) = WORK( J+IV*N ) -
+     $                                SDOT( J-KI-1, T( KI+1, J ), 1,
+     $                                      WORK( KI+1+IV*N ), 1 )
+*
+                     WORK( J+1+IV*N ) = WORK( J+1+IV*N ) -
+     $                                  SDOT( J-KI-1, T( KI+1, J+1 ), 1,
+     $                                        WORK( KI+1+IV*N ), 1 )
+*
+*                    Solve
+*                    [ T(J,J)-WR   T(J,J+1)      ]**T * X = SCALE*( WORK1 )
+*                    [ T(J+1,J)    T(J+1,J+1)-WR ]                ( WORK2 )
+*
+                     CALL SLALN2( .TRUE., 2, 1, SMIN, ONE, T( J, J ),
+     $                            LDT, ONE, ONE, WORK( J+IV*N ), N, WR,
+     $                            ZERO, X, 2, SCALE, XNORM, IERR )
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE )
+     $                  CALL SSCAL( N-KI+1, SCALE, WORK( KI+IV*N ), 1 )
+                     WORK( J  +IV*N ) = X( 1, 1 )
+                     WORK( J+1+IV*N ) = X( 2, 1 )
+*
+                     VMAX = MAX( ABS( WORK( J  +IV*N ) ),
+     $                           ABS( WORK( J+1+IV*N ) ), VMAX )
+                     VCRIT = BIGNUM / VMAX
+*
+                  END IF
+  170          CONTINUE
+*
+*              Copy the vector x or Q*x to VL and normalize.
+*
+               IF( .NOT.OVER ) THEN
+*                 ------------------------------
+*                 no back-transform: copy x to VL and normalize.
+                  CALL SCOPY( N-KI+1, WORK( KI + IV*N ), 1,
+     $                                VL( KI, IS ), 1 )
+*
+                  II = ISAMAX( N-KI+1, VL( KI, IS ), 1 ) + KI - 1
+                  REMAX = ONE / ABS( VL( II, IS ) )
+                  CALL SSCAL( N-KI+1, REMAX, VL( KI, IS ), 1 )
+*
+                  DO 180 K = 1, KI - 1
+                     VL( K, IS ) = ZERO
+  180             CONTINUE
+*
+               ELSE IF( NB.EQ.1 ) THEN
+*                 ------------------------------
+*                 version 1: back-transform each vector with GEMV, Q*x.
+                  IF( KI.LT.N )
+     $               CALL SGEMV( 'N', N, N-KI, ONE,
+     $                           VL( 1, KI+1 ), LDVL,
+     $                           WORK( KI+1 + IV*N ), 1,
+     $                           WORK( KI   + IV*N ), VL( 1, KI ), 1 )
+*
+                  II = ISAMAX( N, VL( 1, KI ), 1 )
+                  REMAX = ONE / ABS( VL( II, KI ) )
+                  CALL SSCAL( N, REMAX, VL( 1, KI ), 1 )
+*
+               ELSE
+*                 ------------------------------
+*                 version 2: back-transform block of vectors with GEMM
+*                 zero out above vector
+*                 could go from KI-NV+1 to KI-1
+                  DO K = 1, KI - 1
+                     WORK( K + IV*N ) = ZERO
+                  END DO
+                  ISCOMPLEX( IV ) = IP
+*                 back-transform and normalization is done below
+               END IF
+            ELSE
+*
+*              --------------------------------------------------------
+*              Complex left eigenvector.
+*
+*              Initial solve:
+*              [ ( T(KI,KI)    T(KI,KI+1)  )**T - (WR - I* WI) ]*X = 0.
+*              [ ( T(KI+1,KI) T(KI+1,KI+1) )                   ]
+*
+               IF( ABS( T( KI, KI+1 ) ).GE.ABS( T( KI+1, KI ) ) ) THEN
+                  WORK( KI   + (IV  )*N ) = WI / T( KI, KI+1 )
+                  WORK( KI+1 + (IV+1)*N ) = ONE
+               ELSE
+                  WORK( KI   + (IV  )*N ) = ONE
+                  WORK( KI+1 + (IV+1)*N ) = -WI / T( KI+1, KI )
+               END IF
+               WORK( KI+1 + (IV  )*N ) = ZERO
+               WORK( KI   + (IV+1)*N ) = ZERO
+*
+*              Form right-hand side.
+*
+               DO 190 K = KI + 2, N
+                  WORK( K+(IV  )*N ) = -WORK( KI  +(IV  )*N )*T(KI,  K)
+                  WORK( K+(IV+1)*N ) = -WORK( KI+1+(IV+1)*N )*T(KI+1,K)
+  190          CONTINUE
+*
+*              Solve transposed quasi-triangular system:
+*              [ T(KI+2:N,KI+2:N)**T - (WR-i*WI) ]*X = WORK1+i*WORK2
+*
+               VMAX = ONE
+               VCRIT = BIGNUM
+*
+               JNXT = KI + 2
+               DO 200 J = KI + 2, N
+                  IF( J.LT.JNXT )
+     $               GO TO 200
+                  J1 = J
+                  J2 = J
+                  JNXT = J + 1
+                  IF( J.LT.N ) THEN
+                     IF( T( J+1, J ).NE.ZERO ) THEN
+                        J2 = J + 1
+                        JNXT = J + 2
+                     END IF
+                  END IF
+*
+                  IF( J1.EQ.J2 ) THEN
+*
+*                    1-by-1 diagonal block
+*
+*                    Scale if necessary to avoid overflow when
+*                    forming the right-hand side elements.
+*
+                     IF( WORK( J ).GT.VCRIT ) THEN
+                        REC = ONE / VMAX
+                        CALL SSCAL( N-KI+1, REC, WORK(KI+(IV  )*N), 1 )
+                        CALL SSCAL( N-KI+1, REC, WORK(KI+(IV+1)*N), 1 )
+                        VMAX = ONE
+                        VCRIT = BIGNUM
+                     END IF
+*
+                     WORK( J+(IV  )*N ) = WORK( J+(IV)*N ) -
+     $                                  SDOT( J-KI-2, T( KI+2, J ), 1,
+     $                                        WORK( KI+2+(IV)*N ), 1 )
+                     WORK( J+(IV+1)*N ) = WORK( J+(IV+1)*N ) -
+     $                                  SDOT( J-KI-2, T( KI+2, J ), 1,
+     $                                        WORK( KI+2+(IV+1)*N ), 1 )
+*
+*                    Solve [ T(J,J)-(WR-i*WI) ]*(X11+i*X12)= WK+I*WK2
+*
+                     CALL SLALN2( .FALSE., 1, 2, SMIN, ONE, T( J, J ),
+     $                            LDT, ONE, ONE, WORK( J+IV*N ), N, WR,
+     $                            -WI, X, 2, SCALE, XNORM, IERR )
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE ) THEN
+                        CALL SSCAL( N-KI+1, SCALE, WORK(KI+(IV  )*N), 1)
+                        CALL SSCAL( N-KI+1, SCALE, WORK(KI+(IV+1)*N), 1)
+                     END IF
+                     WORK( J+(IV  )*N ) = X( 1, 1 )
+                     WORK( J+(IV+1)*N ) = X( 1, 2 )
+                     VMAX = MAX( ABS( WORK( J+(IV  )*N ) ),
+     $                           ABS( WORK( J+(IV+1)*N ) ), VMAX )
+                     VCRIT = BIGNUM / VMAX
+*
+                  ELSE
+*
+*                    2-by-2 diagonal block
+*
+*                    Scale if necessary to avoid overflow when forming
+*                    the right-hand side elements.
+*
+                     BETA = MAX( WORK( J ), WORK( J+1 ) )
+                     IF( BETA.GT.VCRIT ) THEN
+                        REC = ONE / VMAX
+                        CALL SSCAL( N-KI+1, REC, WORK(KI+(IV  )*N), 1 )
+                        CALL SSCAL( N-KI+1, REC, WORK(KI+(IV+1)*N), 1 )
+                        VMAX = ONE
+                        VCRIT = BIGNUM
+                     END IF
+*
+                     WORK( J  +(IV  )*N ) = WORK( J+(IV)*N ) -
+     $                                SDOT( J-KI-2, T( KI+2, J ), 1,
+     $                                      WORK( KI+2+(IV)*N ), 1 )
+*
+                     WORK( J  +(IV+1)*N ) = WORK( J+(IV+1)*N ) -
+     $                                SDOT( J-KI-2, T( KI+2, J ), 1,
+     $                                      WORK( KI+2+(IV+1)*N ), 1 )
+*
+                     WORK( J+1+(IV  )*N ) = WORK( J+1+(IV)*N ) -
+     $                                SDOT( J-KI-2, T( KI+2, J+1 ), 1,
+     $                                      WORK( KI+2+(IV)*N ), 1 )
+*
+                     WORK( J+1+(IV+1)*N ) = WORK( J+1+(IV+1)*N ) -
+     $                                SDOT( J-KI-2, T( KI+2, J+1 ), 1,
+     $                                      WORK( KI+2+(IV+1)*N ), 1 )
+*
+*                    Solve 2-by-2 complex linear equation
+*                    [ (T(j,j)   T(j,j+1)  )**T - (wr-i*wi)*I ]*X = SCALE*B
+*                    [ (T(j+1,j) T(j+1,j+1))                  ]
+*
+                     CALL SLALN2( .TRUE., 2, 2, SMIN, ONE, T( J, J ),
+     $                            LDT, ONE, ONE, WORK( J+IV*N ), N, WR,
+     $                            -WI, X, 2, SCALE, XNORM, IERR )
+*
+*                    Scale if necessary
+*
+                     IF( SCALE.NE.ONE ) THEN
+                        CALL SSCAL( N-KI+1, SCALE, WORK(KI+(IV  )*N), 1)
+                        CALL SSCAL( N-KI+1, SCALE, WORK(KI+(IV+1)*N), 1)
+                     END IF
+                     WORK( J  +(IV  )*N ) = X( 1, 1 )
+                     WORK( J  +(IV+1)*N ) = X( 1, 2 )
+                     WORK( J+1+(IV  )*N ) = X( 2, 1 )
+                     WORK( J+1+(IV+1)*N ) = X( 2, 2 )
+                     VMAX = MAX( ABS( X( 1, 1 ) ), ABS( X( 1, 2 ) ),
+     $                           ABS( X( 2, 1 ) ), ABS( X( 2, 2 ) ),
+     $                           VMAX )
+                     VCRIT = BIGNUM / VMAX
+*
+                  END IF
+  200          CONTINUE
+*
+*              Copy the vector x or Q*x to VL and normalize.
+*
+               IF( .NOT.OVER ) THEN
+*                 ------------------------------
+*                 no back-transform: copy x to VL and normalize.
+                  CALL SCOPY( N-KI+1, WORK( KI + (IV  )*N ), 1,
+     $                        VL( KI, IS   ), 1 )
+                  CALL SCOPY( N-KI+1, WORK( KI + (IV+1)*N ), 1,
+     $                        VL( KI, IS+1 ), 1 )
+*
+                  EMAX = ZERO
+                  DO 220 K = KI, N
+                     EMAX = MAX( EMAX, ABS( VL( K, IS   ) )+
+     $                                 ABS( VL( K, IS+1 ) ) )
+  220             CONTINUE
+                  REMAX = ONE / EMAX
+                  CALL SSCAL( N-KI+1, REMAX, VL( KI, IS   ), 1 )
+                  CALL SSCAL( N-KI+1, REMAX, VL( KI, IS+1 ), 1 )
+*
+                  DO 230 K = 1, KI - 1
+                     VL( K, IS   ) = ZERO
+                     VL( K, IS+1 ) = ZERO
+  230             CONTINUE
+*
+               ELSE IF( NB.EQ.1 ) THEN
+*                 ------------------------------
+*                 version 1: back-transform each vector with GEMV, Q*x.
+                  IF( KI.LT.N-1 ) THEN
+                     CALL SGEMV( 'N', N, N-KI-1, ONE,
+     $                           VL( 1, KI+2 ), LDVL,
+     $                           WORK( KI+2 + (IV)*N ), 1,
+     $                           WORK( KI   + (IV)*N ),
+     $                           VL( 1, KI ), 1 )
+                     CALL SGEMV( 'N', N, N-KI-1, ONE,
+     $                           VL( 1, KI+2 ), LDVL,
+     $                           WORK( KI+2 + (IV+1)*N ), 1,
+     $                           WORK( KI+1 + (IV+1)*N ),
+     $                           VL( 1, KI+1 ), 1 )
+                  ELSE
+                     CALL SSCAL( N, WORK(KI+  (IV  )*N), VL(1, KI  ), 1)
+                     CALL SSCAL( N, WORK(KI+1+(IV+1)*N), VL(1, KI+1), 1)
+                  END IF
+*
+                  EMAX = ZERO
+                  DO 240 K = 1, N
+                     EMAX = MAX( EMAX, ABS( VL( K, KI   ) )+
+     $                                 ABS( VL( K, KI+1 ) ) )
+  240             CONTINUE
+                  REMAX = ONE / EMAX
+                  CALL SSCAL( N, REMAX, VL( 1, KI   ), 1 )
+                  CALL SSCAL( N, REMAX, VL( 1, KI+1 ), 1 )
+*
+               ELSE
+*                 ------------------------------
+*                 version 2: back-transform block of vectors with GEMM
+*                 zero out above vector
+*                 could go from KI-NV+1 to KI-1
+                  DO K = 1, KI - 1
+                     WORK( K + (IV  )*N ) = ZERO
+                     WORK( K + (IV+1)*N ) = ZERO
+                  END DO
+                  ISCOMPLEX( IV   ) =  IP
+                  ISCOMPLEX( IV+1 ) = -IP
+                  IV = IV + 1
+*                 back-transform and normalization is done below
+               END IF
+            END IF
+
+            IF( NB.GT.1 ) THEN
+*              --------------------------------------------------------
+*              Blocked version of back-transform
+*              For complex case, KI2 includes both vectors (KI and KI+1)
+               IF( IP.EQ.0 ) THEN
+                  KI2 = KI
+               ELSE
+                  KI2 = KI + 1
+               END IF
+
+*              Columns 1:IV of work are valid vectors.
+*              When the number of vectors stored reaches NB-1 or NB,
+*              or if this was last vector, do the GEMM
+               IF( (IV.GE.NB-1) .OR. (KI2.EQ.N) ) THEN
+                  CALL SGEMM( 'N', 'N', N, IV, N-KI2+IV, ONE,
+     $                        VL( 1, KI2-IV+1 ), LDVL,
+     $                        WORK( KI2-IV+1 + (1)*N ), N,
+     $                        ZERO,
+     $                        WORK( 1 + (NB+1)*N ), N )
+*                 normalize vectors
+                  DO K = 1, IV
+                     IF( ISCOMPLEX(K).EQ.0) THEN
+*                       real eigenvector
+                        II = ISAMAX( N, WORK( 1 + (NB+K)*N ), 1 )
+                        REMAX = ONE / ABS( WORK( II + (NB+K)*N ) )
+                     ELSE IF( ISCOMPLEX(K).EQ.1) THEN
+*                       first eigenvector of conjugate pair
+                        EMAX = ZERO
+                        DO II = 1, N
+                           EMAX = MAX( EMAX,
+     $                                 ABS( WORK( II + (NB+K  )*N ) )+
+     $                                 ABS( WORK( II + (NB+K+1)*N ) ) )
+                        END DO
+                        REMAX = ONE / EMAX
+*                    else if ISCOMPLEX(K).EQ.-1
+*                       second eigenvector of conjugate pair
+*                       reuse same REMAX as previous K
+                     END IF
+                     CALL SSCAL( N, REMAX, WORK( 1 + (NB+K)*N ), 1 )
+                  END DO
+                  CALL SLACPY( 'F', N, IV,
+     $                         WORK( 1 + (NB+1)*N ), N,
+     $                         VL( 1, KI2-IV+1 ), LDVL )
+                  IV = 1
+               ELSE
+                  IV = IV + 1
+               END IF
+            END IF ! blocked back-transform
+*
+            IS = IS + 1
+            IF( IP.NE.0 )
+     $         IS = IS + 1
+  260    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of STREVC3
+*
+      END
index 0d6e218bb788224219e966873d9d722178b496d2..18c4db0d02904f49c1effeee0eaf787983e58330 100644 (file)
 *> \param[in,out] U1
 *> \verbatim
 *>          U1 is COMPLEX*16 array, dimension (LDU1,P)
-*>          On entry, an LDU1-by-P matrix. On exit, U1 is postmultiplied
+*>          On entry, a P-by-P matrix. On exit, U1 is postmultiplied
 *>          by the left singular vector matrix common to [ B11 ; 0 ] and
 *>          [ B12 0 0 ; 0 -I 0 0 ].
 *> \endverbatim
 *> \param[in] LDU1
 *> \verbatim
 *>          LDU1 is INTEGER
-*>          The leading dimension of the array U1.
+*>          The leading dimension of the array U1, LDU1 >= MAX(1,P).
 *> \endverbatim
 *>
 *> \param[in,out] U2
 *> \verbatim
 *>          U2 is COMPLEX*16 array, dimension (LDU2,M-P)
-*>          On entry, an LDU2-by-(M-P) matrix. On exit, U2 is
+*>          On entry, an (M-P)-by-(M-P) matrix. On exit, U2 is
 *>          postmultiplied by the left singular vector matrix common to
 *>          [ B21 ; 0 ] and [ B22 0 0 ; 0 0 I ].
 *> \endverbatim
 *> \param[in] LDU2
 *> \verbatim
 *>          LDU2 is INTEGER
-*>          The leading dimension of the array U2.
+*>          The leading dimension of the array U2, LDU2 >= MAX(1,M-P).
 *> \endverbatim
 *>
 *> \param[in,out] V1T
 *> \verbatim
 *>          V1T is COMPLEX*16 array, dimension (LDV1T,Q)
-*>          On entry, a LDV1T-by-Q matrix. On exit, V1T is premultiplied
+*>          On entry, a Q-by-Q matrix. On exit, V1T is premultiplied
 *>          by the conjugate transpose of the right singular vector
 *>          matrix common to [ B11 ; 0 ] and [ B21 ; 0 ].
 *> \endverbatim
 *> \param[in] LDV1T
 *> \verbatim
 *>          LDV1T is INTEGER
-*>          The leading dimension of the array V1T.
+*>          The leading dimension of the array V1T, LDV1T >= MAX(1,Q).
 *> \endverbatim
 *>
 *> \param[in,out] V2T
 *> \verbatim
 *>          V2T is COMPLEX*16 array, dimenison (LDV2T,M-Q)
-*>          On entry, a LDV2T-by-(M-Q) matrix. On exit, V2T is
+*>          On entry, an (M-Q)-by-(M-Q) matrix. On exit, V2T is
 *>          premultiplied by the conjugate transpose of the right
 *>          singular vector matrix common to [ B12 0 0 ; 0 -I 0 ] and
 *>          [ B22 0 0 ; 0 0 I ].
 *> \param[in] LDV2T
 *> \verbatim
 *>          LDV2T is INTEGER
-*>          The leading dimension of the array V2T.
+*>          The leading dimension of the array V2T, LDV2T >= MAX(1,M-Q).
 *> \endverbatim
 *>
 *> \param[out] B11D
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complex16OTHERcomputational
 *
      $                   V2T, LDV2T, B11D, B11E, B12D, B12E, B21D, B21E,
      $                   B22D, B22E, RWORK, LRWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBU1, JOBU2, JOBV1T, JOBV2T, TRANS
index d7d0a9d2850e1cb780323978e182d838976b7eac..493cc4164a1682fcc94e4ae723c2444fbbdc7a44 100644 (file)
 *>               -3 : failure of CGETRF
 *>               -31: stop the iterative refinement after the 30th
 *>                    iterations
-*>          > 0: iterative refinement has been sucessfully used.
+*>          > 0: iterative refinement has been successfully used.
 *>               Returns the number of iterations
 *> \endverbatim
 *>
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup complex16GEsolve
 *
       SUBROUTINE ZCGESV( N, NRHS, A, LDA, IPIV, B, LDB, X, LDX, WORK,
      $                   SWORK, RWORK, ITER, INFO )
 *
-*  -- LAPACK driver routine (version 3.4.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            INFO, ITER, LDA, LDB, LDX, N, NRHS
index dfa114d96d3afa012d208bcfba3156fe9d1c1386..4cf9f61e0d07d80ff7dae113dbd6da43eb4e34f7 100644 (file)
 *>               -3 : failure of CPOTRF
 *>               -31: stop the iterative refinement after the 30th
 *>                    iterations
-*>          > 0: iterative refinement has been sucessfully used.
+*>          > 0: iterative refinement has been successfully used.
 *>               Returns the number of iterations
 *> \endverbatim
 *>
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup complex16POsolve
 *
       SUBROUTINE ZCPOSV( UPLO, N, NRHS, A, LDA, B, LDB, X, LDX, WORK,
      $                   SWORK, RWORK, ITER, INFO )
 *
-*  -- LAPACK driver routine (version 3.4.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          UPLO
index 3dce529cd60b4d40ac42782da1b2d37cc1c87fb0..3c53046bfb20841bd2064e9542bee42d949eb290 100644 (file)
@@ -84,7 +84,7 @@
 *>
 *> \param[in] AB
 *> \verbatim
-*>          AB is DOUBLE PRECISION array, dimension (LDAB,N)
+*>          AB is COMPLEX*16 array, dimension (LDAB,N)
 *>          On entry, the matrix A in band storage, in rows 1 to KL+KU+1.
 *>          The j-th column of A is stored in the j-th column of the
 *>          array AB as follows:
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup complex16GBcomputational
 *
       SUBROUTINE ZGBEQUB( M, N, KL, KU, AB, LDAB, R, C, ROWCND, COLCND,
      $                    AMAX, INFO )
 *
-*  -- LAPACK computational routine (version 3.4.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            INFO, KL, KU, LDAB, M, N
index 2b81d403b98a3428c90bfb02a04bea345e79ced7..14972ebb1d88ee923c1e81a61ee2ab856230a937 100644 (file)
 *>
 *> \param[in] B
 *> \verbatim
-*>          B is DOUBLE PRECISION array, dimension (LDB,NRHS)
+*>          B is COMPLEX*16 array, dimension (LDB,NRHS)
 *>     The right hand side matrix B.
 *> \endverbatim
 *>
 *>
 *> \param[out] BERR
 *> \verbatim
-*>          BERR is COMPLEX*16 array, dimension (NRHS)
+*>          BERR is DOUBLE PRECISION array, dimension (NRHS)
 *>     Componentwise relative backward error.  This is the
 *>     componentwise relative backward error of each solution vector X(j)
 *>     (i.e., the smallest relative change in any element of A or B that
      $                    ERR_BNDS_COMP, NPARAMS, PARAMS, WORK, RWORK,
      $                    INFO )
 *
-*  -- LAPACK computational routine (version 3.4.1) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     April 2012
 *
 *     Perform refinement on each right-hand side
 *
-      IF ( REF_TYPE .NE. 0 ) THEN
+      IF ( REF_TYPE .NE. 0 .AND. INFO .EQ. 0 ) THEN
 
          PREC_TYPE = ILAPREC( 'E' )
 
index 4cf4ef319412752f43156fe175659cd3f2e61b13..7868245e71faf831b95b3a88c4a4f933c2c49289 100644 (file)
@@ -83,7 +83,7 @@
 *>
 *> \param[in] SELECT
 *> \verbatim
-*>          SELECT is procedure) LOGICAL FUNCTION of one COMPLEX*16 argument
+*>          SELECT is a LOGICAL FUNCTION of one COMPLEX*16 argument
 *>          SELECT must be declared EXTERNAL in the calling subroutine.
 *>          If SORT = 'S', SELECT is used to select eigenvalues to order
 *>          to the top left of the Schur form.
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup complex16GEeigen
 *
      $                   VS, LDVS, RCONDE, RCONDV, WORK, LWORK, RWORK,
      $                   BWORK, INFO )
 *
-*  -- LAPACK driver routine (version 3.4.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBVS, SENSE, SORT
index a518b4cd9efeafa0422c9f418c12d05542ef039f..1fb35a17526e44a6dd06930317b457c8adea9ca3 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
+*
+*  @precisions fortran z -> c
 *
 *> \ingroup complex16GEeigen
 *
 *  =====================================================================
       SUBROUTINE ZGEEV( JOBVL, JOBVR, N, A, LDA, W, VL, LDVL, VR, LDVR,
      $                  WORK, LWORK, RWORK, INFO )
+      implicit none
 *
-*  -- LAPACK driver routine (version 3.4.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBVL, JOBVR
       LOGICAL            LQUERY, SCALEA, WANTVL, WANTVR
       CHARACTER          SIDE
       INTEGER            HSWORK, I, IBAL, IERR, IHI, ILO, IRWORK, ITAU,
-     $                   IWRK, K, MAXWRK, MINWRK, NOUT
+     $                   IWRK, K, LWORK_TREVC, MAXWRK, MINWRK, NOUT
       DOUBLE PRECISION   ANRM, BIGNUM, CSCALE, EPS, SCL, SMLNUM
       COMPLEX*16         TMP
 *     ..
 *     ..
 *     .. External Subroutines ..
       EXTERNAL           DLABAD, XERBLA, ZDSCAL, ZGEBAK, ZGEBAL, ZGEHRD,
-     $                   ZHSEQR, ZLACPY, ZLASCL, ZSCAL, ZTREVC, ZUNGHR
+     $                   ZHSEQR, ZLACPY, ZLASCL, ZSCAL, ZTREVC3, ZUNGHR
 *     ..
 *     .. External Functions ..
       LOGICAL            LSAME
       EXTERNAL           LSAME, IDAMAX, ILAENV, DLAMCH, DZNRM2, ZLANGE
 *     ..
 *     .. Intrinsic Functions ..
-      INTRINSIC          DBLE, DCMPLX, DCONJG, DIMAG, MAX, SQRT
+      INTRINSIC          DBLE, DCMPLX, CONJG, AIMAG, MAX, SQRT
 *     ..
 *     .. Executable Statements ..
 *
             IF( WANTVL ) THEN
                MAXWRK = MAX( MAXWRK, N + ( N - 1 )*ILAENV( 1, 'ZUNGHR',
      $                       ' ', N, 1, N, -1 ) )
+               CALL ZTREVC3( 'L', 'B', SELECT, N, A, LDA,
+     $                       VL, LDVL, VR, LDVR,
+     $                       N, NOUT, WORK, -1, RWORK, -1, IERR )
+               LWORK_TREVC = INT( WORK(1) )
+               MAXWRK = MAX( MAXWRK, N + LWORK_TREVC )
                CALL ZHSEQR( 'S', 'V', N, 1, N, A, LDA, W, VL, LDVL,
-     $                WORK, -1, INFO )
+     $                      WORK, -1, INFO )
             ELSE IF( WANTVR ) THEN
                MAXWRK = MAX( MAXWRK, N + ( N - 1 )*ILAENV( 1, 'ZUNGHR',
      $                       ' ', N, 1, N, -1 ) )
+               CALL ZTREVC3( 'R', 'B', SELECT, N, A, LDA,
+     $                       VL, LDVL, VR, LDVR,
+     $                       N, NOUT, WORK, -1, RWORK, -1, IERR )
+               LWORK_TREVC = INT( WORK(1) )
+               MAXWRK = MAX( MAXWRK, N + LWORK_TREVC )
                CALL ZHSEQR( 'S', 'V', N, 1, N, A, LDA, W, VR, LDVR,
-     $                WORK, -1, INFO )
+     $                      WORK, -1, INFO )
             ELSE
                CALL ZHSEQR( 'E', 'N', N, 1, N, A, LDA, W, VR, LDVR,
-     $                WORK, -1, INFO )
+     $                      WORK, -1, INFO )
             END IF
-            HSWORK = WORK( 1 )
+            HSWORK = INT( WORK(1) )
             MAXWRK = MAX( MAXWRK, HSWORK, MINWRK )
          END IF
          WORK( 1 ) = MAXWRK
       IF( WANTVL .OR. WANTVR ) THEN
 *
 *        Compute left and/or right eigenvectors
-*        (CWorkspace: need 2*N)
+*        (CWorkspace: need 2*N, prefer N + 2*N*NB)
 *        (RWorkspace: need 2*N)
 *
          IRWORK = IBAL + N
-         CALL ZTREVC( SIDE, 'B', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,
-     $                N, NOUT, WORK( IWRK ), RWORK( IRWORK ), IERR )
+         CALL ZTREVC3( SIDE, 'B', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,
+     $                 N, NOUT, WORK( IWRK ), LWORK-IWRK+1,
+     $                 RWORK( IRWORK ), N, IERR )
       END IF
 *
       IF( WANTVL ) THEN
             CALL ZDSCAL( N, SCL, VL( 1, I ), 1 )
             DO 10 K = 1, N
                RWORK( IRWORK+K-1 ) = DBLE( VL( K, I ) )**2 +
-     $                               DIMAG( VL( K, I ) )**2
+     $                               AIMAG( VL( K, I ) )**2
    10       CONTINUE
             K = IDAMAX( N, RWORK( IRWORK ), 1 )
-            TMP = DCONJG( VL( K, I ) ) / SQRT( RWORK( IRWORK+K-1 ) )
+            TMP = CONJG( VL( K, I ) ) / SQRT( RWORK( IRWORK+K-1 ) )
             CALL ZSCAL( N, TMP, VL( 1, I ), 1 )
             VL( K, I ) = DCMPLX( DBLE( VL( K, I ) ), ZERO )
    20    CONTINUE
             CALL ZDSCAL( N, SCL, VR( 1, I ), 1 )
             DO 30 K = 1, N
                RWORK( IRWORK+K-1 ) = DBLE( VR( K, I ) )**2 +
-     $                               DIMAG( VR( K, I ) )**2
+     $                               AIMAG( VR( K, I ) )**2
    30       CONTINUE
             K = IDAMAX( N, RWORK( IRWORK ), 1 )
-            TMP = DCONJG( VR( K, I ) ) / SQRT( RWORK( IRWORK+K-1 ) )
+            TMP = CONJG( VR( K, I ) ) / SQRT( RWORK( IRWORK+K-1 ) )
             CALL ZSCAL( N, TMP, VR( 1, I ), 1 )
             VR( K, I ) = DCMPLX( DBLE( VR( K, I ) ), ZERO )
    40    CONTINUE
index 402eec799f6c09be3eb1367ac78548bb7395b441..752d0328e1218799a204e711d05244dfd6e9be24 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
+*
+*  @precisions fortran z -> c
 *
 *> \ingroup complex16GEeigen
 *
       SUBROUTINE ZGEEVX( BALANC, JOBVL, JOBVR, SENSE, N, A, LDA, W, VL,
      $                   LDVL, VR, LDVR, ILO, IHI, SCALE, ABNRM, RCONDE,
      $                   RCONDV, WORK, LWORK, RWORK, INFO )
+      implicit none
 *
-*  -- LAPACK driver routine (version 3.4.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          BALANC, JOBVL, JOBVR, SENSE
       LOGICAL            LQUERY, SCALEA, WANTVL, WANTVR, WNTSNB, WNTSNE,
      $                   WNTSNN, WNTSNV
       CHARACTER          JOB, SIDE
-      INTEGER            HSWORK, I, ICOND, IERR, ITAU, IWRK, K, MAXWRK,
-     $                   MINWRK, NOUT
+      INTEGER            HSWORK, I, ICOND, IERR, ITAU, IWRK, K,
+     $                   LWORK_TREVC, MAXWRK, MINWRK, NOUT
       DOUBLE PRECISION   ANRM, BIGNUM, CSCALE, EPS, SCL, SMLNUM
       COMPLEX*16         TMP
 *     ..
 *     ..
 *     .. External Subroutines ..
       EXTERNAL           DLABAD, DLASCL, XERBLA, ZDSCAL, ZGEBAK, ZGEBAL,
-     $                   ZGEHRD, ZHSEQR, ZLACPY, ZLASCL, ZSCAL, ZTREVC,
+     $                   ZGEHRD, ZHSEQR, ZLACPY, ZLASCL, ZSCAL, ZTREVC3,
      $                   ZTRSNA, ZUNGHR
 *     ..
 *     .. External Functions ..
       EXTERNAL           LSAME, IDAMAX, ILAENV, DLAMCH, DZNRM2, ZLANGE
 *     ..
 *     .. Intrinsic Functions ..
-      INTRINSIC          DBLE, DCMPLX, DCONJG, DIMAG, MAX, SQRT
+      INTRINSIC          DBLE, DCMPLX, CONJG, AIMAG, MAX, SQRT
 *     ..
 *     .. Executable Statements ..
 *
             MAXWRK = N + N*ILAENV( 1, 'ZGEHRD', ' ', N, 1, N, 0 )
 *
             IF( WANTVL ) THEN
+               CALL ZTREVC3( 'L', 'B', SELECT, N, A, LDA,
+     $                       VL, LDVL, VR, LDVR,
+     $                       N, NOUT, WORK, -1, RWORK, -1, IERR )
+               LWORK_TREVC = INT( WORK(1) )
+               MAXWRK = MAX( MAXWRK, LWORK_TREVC )
                CALL ZHSEQR( 'S', 'V', N, 1, N, A, LDA, W, VL, LDVL,
      $                WORK, -1, INFO )
             ELSE IF( WANTVR ) THEN
+               CALL ZTREVC3( 'R', 'B', SELECT, N, A, LDA,
+     $                       VL, LDVL, VR, LDVR,
+     $                       N, NOUT, WORK, -1, RWORK, -1, IERR )
+               LWORK_TREVC = INT( WORK(1) )
+               MAXWRK = MAX( MAXWRK, LWORK_TREVC )
                CALL ZHSEQR( 'S', 'V', N, 1, N, A, LDA, W, VR, LDVR,
      $                WORK, -1, INFO )
             ELSE
      $                WORK, -1, INFO )
                END IF
             END IF
-            HSWORK = WORK( 1 )
+            HSWORK = INT( WORK(1) )
 *
             IF( ( .NOT.WANTVL ) .AND. ( .NOT.WANTVR ) ) THEN
                MINWRK = 2*N
      $                WORK( IWRK ), LWORK-IWRK+1, INFO )
       END IF
 *
-*     If INFO > 0 from ZHSEQR, then quit
+*     If INFO .NE. 0 from ZHSEQR, then quit
 *
-      IF( INFO.GT.0 )
+      IF( INFO.NE.0 )
      $   GO TO 50
 *
       IF( WANTVL .OR. WANTVR ) THEN
 *
 *        Compute left and/or right eigenvectors
-*        (CWorkspace: need 2*N)
+*        (CWorkspace: need 2*N, prefer N + 2*N*NB)
 *        (RWorkspace: need N)
 *
-         CALL ZTREVC( SIDE, 'B', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,
-     $                N, NOUT, WORK( IWRK ), RWORK, IERR )
+         CALL ZTREVC3( SIDE, 'B', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,
+     $                 N, NOUT, WORK( IWRK ), LWORK-IWRK+1,
+     $                 RWORK, N, IERR )
       END IF
 *
 *     Compute condition numbers if desired
             CALL ZDSCAL( N, SCL, VL( 1, I ), 1 )
             DO 10 K = 1, N
                RWORK( K ) = DBLE( VL( K, I ) )**2 +
-     $                      DIMAG( VL( K, I ) )**2
+     $                      AIMAG( VL( K, I ) )**2
    10       CONTINUE
             K = IDAMAX( N, RWORK, 1 )
-            TMP = DCONJG( VL( K, I ) ) / SQRT( RWORK( K ) )
+            TMP = CONJG( VL( K, I ) ) / SQRT( RWORK( K ) )
             CALL ZSCAL( N, TMP, VL( 1, I ), 1 )
             VL( K, I ) = DCMPLX( DBLE( VL( K, I ) ), ZERO )
    20    CONTINUE
             CALL ZDSCAL( N, SCL, VR( 1, I ), 1 )
             DO 30 K = 1, N
                RWORK( K ) = DBLE( VR( K, I ) )**2 +
-     $                      DIMAG( VR( K, I ) )**2
+     $                      AIMAG( VR( K, I ) )**2
    30       CONTINUE
             K = IDAMAX( N, RWORK, 1 )
-            TMP = DCONJG( VR( K, I ) ) / SQRT( RWORK( K ) )
+            TMP = CONJG( VR( K, I ) ) / SQRT( RWORK( K ) )
             CALL ZSCAL( N, TMP, VR( 1, I ), 1 )
             VR( K, I ) = DCMPLX( DBLE( VR( K, I ) ), ZERO )
    40    CONTINUE
index 62274f3a24c3b2fb8415ec97028f3a4b57af9aee..ad47a4079145c06d0efc64bf11219f764f4dc8e4 100644 (file)
@@ -27,7 +27,7 @@
 *     INTEGER     INFO, LDA, LDU, LDV, LWORK, M, N
 *     ..
 *     .. Array Arguments ..
-*     DOUBLE COMPLEX     A( LDA, * ),  U( LDU, * ), V( LDV, * ), CWORK( LWORK )
+*     COMPLEX*16     A( LDA, * ),  U( LDU, * ), V( LDV, * ), CWORK( LWORK )
 *     DOUBLE PRECISION   SVA( N ), RWORK( LRWORK )      
 *     INTEGER     IWORK( * )
 *     CHARACTER*1 JOBA, JOBP, JOBR, JOBT, JOBU, JOBV
 *>
 *> \verbatim
 *>
-* ZGEJSV computes the singular value decomposition (SVD) of a real M-by-N
-* matrix [A], where M >= N. The SVD of [A] is written as
-*
-*              [A] = [U] * [SIGMA] * [V]^*,
-*
-* where [SIGMA] is an N-by-N (M-by-N) matrix which is zero except for its N
-* diagonal elements, [U] is an M-by-N (or M-by-M) orthonormal matrix, and
-* [V] is an N-by-N orthogonal matrix. The diagonal elements of [SIGMA] are
-* the singular values of [A]. The columns of [U] and [V] are the left and
-* the right singular vectors of [A], respectively. The matrices [U] and [V]
-* are computed and stored in the arrays U and V, respectively. The diagonal
-* of [SIGMA] is computed and stored in the array SVA.
-*
-*  Arguments:
-*  ==========
+*> ZGEJSV computes the singular value decomposition (SVD) of a complex M-by-N
+*> matrix [A], where M >= N. The SVD of [A] is written as
+*>
+*>              [A] = [U] * [SIGMA] * [V]^*,
+*>
+*> where [SIGMA] is an N-by-N (M-by-N) matrix which is zero except for its N
+*> diagonal elements, [U] is an M-by-N (or M-by-M) unitary matrix, and
+*> [V] is an N-by-N unitary matrix. The diagonal elements of [SIGMA] are
+*> the singular values of [A]. The columns of [U] and [V] are the left and
+*> the right singular vectors of [A], respectively. The matrices [U] and [V]
+*> are computed and stored in the arrays U and V, respectively. The diagonal
+*> of [SIGMA] is computed and stored in the array SVA.
+*> \endverbatim
+*>
+*>  Arguments:
+*>  ==========
 *>
 *> \param[in] JOBA
 *> \verbatim
 *>
 *> \param[in,out] A
 *> \verbatim
-*>          A is DOUBLE COMPLEX array, dimension (LDA,N)
+*>          A is COMPLEX*16 array, dimension (LDA,N)
 *>          On entry, the M-by-N matrix A.
 *> \endverbatim
 *>
 *>
 *> \param[out] U
 *> \verbatim
-*>          U is DOUBLE COMPLEX array, dimension ( LDU, N )
+*>          U is COMPLEX*16 array, dimension ( LDU, N )
 *>          If JOBU = 'U', then U contains on exit the M-by-N matrix of
 *>                         the left singular vectors.
 *>          If JOBU = 'F', then U contains on exit the M-by-M matrix of
 *>                         copied back to the V array. This 'W' option is just
 *>                         a reminder to the caller that in this case U is
 *>                         reserved as workspace of length N*N.
-*>          If JOBU = 'N'  U is not referenced.
+*>          If JOBU = 'N'  U is not referenced, unless JOBT='T'.
 *> \endverbatim
 *>
 *> \param[in] LDU
 *>
 *> \param[out] V
 *> \verbatim
-*>          V is DOUBLE COMPLEX array, dimension ( LDV, N )
+*>          V is COMPLEX*16 array, dimension ( LDV, N )
 *>          If JOBV = 'V', 'J' then V contains on exit the N-by-N matrix of
 *>                         the right singular vectors;
 *>          If JOBV = 'W', AND (JOBU.EQ.'U' AND JOBT.EQ.'T' AND M.EQ.N),
 *>                         copied back to the U array. This 'W' option is just
 *>                         a reminder to the caller that in this case V is
 *>                         reserved as workspace of length N*N.
-*>          If JOBV = 'N'  V is not referenced.
+*>          If JOBV = 'N'  V is not referenced, unless JOBT='T'.
 *> \endverbatim
 *>
 *> \param[in] LDV
 *>
 *> \param[out] CWORK
 *> \verbatim
-*> CWORK (workspace)
-*>          CWORK is DOUBLE COMPLEX array, dimension at least LWORK.     
+*>          CWORK is COMPLEX*16 array, dimension at least LWORK.     
 *> \endverbatim
 *>
 *> \param[in] LWORK
 *>          LWORK depends on the job:
 *>
 *>          1. If only SIGMA is needed ( JOBU.EQ.'N', JOBV.EQ.'N' ) and
-*>            1.1 .. no scaled condition estimate required (JOBE.EQ.'N'):
+*>            1.1 .. no scaled condition estimate required (JOBA.NE.'E'.AND.JOBA.NE.'G'):
 *>               LWORK >= 2*N+1. This is the minimal requirement.
 *>               ->> For optimal performance (blocked code) the optimal value
 *>               is LWORK >= N + (N+1)*NB. Here NB is the optimal
 *>               is LWORK >= max(N+(N+1)*NB, N*N+3*N).
 *>               In general, the optimal length LWORK is computed as
 *>               LWORK >= max(N+LWORK(ZGEQP3),N+LWORK(ZGEQRF), 
-*>                                                     N+N*N+LWORK(CPOCON)).
+*>                                                     N+N*N+LWORK(ZPOCON)).
 *>
 *>          2. If SIGMA and the right singular vectors are needed (JOBV.EQ.'V'),
 *>             (JOBU.EQ.'N')
 *>            -> the minimal requirement is LWORK >= 3*N.
 *>            -> For optimal performance, LWORK >= max(N+(N+1)*NB, 3*N,2*N+N*NB),
-*>               where NB is the optimal block size for ZGEQP3, ZGEQRF, ZGELQ,
-*>               CUNMLQ. In general, the optimal length LWORK is computed as
-*>               LWORK >= max(N+LWORK(ZGEQP3), N+LWORK(CPOCON), N+LWORK(ZGESVJ),
-*>                       N+LWORK(ZGELQF), 2*N+LWORK(ZGEQRF), N+LWORK(CUNMLQ)).
+*>               where NB is the optimal block size for ZGEQP3, ZGEQRF, ZGELQF,
+*>               ZUNMLQ. In general, the optimal length LWORK is computed as
+*>               LWORK >= max(N+LWORK(ZGEQP3), N+LWORK(ZPOCON), N+LWORK(ZGESVJ),
+*>                       N+LWORK(ZGELQF), 2*N+LWORK(ZGEQRF), N+LWORK(ZUNMLQ)).
 *>
 *>          3. If SIGMA and the left singular vectors are needed
 *>            -> the minimal requirement is LWORK >= 3*N.
 *>            -> For optimal performance:
 *>               if JOBU.EQ.'U' :: LWORK >= max(3*N, N+(N+1)*NB, 2*N+N*NB),
-*>               where NB is the optimal block size for ZGEQP3, ZGEQRF, CUNMQR.
+*>               where NB is the optimal block size for ZGEQP3, ZGEQRF, ZUNMQR.
 *>               In general, the optimal length LWORK is computed as
-*>               LWORK >= max(N+LWORK(ZGEQP3),N+LWORK(CPOCON),
-*>                        2*N+LWORK(ZGEQRF), N+LWORK(CUNMQR)). 
+*>               LWORK >= max(N+LWORK(ZGEQP3),N+LWORK(ZPOCON),
+*>                        2*N+LWORK(ZGEQRF), N+LWORK(ZUNMQR)). 
 *>               
 *>          4. If the full SVD is needed: (JOBU.EQ.'U' or JOBU.EQ.'F') and 
 *>            4.1. if JOBV.EQ.'V'  
 *>               the minimal requirement is LWORK >= 5*N+2*N*N. 
 *>            4.2. if JOBV.EQ.'J' the minimal requirement is 
 *>               LWORK >= 4*N+N*N.
-*>            In both cases, the allocated CWORK can accomodate blocked runs
-*>            of ZGEQP3, ZGEQRF, ZGELQF, SUNMQR, CUNMLQ.
+*>            In both cases, the allocated CWORK can accommodate blocked runs
+*>            of ZGEQP3, ZGEQRF, ZGELQF, ZUNMQR, ZUNMLQ.
 *> \endverbatim
 *>
 *> \param[out] RWORK
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complex16GEsing
 *
 *>
 *> \verbatim
 *>
-* [1] Z. Drmac and K. Veselic: New fast and accurate Jacobi SVD algorithm I.
-*     SIAM J. Matrix Anal. Appl. Vol. 35, No. 2 (2008), pp. 1322-1342.
-*     LAPACK Working note 169.
-* [2] Z. Drmac and K. Veselic: New fast and accurate Jacobi SVD algorithm II.
-*     SIAM J. Matrix Anal. Appl. Vol. 35, No. 2 (2008), pp. 1343-1362.
-*     LAPACK Working note 170.
-* [3] Z. Drmac and Z. Bujanovic: On the failure of rank-revealing QR
-*     factorization software - a case study.
-*     ACM Trans. math. Softw. Vol. 35, No 2 (2008), pp. 1-28.
-*     LAPACK Working note 176.
-* [4] Z. Drmac: SIGMA - mathematical software library for accurate SVD, PSV,
-*     QSVD, (H,K)-SVD computations.
-*     Department of Mathematics, University of Zagreb, 2008.
+*> [1] Z. Drmac and K. Veselic: New fast and accurate Jacobi SVD algorithm I.
+*>     SIAM J. Matrix Anal. Appl. Vol. 35, No. 2 (2008), pp. 1322-1342.
+*>     LAPACK Working note 169.
+*> [2] Z. Drmac and K. Veselic: New fast and accurate Jacobi SVD algorithm II.
+*>     SIAM J. Matrix Anal. Appl. Vol. 35, No. 2 (2008), pp. 1343-1362.
+*>     LAPACK Working note 170.
+*> [3] Z. Drmac and Z. Bujanovic: On the failure of rank-revealing QR
+*>     factorization software - a case study.
+*>     ACM Trans. Math. Softw. Vol. 35, No 2 (2008), pp. 1-28.
+*>     LAPACK Working note 176.
+*> [4] Z. Drmac: SIGMA - mathematical software library for accurate SVD, PSV,
+*>     QSVD, (H,K)-SVD computations.
+*>     Department of Mathematics, University of Zagreb, 2008.
 *> \endverbatim
 *
 *>  \par Bugs, examples and comments:
      $                   M, N, A, LDA, SVA, U, LDU, V, LDV,
      $                   CWORK, LWORK, RWORK, LRWORK, IWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       IMPLICIT    NONE
       INTEGER     INFO, LDA, LDU, LDV, LWORK, LRWORK, M, N
 *     ..
 *     .. Array Arguments ..
-      DOUBLE COMPLEX   A( LDA, * ), U( LDU, * ), V( LDV, * ), 
+      COMPLEX*16       A( LDA, * ), U( LDU, * ), V( LDV, * ), 
      $                 CWORK( LWORK )
       DOUBLE PRECISION SVA( N ), RWORK( * )
       INTEGER          IWORK( * )
 *     .. Local Parameters ..
       DOUBLE PRECISION ZERO,         ONE
       PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
-      DOUBLE COMPLEX            CZERO,       CONE
+      COMPLEX*16                CZERO,       CONE
       PARAMETER  ( CZERO = ( 0.0D0, 0.0D0 ), CONE = ( 1.0D0, 0.0D0 ) )
 *     ..
 *     .. Local Scalars ..
-      DOUBLE COMPLEX   CTEMP
+      COMPLEX*16       CTEMP
       DOUBLE PRECISION AAPP,    AAQQ,   AATMAX, AATMIN, BIG,    BIG1,   
      $                 COND_OK, CONDR1, CONDR2, ENTRA,  ENTRAT, EPSLN,  
      $                 MAXPRJ,  SCALEM, SCONDA, SFMIN,  SMALL,  TEMP1,  
      $        NOSCAL, ROWPIV, RSVEC,  TRANSP
 *     ..
 *     .. Intrinsic Functions ..
-      INTRINSIC ABS,  DCMPLX, DCONJG, DLOG, DMAX1, DMIN1, DFLOAT,
+      INTRINSIC ABS,  DCMPLX, DCONJG, DLOG, DMAX1, DMIN1, DBLE,
      $          MAX0, MIN0, NINT,  DSQRT
 *     ..
 *     .. External Functions ..
       DOUBLE PRECISION      DLAMCH, DZNRM2
-      INTEGER   IDAMAX
+      INTEGER   IDAMAX, IZAMAX
       LOGICAL   LSAME
-      EXTERNAL  IDAMAX, LSAME, DLAMCH, DZNRM2
+      EXTERNAL  IDAMAX, IZAMAX, LSAME, DLAMCH, DZNRM2
 *     ..
 *     .. External Subroutines ..
-      EXTERNAL  ZCOPY,  ZGELQF, ZGEQP3, ZGEQRF, ZLACPY, ZLASCL,
-     $          ZLASET, ZLASSQ, ZLASWP, ZUNGQR, ZUNMLQ,
+      EXTERNAL  DLASSQ, ZCOPY,  ZGELQF, ZGEQP3, ZGEQRF, ZLACPY, ZLASCL,
+     $          DLASCL, ZLASET, ZLASSQ, ZLASWP, ZUNGQR, ZUNMLQ,
      $          ZUNMQR, ZPOCON, DSCAL, ZDSCAL, ZSWAP,  ZTRSM,  XERBLA
 *
       EXTERNAL  ZGESVJ
 *
 *     Quick return for void matrix (Y3K safe)
 * #:)
-      IF ( ( M .EQ. 0 ) .OR. ( N .EQ. 0 ) ) RETURN
+      IF ( ( M .EQ. 0 ) .OR. ( N .EQ. 0 ) ) THEN
+         IWORK(1:3) = 0
+         RWORK(1:7) = 0
+         RETURN
+      ENDIF
 *
 *     Determine whether the matrix U should be M x N or M x M
 *
 *     overflow. It is possible that this scaling pushes the smallest
 *     column norm left from the underflow threshold (extreme case).
 *
-      SCALEM  = ONE / DSQRT(DFLOAT(M)*DFLOAT(N))
+      SCALEM  = ONE / DSQRT(DBLE(M)*DBLE(N))
       NOSCAL  = .TRUE.
       GOSCAL  = .TRUE.
       DO 1874 p = 1, N
  1950       CONTINUE
          ELSE
             DO 1904 p = 1, M
-               RWORK(M+N+p) = SCALEM*ABS( A(p,IDAMAX(N,A(p,1),LDA)) )
+               RWORK(M+N+p) = SCALEM*ABS( A(p,IZAMAX(N,A(p,1),LDA)) )
                AATMAX = DMAX1( AATMAX, RWORK(M+N+p) )
                AATMIN = DMIN1( AATMIN, RWORK(M+N+p) )
  1904       CONTINUE
 *
          XSC   = ZERO
          TEMP1 = ONE
-         CALL ZLASSQ( N, SVA, 1, XSC, TEMP1 )
+         CALL DLASSQ( N, SVA, 1, XSC, TEMP1 )
          TEMP1 = ONE / TEMP1
 *
          ENTRA = ZERO
             BIG1  = ( ( SVA(p) / XSC )**2 ) * TEMP1
             IF ( BIG1 .NE. ZERO ) ENTRA = ENTRA + BIG1 * DLOG(BIG1)
  1113    CONTINUE
-         ENTRA = - ENTRA / DLOG(DFLOAT(N))
+         ENTRA = - ENTRA / DLOG(DBLE(N))
 *
 *        Now, SVA().^2/Trace(A^* * A) is a point in the probability simplex.
 *        It is derived from the diagonal of  A^* * A.  Do the same with the
             BIG1 = ( ( RWORK(p) / XSC )**2 ) * TEMP1
             IF ( BIG1 .NE. ZERO ) ENTRAT = ENTRAT + BIG1 * DLOG(BIG1)
  1114    CONTINUE
-         ENTRAT = - ENTRAT / DLOG(DFLOAT(M))
+         ENTRAT = - ENTRAT / DLOG(DBLE(M))
 *
 *        Analyze the entropies and decide A or A^*. Smaller entropy
 *        usually means better input for the algorithm.
 *     one should use ZGESVJ instead of ZGEJSV.
 *
       BIG1   = DSQRT( BIG )
-      TEMP1  = DSQRT( BIG / DFLOAT(N) )
+      TEMP1  = DSQRT( BIG / DBLE(N) )
 *
-      CALL ZLASCL( 'G', 0, 0, AAPP, TEMP1, N, 1, SVA, N, IERR )
+      CALL DLASCL( 'G', 0, 0, AAPP, TEMP1, N, 1, SVA, N, IERR )
       IF ( AAQQ .GT. (AAPP * SFMIN) ) THEN
           AAQQ = ( AAQQ / AAPP ) * TEMP1
       ELSE
 *        sigma_i < N*EPSLN*||A|| are flushed to zero. This is an
 *        agressive enforcement of lower numerical rank by introducing a
 *        backward error of the order of N*EPSLN*||A||.
-         TEMP1 = DSQRT(DFLOAT(N))*EPSLN
+         TEMP1 = DSQRT(DBLE(N))*EPSLN
          DO 3001 p = 2, N
             IF ( ABS(A(p,p)) .GE. (TEMP1*ABS(A(1,1))) ) THEN
                NR = NR + 1
             TEMP1  = ABS(A(p,p)) / SVA(IWORK(p))
             MAXPRJ = DMIN1( MAXPRJ, TEMP1 )
  3051    CONTINUE
-         IF ( MAXPRJ**2 .GE. ONE - DFLOAT(N)*EPSLN ) ALMORT = .TRUE.
+         IF ( MAXPRJ**2 .GE. ONE - DBLE(N)*EPSLN ) ALMORT = .TRUE.
       END IF
 *
 *
 *
             IF ( L2PERT ) THEN
 *              XSC = SQRT(SMALL)
-               XSC = EPSLN / DFLOAT(N)
+               XSC = EPSLN / DBLE(N)
                DO 4947 q = 1, NR
                   CTEMP = DCMPLX(XSC*ABS(A(q,q)),ZERO)
                   DO 4949 p = 1, N
 *           to drown denormals
             IF ( L2PERT ) THEN
 *              XSC = SQRT(SMALL)
-               XSC = EPSLN / DFLOAT(N)
+               XSC = EPSLN / DBLE(N)
                DO 1947 q = 1, NR
                   CTEMP = DCMPLX(XSC*ABS(A(q,q)),ZERO)
                   DO 1949 p = 1, NR
                CALL ZCOPY( NR-p+1, V(p,p), LDV, V(p,p), 1 )
                CALL ZLACGV( NR-p+1, V(p,p), 1 ) 
  8998       CONTINUE
-            CALL ZLASET( 'Upper', NR-1, NR-1, ZERO, ZERO, V(1,2), LDV )
+            CALL ZLASET('Upper', NR-1, NR-1, CZERO, CZERO, V(1,2), LDV)
 *
             CALL ZGESVJ( 'Lower', 'U','N', NR, NR, V,LDV, SVA, NR, U,
      $                  LDU, CWORK(N+1), LWORK-N, RWORK, LRWORK, INFO )
             CONDR1 = ONE / DSQRT(TEMP1)
 *           .. here need a second oppinion on the condition number
 *           .. then assume worst case scenario
-*           R1 is OK for inverse <=> CONDR1 .LT. DFLOAT(N)
-*           more conservative    <=> CONDR1 .LT. SQRT(DFLOAT(N))
+*           R1 is OK for inverse <=> CONDR1 .LT. DBLE(N)
+*           more conservative    <=> CONDR1 .LT. SQRT(DBLE(N))
 *
-            COND_OK = DSQRT(DSQRT(DFLOAT(NR)))
+            COND_OK = DSQRT(DSQRT(DBLE(NR)))
 *[TP]       COND_OK is a tuning parameter.
 *
             IF ( CONDR1 .LT. COND_OK ) THEN
                   CALL ZTRSM('L','U','C','N',NR,NR,CONE,CWORK(2*N+1),
      $                 N,V,LDV)
                   IF ( NR .LT. N ) THEN
-                   CALL ZLASET('A',N-NR,NR,ZERO,CZERO,V(NR+1,1),LDV)
-                   CALL ZLASET('A',NR,N-NR,ZERO,CZERO,V(1,NR+1),LDV)
-                   CALL ZLASET('A',N-NR,N-NR,ZERO,CONE,V(NR+1,NR+1),LDV)
+                  CALL ZLASET('A',N-NR,NR,CZERO,CZERO,V(NR+1,1),LDV)
+                  CALL ZLASET('A',NR,N-NR,CZERO,CZERO,V(1,NR+1),LDV)
+                  CALL ZLASET('A',N-NR,N-NR,CZERO,CONE,V(NR+1,NR+1),LDV)
                   END IF
                   CALL ZUNMQR('L','N',N,N,NR,CWORK(2*N+1),N,CWORK(N+1),
      $                V,LDV,CWORK(2*N+N*NR+NR+1),LWORK-2*N-N*NR-NR,IERR)
 *           first QRF. Also, scale the columns to make them unit in
 *           Euclidean norm. This applies to all cases.
 *
-            TEMP1 = DSQRT(DFLOAT(N)) * EPSLN
+            TEMP1 = DSQRT(DBLE(N)) * EPSLN
             DO 1972 q = 1, N
                DO 972 p = 1, N
                   CWORK(2*N+N*NR+NR+IWORK(p)) = V(p,q)
      $           LDU, CWORK(N+1), LWORK-N, IERR )
 
 *           The columns of U are normalized. The cost is O(M*N) flops.
-            TEMP1 = DSQRT(DFLOAT(M)) * EPSLN
+            TEMP1 = DSQRT(DBLE(M)) * EPSLN
             DO 1973 p = 1, NR
                XSC = ONE / DZNRM2( M, U(1,p), 1 )
                IF ( (XSC .LT. (ONE-TEMP1)) .OR. (XSC .GT. (ONE+TEMP1)) )
             DO 6972 p = 1, N
                CALL ZCOPY( N, CWORK(N+p), N, V(IWORK(p),1), LDV )
  6972       CONTINUE
-            TEMP1 = DSQRT(DFLOAT(N))*EPSLN
+            TEMP1 = DSQRT(DBLE(N))*EPSLN
             DO 6971 p = 1, N
                XSC = ONE / DZNRM2( N, V(1,p), 1 )
                IF ( (XSC .LT. (ONE-TEMP1)) .OR. (XSC .GT. (ONE+TEMP1)) )
             END IF
             CALL ZUNMQR( 'Left', 'No Tr', M, N1, N, A, LDA, CWORK, U,
      $           LDU, CWORK(N+1), LWORK-N, IERR )
-            TEMP1 = DSQRT(DFLOAT(M))*EPSLN
+            TEMP1 = DSQRT(DBLE(M))*EPSLN
             DO 6973 p = 1, N1
                XSC = ONE / DZNRM2( M, U(1,p), 1 )
                IF ( (XSC .LT. (ONE-TEMP1)) .OR. (XSC .GT. (ONE+TEMP1)) )
          NUMRANK = NINT(RWORK(2))
 
          IF ( NR .LT. N ) THEN
-            CALL ZLASET( 'A',N-NR,NR,ZERO,ZERO,V(NR+1,1),LDV )
-            CALL ZLASET( 'A',NR,N-NR,ZERO,ZERO,V(1,NR+1),LDV )
-            CALL ZLASET( 'A',N-NR,N-NR,ZERO,ONE,V(NR+1,NR+1),LDV )
+            CALL ZLASET( 'A',N-NR,NR,CZERO,CZERO,V(NR+1,1),LDV )
+            CALL ZLASET( 'A',NR,N-NR,CZERO,CZERO,V(1,NR+1),LDV )
+            CALL ZLASET( 'A',N-NR,N-NR,CZERO,CONE,V(NR+1,NR+1),LDV )
          END IF
 
          CALL ZUNMQR( 'L','N',N,N,NR,CWORK(2*N+1),N,CWORK(N+1),
 *           first QRF. Also, scale the columns to make them unit in
 *           Euclidean norm. This applies to all cases.
 *
-            TEMP1 = DSQRT(DFLOAT(N)) * EPSLN
+            TEMP1 = DSQRT(DBLE(N)) * EPSLN
             DO 7972 q = 1, N
                DO 8972 p = 1, N
                   CWORK(2*N+N*NR+NR+IWORK(p)) = V(p,q)
 *     Undo scaling, if necessary (and possible)
 *
       IF ( USCAL2 .LE. (BIG/SVA(1))*USCAL1 ) THEN
-         CALL ZLASCL( 'G', 0, 0, USCAL1, USCAL2, NR, 1, SVA, N, IERR )
+         CALL DLASCL( 'G', 0, 0, USCAL1, USCAL2, NR, 1, SVA, N, IERR )
          USCAL1 = ONE
          USCAL2 = ONE
       END IF
index 56e58ddfe5caa6b4ad94240bfd1cca86240a8753..b99535a64b6321c8d78bd29a69ba5712e387e247 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup complex16GEsolve
 *
       SUBROUTINE ZGELSS( M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK,
      $                   WORK, LWORK, RWORK, INFO )
 *
-*  -- LAPACK driver routine (version 3.4.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
 *              Path 1 - overdetermined or exactly determined
 *
 *              Compute space needed for ZGEBRD
-               CALL ZGEBRD( MM, N, A, LDA, S, DUM(1), DUM(1),
-     $                      DUM(1), DUM(1), -1, INFO )
+               CALL ZGEBRD( MM, N, A, LDA, S, S, DUM(1), DUM(1), DUM(1),
+     $                      -1, INFO )
                LWORK_ZGEBRD=DUM(1)
 *              Compute space needed for ZUNMBR
                CALL ZUNMBR( 'Q', 'L', 'C', MM, NRHS, N, A, LDA, DUM(1),
      $                -1, INFO )
                   LWORK_ZGELQF=DUM(1)
 *                 Compute space needed for ZGEBRD
-                  CALL ZGEBRD( M, M, A, LDA, S, DUM(1), DUM(1),
-     $                      DUM(1), DUM(1), -1, INFO )
+                  CALL ZGEBRD( M, M, A, LDA, S, S, DUM(1), DUM(1),
+     $                         DUM(1), -1, INFO )
                   LWORK_ZGEBRD=DUM(1)
 *                 Compute space needed for ZUNMBR
                   CALL ZUNMBR( 'Q', 'L', 'C', M, NRHS, N, A, LDA, 
 *                 Path 2 - underdetermined
 *
 *                 Compute space needed for ZGEBRD
-                  CALL ZGEBRD( M, N, A, LDA, S, DUM(1), DUM(1),
-     $                      DUM(1), DUM(1), -1, INFO )
+                  CALL ZGEBRD( M, N, A, LDA, S, S, DUM(1), DUM(1),
+     $                         DUM(1), -1, INFO )
                   LWORK_ZGEBRD=DUM(1)
 *                 Compute space needed for ZUNMBR
                   CALL ZUNMBR( 'Q', 'L', 'C', M, NRHS, M, A, LDA, 
index 8926b9980b8df86a600febf4459d38a8844d5cb1..6995a289c5cbcef05f3c8bfc6eaf2e93d426cb7c 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup complex16GEcomputational
 *
 *  =====================================================================
       RECURSIVE SUBROUTINE ZGEQRT3( M, N, A, LDA, T, LDT, INFO )
 *
-*  -- LAPACK computational routine (version 3.4.2) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER   INFO, LDA, M, N, LDT
 *
 *        Compute Householder transform when N=1
 *
-         CALL ZLARFG( M, A, A( MIN( 2, M ), 1 ), 1, T )
+         CALL ZLARFG( M, A(1,1), A( MIN( 2, M ), 1 ), 1, T(1,1) )
 *         
       ELSE
 *
index ea08dbc6dbf44272baae155b3bed17845c54fc69..4f3201756bcd812f183401c10a21c7574ddf7273 100644 (file)
@@ -18,8 +18,8 @@
 *  Definition:
 *  ===========
 *
-*       SUBROUTINE ZGESDD( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK,
-*                          LWORK, RWORK, IWORK, INFO )
+*       SUBROUTINE ZGESDD( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT,
+*                          WORK, LWORK, RWORK, IWORK, INFO )
 * 
 *       .. Scalar Arguments ..
 *       CHARACTER          JOBZ
 *> \param[in] LDU
 *> \verbatim
 *>          LDU is INTEGER
-*>          The leading dimension of the array U.  LDU >= 1; if
-*>          JOBZ = 'S' or 'A' or JOBZ = 'O' and M < N, LDU >= M.
+*>          The leading dimension of the array U.  LDU >= 1;
+*>          if JOBZ = 'S' or 'A' or JOBZ = 'O' and M < N, LDU >= M.
 *> \endverbatim
 *>
 *> \param[out] VT
 *> \param[in] LDVT
 *> \verbatim
 *>          LDVT is INTEGER
-*>          The leading dimension of the array VT.  LDVT >= 1; if
-*>          JOBZ = 'A' or JOBZ = 'O' and M >= N, LDVT >= N;
+*>          The leading dimension of the array VT.  LDVT >= 1;
+*>          if JOBZ = 'A' or JOBZ = 'O' and M >= N, LDVT >= N;
 *>          if JOBZ = 'S', LDVT >= min(M,N).
 *> \endverbatim
 *>
 *> \verbatim
 *>          LWORK is INTEGER
 *>          The dimension of the array WORK. LWORK >= 1.
-*>          if JOBZ = 'N', LWORK >= 2*min(M,N)+max(M,N).
-*>          if JOBZ = 'O',
-*>                LWORK >= 2*min(M,N)*min(M,N)+2*min(M,N)+max(M,N).
-*>          if JOBZ = 'S' or 'A',
-*>                LWORK >= min(M,N)*min(M,N)+2*min(M,N)+max(M,N).
-*>          For good performance, LWORK should generally be larger.
-*>
 *>          If LWORK = -1, a workspace query is assumed.  The optimal
 *>          size for the WORK array is calculated and stored in WORK(1),
 *>          and no other work except argument checking is performed.
+*>
+*>          Let mx = max(M,N) and mn = min(M,N).
+*>          If JOBZ = 'N', LWORK >= 2*mn + mx.
+*>          If JOBZ = 'O', LWORK >= 2*mn*mn + 2*mn + mx.
+*>          If JOBZ = 'S', LWORK >=   mn*mn + 3*mn.
+*>          If JOBZ = 'A', LWORK >=   mn*mn + 2*mn + mx.
+*>          These are not tight minimums in all cases; see comments inside code.
+*>          For good performance, LWORK should generally be larger;
+*>          a query is recommended.
 *> \endverbatim
 *>
 *> \param[out] RWORK
 *> \verbatim
 *>          RWORK is DOUBLE PRECISION array, dimension (MAX(1,LRWORK))
-*>          If JOBZ = 'N', LRWORK >= 7*min(M,N).
-*>          Otherwise,
-*>          LRWORK >= min(M,N)*max(5*min(M,N)+7,2*max(M,N)+2*min(M,N)+1)
+*>          Let mx = max(M,N) and mn = min(M,N).
+*>          If JOBZ = 'N',    LRWORK >= 5*mn (LAPACK <= 3.6 needs 7*mn);
+*>          else if mx >> mn, LRWORK >= 5*mn*mn + 5*mn;
+*>          else              LRWORK >= max( 5*mn*mn + 5*mn,
+*>                                           2*mx*mn + 2*mn*mn + mn ).
 *> \endverbatim
 *>
 *> \param[out] IWORK
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complex16GEsing
 *
 *>     Ming Gu and Huan Ren, Computer Science Division, University of
 *>     California at Berkeley, USA
 *>
+*> @precisions fortran z -> c
 *  =====================================================================
-      SUBROUTINE ZGESDD( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK,
-     $                   LWORK, RWORK, IWORK, INFO )
+      SUBROUTINE ZGESDD( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT,
+     $                   WORK, LWORK, RWORK, IWORK, INFO )
+      implicit none
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ
 *  =====================================================================
 *
 *     .. Parameters ..
-      INTEGER            LQUERV
-      PARAMETER          ( LQUERV = -1 )
       COMPLEX*16         CZERO, CONE
       PARAMETER          ( CZERO = ( 0.0D+0, 0.0D+0 ),
      $                   CONE = ( 1.0D+0, 0.0D+0 ) )
       PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
 *     ..
 *     .. Local Scalars ..
-      LOGICAL            WNTQA, WNTQAS, WNTQN, WNTQO, WNTQS
+      LOGICAL            LQUERY, WNTQA, WNTQAS, WNTQN, WNTQO, WNTQS
       INTEGER            BLK, CHUNK, I, IE, IERR, IL, IR, IRU, IRVT,
      $                   ISCL, ITAU, ITAUP, ITAUQ, IU, IVT, LDWKVT,
      $                   LDWRKL, LDWRKR, LDWRKU, MAXWRK, MINMN, MINWRK,
      $                   MNTHR1, MNTHR2, NRWORK, NWORK, WRKBL
+      INTEGER            LWORK_ZGEBRD_MN, LWORK_ZGEBRD_MM,
+     $                   LWORK_ZGEBRD_NN, LWORK_ZGELQF_MN,
+     $                   LWORK_ZGEQRF_MN,
+     $                   LWORK_ZUNGBR_P_MN, LWORK_ZUNGBR_P_NN,
+     $                   LWORK_ZUNGBR_Q_MN, LWORK_ZUNGBR_Q_MM,
+     $                   LWORK_ZUNGLQ_MN, LWORK_ZUNGLQ_NN,
+     $                   LWORK_ZUNGQR_MM, LWORK_ZUNGQR_MN,
+     $                   LWORK_ZUNMBR_PRC_MM, LWORK_ZUNMBR_QLN_MM,
+     $                   LWORK_ZUNMBR_PRC_MN, LWORK_ZUNMBR_QLN_MN,
+     $                   LWORK_ZUNMBR_PRC_NN, LWORK_ZUNMBR_QLN_NN
       DOUBLE PRECISION   ANRM, BIGNUM, EPS, SMLNUM
 *     ..
 *     .. Local Arrays ..
       INTEGER            IDUM( 1 )
       DOUBLE PRECISION   DUM( 1 )
+      COMPLEX*16         CDUM( 1 )
 *     ..
 *     .. External Subroutines ..
       EXTERNAL           DBDSDC, DLASCL, XERBLA, ZGEBRD, ZGELQF, ZGEMM,
 *     ..
 *     .. External Functions ..
       LOGICAL            LSAME
-      INTEGER            ILAENV
       DOUBLE PRECISION   DLAMCH, ZLANGE
-      EXTERNAL           LSAME, ILAENV, DLAMCH, ZLANGE
+      EXTERNAL           LSAME, DLAMCH, ZLANGE
 *     ..
 *     .. Intrinsic Functions ..
       INTRINSIC          INT, MAX, MIN, SQRT
 *
 *     Test the input arguments
 *
-      INFO = 0
-      MINMN = MIN( M, N )
+      INFO   = 0
+      MINMN  = MIN( M, N )
       MNTHR1 = INT( MINMN*17.0D0 / 9.0D0 )
       MNTHR2 = INT( MINMN*5.0D0 / 3.0D0 )
-      WNTQA = LSAME( JOBZ, 'A' )
-      WNTQS = LSAME( JOBZ, 'S' )
+      WNTQA  = LSAME( JOBZ, 'A' )
+      WNTQS  = LSAME( JOBZ, 'S' )
       WNTQAS = WNTQA .OR. WNTQS
-      WNTQO = LSAME( JOBZ, 'O' )
-      WNTQN = LSAME( JOBZ, 'N' )
+      WNTQO  = LSAME( JOBZ, 'O' )
+      WNTQN  = LSAME( JOBZ, 'N' )
+      LQUERY = ( LWORK.EQ.-1 )
       MINWRK = 1
       MAXWRK = 1
 *
       END IF
 *
 *     Compute workspace
-*      (Note: Comments in the code beginning "Workspace:" describe the
-*       minimal amount of workspace needed at that point in the code,
+*       Note: Comments in the code beginning "Workspace:" describe the
+*       minimal amount of workspace allocated at that point in the code,
 *       as well as the preferred amount for good performance.
 *       CWorkspace refers to complex workspace, and RWorkspace to
 *       real workspace. NB refers to the optimal block size for the
          IF( M.GE.N ) THEN
 *
 *           There is no complex work space needed for bidiagonal SVD
-*           The real work space needed for bidiagonal SVD is BDSPAC
-*           for computing singular values and singular vectors; BDSPAN
-*           for computing singular values only.
-*           BDSPAC = 5*N*N + 7*N
-*           BDSPAN = MAX(7*N+4, 3*N+2+SMLSIZ*(SMLSIZ+8))
+*           The real work space needed for bidiagonal SVD (dbdsdc) is
+*           BDSPAC = 3*N*N + 4*N for singular values and vectors;
+*           BDSPAC = 4*N         for singular values only;
+*           not including e, RU, and RVT matrices.
+*
+*           Compute space preferred for each routine
+            CALL ZGEBRD( M, N, CDUM(1), M, DUM(1), DUM(1), CDUM(1),
+     $                   CDUM(1), CDUM(1), -1, IERR )
+            LWORK_ZGEBRD_MN = INT( CDUM(1) )
+*
+            CALL ZGEBRD( N, N, CDUM(1), N, DUM(1), DUM(1), CDUM(1),
+     $                   CDUM(1), CDUM(1), -1, IERR )
+            LWORK_ZGEBRD_NN = INT( CDUM(1) )
+*
+            CALL ZGEQRF( M, N, CDUM(1), M, CDUM(1), CDUM(1), -1, IERR )
+            LWORK_ZGEQRF_MN = INT( CDUM(1) )
+*
+            CALL ZUNGBR( 'P', N, N, N, CDUM(1), N, CDUM(1), CDUM(1),
+     $                   -1, IERR )
+            LWORK_ZUNGBR_P_NN = INT( CDUM(1) )
+*
+            CALL ZUNGBR( 'Q', M, M, N, CDUM(1), M, CDUM(1), CDUM(1),
+     $                   -1, IERR )
+            LWORK_ZUNGBR_Q_MM = INT( CDUM(1) )
+*
+            CALL ZUNGBR( 'Q', M, N, N, CDUM(1), M, CDUM(1), CDUM(1),
+     $                   -1, IERR )
+            LWORK_ZUNGBR_Q_MN = INT( CDUM(1) )
+*
+            CALL ZUNGQR( M, M, N, CDUM(1), M, CDUM(1), CDUM(1),
+     $                   -1, IERR )
+            LWORK_ZUNGQR_MM = INT( CDUM(1) )
+*
+            CALL ZUNGQR( M, N, N, CDUM(1), M, CDUM(1), CDUM(1),
+     $                   -1, IERR )
+            LWORK_ZUNGQR_MN = INT( CDUM(1) )
+*
+            CALL ZUNMBR( 'P', 'R', 'C', N, N, N, CDUM(1), N, CDUM(1),
+     $                   CDUM(1), N, CDUM(1), -1, IERR )
+            LWORK_ZUNMBR_PRC_NN = INT( CDUM(1) )
+*
+            CALL ZUNMBR( 'Q', 'L', 'N', M, M, N, CDUM(1), M, CDUM(1),
+     $                   CDUM(1), M, CDUM(1), -1, IERR )
+            LWORK_ZUNMBR_QLN_MM = INT( CDUM(1) )
+*
+            CALL ZUNMBR( 'Q', 'L', 'N', M, N, N, CDUM(1), M, CDUM(1),
+     $                   CDUM(1), M, CDUM(1), -1, IERR )
+            LWORK_ZUNMBR_QLN_MN = INT( CDUM(1) )
+*
+            CALL ZUNMBR( 'Q', 'L', 'N', N, N, N, CDUM(1), N, CDUM(1),
+     $                   CDUM(1), N, CDUM(1), -1, IERR )
+            LWORK_ZUNMBR_QLN_NN = INT( CDUM(1) )
 *
             IF( M.GE.MNTHR1 ) THEN
                IF( WNTQN ) THEN
 *
-*                 Path 1 (M much larger than N, JOBZ='N')
+*                 Path 1 (M >> N, JOBZ='N')
 *
-                  MAXWRK = N + N*ILAENV( 1, 'ZGEQRF', ' ', M, N, -1,
-     $                     -1 )
-                  MAXWRK = MAX( MAXWRK, 2*N+2*N*
-     $                     ILAENV( 1, 'ZGEBRD', ' ', N, N, -1, -1 ) )
+                  MAXWRK = N + LWORK_ZGEQRF_MN
+                  MAXWRK = MAX( MAXWRK, 2*N + LWORK_ZGEBRD_NN )
                   MINWRK = 3*N
                ELSE IF( WNTQO ) THEN
 *
-*                 Path 2 (M much larger than N, JOBZ='O')
-*
-                  WRKBL = N + N*ILAENV( 1, 'ZGEQRF', ' ', M, N, -1, -1 )
-                  WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'ZUNGQR', ' ', M,
-     $                    N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*N+2*N*
-     $                    ILAENV( 1, 'ZGEBRD', ' ', N, N, -1, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*N+N*
-     $                    ILAENV( 1, 'ZUNMBR', 'QLN', N, N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*N+N*
-     $                    ILAENV( 1, 'ZUNMBR', 'PRC', N, N, N, -1 ) )
+*                 Path 2 (M >> N, JOBZ='O')
+*
+                  WRKBL = N + LWORK_ZGEQRF_MN
+                  WRKBL = MAX( WRKBL,   N + LWORK_ZUNGQR_MN )
+                  WRKBL = MAX( WRKBL, 2*N + LWORK_ZGEBRD_NN )
+                  WRKBL = MAX( WRKBL, 2*N + LWORK_ZUNMBR_QLN_NN )
+                  WRKBL = MAX( WRKBL, 2*N + LWORK_ZUNMBR_PRC_NN )
                   MAXWRK = M*N + N*N + WRKBL
                   MINWRK = 2*N*N + 3*N
                ELSE IF( WNTQS ) THEN
 *
-*                 Path 3 (M much larger than N, JOBZ='S')
-*
-                  WRKBL = N + N*ILAENV( 1, 'ZGEQRF', ' ', M, N, -1, -1 )
-                  WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'ZUNGQR', ' ', M,
-     $                    N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*N+2*N*
-     $                    ILAENV( 1, 'ZGEBRD', ' ', N, N, -1, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*N+N*
-     $                    ILAENV( 1, 'ZUNMBR', 'QLN', N, N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*N+N*
-     $                    ILAENV( 1, 'ZUNMBR', 'PRC', N, N, N, -1 ) )
+*                 Path 3 (M >> N, JOBZ='S')
+*
+                  WRKBL = N + LWORK_ZGEQRF_MN
+                  WRKBL = MAX( WRKBL,   N + LWORK_ZUNGQR_MN )
+                  WRKBL = MAX( WRKBL, 2*N + LWORK_ZGEBRD_NN )
+                  WRKBL = MAX( WRKBL, 2*N + LWORK_ZUNMBR_QLN_NN )
+                  WRKBL = MAX( WRKBL, 2*N + LWORK_ZUNMBR_PRC_NN )
                   MAXWRK = N*N + WRKBL
                   MINWRK = N*N + 3*N
                ELSE IF( WNTQA ) THEN
 *
-*                 Path 4 (M much larger than N, JOBZ='A')
-*
-                  WRKBL = N + N*ILAENV( 1, 'ZGEQRF', ' ', M, N, -1, -1 )
-                  WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'ZUNGQR', ' ', M,
-     $                    M, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*N+2*N*
-     $                    ILAENV( 1, 'ZGEBRD', ' ', N, N, -1, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*N+N*
-     $                    ILAENV( 1, 'ZUNMBR', 'QLN', N, N, N, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*N+N*
-     $                    ILAENV( 1, 'ZUNMBR', 'PRC', N, N, N, -1 ) )
+*                 Path 4 (M >> N, JOBZ='A')
+*
+                  WRKBL = N + LWORK_ZGEQRF_MN
+                  WRKBL = MAX( WRKBL,   N + LWORK_ZUNGQR_MM )
+                  WRKBL = MAX( WRKBL, 2*N + LWORK_ZGEBRD_NN )
+                  WRKBL = MAX( WRKBL, 2*N + LWORK_ZUNMBR_QLN_NN )
+                  WRKBL = MAX( WRKBL, 2*N + LWORK_ZUNMBR_PRC_NN )
                   MAXWRK = N*N + WRKBL
-                  MINWRK = N*N + 2*N + M
+                  MINWRK = N*N + MAX( 3*N, N + M )
                END IF
             ELSE IF( M.GE.MNTHR2 ) THEN
 *
-*              Path 5 (M much larger than N, but not as much as MNTHR1)
+*              Path 5 (M >> N, but not as much as MNTHR1)
 *
-               MAXWRK = 2*N + ( M+N )*ILAENV( 1, 'ZGEBRD', ' ', M, N,
-     $                  -1, -1 )
+               MAXWRK = 2*N + LWORK_ZGEBRD_MN
                MINWRK = 2*N + M
                IF( WNTQO ) THEN
-                  MAXWRK = MAX( MAXWRK, 2*N+N*
-     $                     ILAENV( 1, 'ZUNGBR', 'P', N, N, N, -1 ) )
-                  MAXWRK = MAX( MAXWRK, 2*N+N*
-     $                     ILAENV( 1, 'ZUNGBR', 'Q', M, N, N, -1 ) )
+*                 Path 5o (M >> N, JOBZ='O')
+                  MAXWRK = MAX( MAXWRK, 2*N + LWORK_ZUNGBR_P_NN )
+                  MAXWRK = MAX( MAXWRK, 2*N + LWORK_ZUNGBR_Q_MN )
                   MAXWRK = MAXWRK + M*N
                   MINWRK = MINWRK + N*N
                ELSE IF( WNTQS ) THEN
-                  MAXWRK = MAX( MAXWRK, 2*N+N*
-     $                     ILAENV( 1, 'ZUNGBR', 'P', N, N, N, -1 ) )
-                  MAXWRK = MAX( MAXWRK, 2*N+N*
-     $                     ILAENV( 1, 'ZUNGBR', 'Q', M, N, N, -1 ) )
+*                 Path 5s (M >> N, JOBZ='S')
+                  MAXWRK = MAX( MAXWRK, 2*N + LWORK_ZUNGBR_P_NN )
+                  MAXWRK = MAX( MAXWRK, 2*N + LWORK_ZUNGBR_Q_MN )
                ELSE IF( WNTQA ) THEN
-                  MAXWRK = MAX( MAXWRK, 2*N+N*
-     $                     ILAENV( 1, 'ZUNGBR', 'P', N, N, N, -1 ) )
-                  MAXWRK = MAX( MAXWRK, 2*N+M*
-     $                     ILAENV( 1, 'ZUNGBR', 'Q', M, M, N, -1 ) )
+*                 Path 5a (M >> N, JOBZ='A')
+                  MAXWRK = MAX( MAXWRK, 2*N + LWORK_ZUNGBR_P_NN )
+                  MAXWRK = MAX( MAXWRK, 2*N + LWORK_ZUNGBR_Q_MM )
                END IF
             ELSE
 *
-*              Path 6 (M at least N, but not much larger)
+*              Path 6 (M >= N, but not much larger)
 *
-               MAXWRK = 2*N + ( M+N )*ILAENV( 1, 'ZGEBRD', ' ', M, N,
-     $                  -1, -1 )
+               MAXWRK = 2*N + LWORK_ZGEBRD_MN
                MINWRK = 2*N + M
                IF( WNTQO ) THEN
-                  MAXWRK = MAX( MAXWRK, 2*N+N*
-     $                     ILAENV( 1, 'ZUNMBR', 'PRC', N, N, N, -1 ) )
-                  MAXWRK = MAX( MAXWRK, 2*N+N*
-     $                     ILAENV( 1, 'ZUNMBR', 'QLN', M, N, N, -1 ) )
+*                 Path 6o (M >= N, JOBZ='O')
+                  MAXWRK = MAX( MAXWRK, 2*N + LWORK_ZUNMBR_PRC_NN )
+                  MAXWRK = MAX( MAXWRK, 2*N + LWORK_ZUNMBR_QLN_MN )
                   MAXWRK = MAXWRK + M*N
                   MINWRK = MINWRK + N*N
                ELSE IF( WNTQS ) THEN
-                  MAXWRK = MAX( MAXWRK, 2*N+N*
-     $                     ILAENV( 1, 'ZUNMBR', 'PRC', N, N, N, -1 ) )
-                  MAXWRK = MAX( MAXWRK, 2*N+N*
-     $                     ILAENV( 1, 'ZUNMBR', 'QLN', M, N, N, -1 ) )
+*                 Path 6s (M >= N, JOBZ='S')
+                  MAXWRK = MAX( MAXWRK, 2*N + LWORK_ZUNMBR_QLN_MN )
+                  MAXWRK = MAX( MAXWRK, 2*N + LWORK_ZUNMBR_PRC_NN )
                ELSE IF( WNTQA ) THEN
-                  MAXWRK = MAX( MAXWRK, 2*N+N*
-     $                     ILAENV( 1, 'ZUNGBR', 'PRC', N, N, N, -1 ) )
-                  MAXWRK = MAX( MAXWRK, 2*N+M*
-     $                     ILAENV( 1, 'ZUNGBR', 'QLN', M, M, N, -1 ) )
+*                 Path 6a (M >= N, JOBZ='A')
+                  MAXWRK = MAX( MAXWRK, 2*N + LWORK_ZUNMBR_QLN_MM )
+                  MAXWRK = MAX( MAXWRK, 2*N + LWORK_ZUNMBR_PRC_NN )
                END IF
             END IF
          ELSE
 *
 *           There is no complex work space needed for bidiagonal SVD
-*           The real work space needed for bidiagonal SVD is BDSPAC
-*           for computing singular values and singular vectors; BDSPAN
-*           for computing singular values only.
-*           BDSPAC = 5*M*M + 7*M
-*           BDSPAN = MAX(7*M+4, 3*M+2+SMLSIZ*(SMLSIZ+8))
+*           The real work space needed for bidiagonal SVD (dbdsdc) is
+*           BDSPAC = 3*M*M + 4*M for singular values and vectors;
+*           BDSPAC = 4*M         for singular values only;
+*           not including e, RU, and RVT matrices.
+*
+*           Compute space preferred for each routine
+            CALL ZGEBRD( M, N, CDUM(1), M, DUM(1), DUM(1), CDUM(1),
+     $                   CDUM(1), CDUM(1), -1, IERR )
+            LWORK_ZGEBRD_MN = INT( CDUM(1) )
+*
+            CALL ZGEBRD( M, M, CDUM(1), M, DUM(1), DUM(1), CDUM(1),
+     $                   CDUM(1), CDUM(1), -1, IERR )
+            LWORK_ZGEBRD_MM = INT( CDUM(1) )
+*
+            CALL ZGELQF( M, N, CDUM(1), M, CDUM(1), CDUM(1), -1, IERR )
+            LWORK_ZGELQF_MN = INT( CDUM(1) )
+*
+            CALL ZUNGBR( 'P', M, N, M, CDUM(1), M, CDUM(1), CDUM(1),
+     $                   -1, IERR )
+            LWORK_ZUNGBR_P_MN = INT( CDUM(1) )
+*
+            CALL ZUNGBR( 'P', N, N, M, CDUM(1), N, CDUM(1), CDUM(1),
+     $                   -1, IERR )
+            LWORK_ZUNGBR_P_NN = INT( CDUM(1) )
+*
+            CALL ZUNGBR( 'Q', M, M, N, CDUM(1), M, CDUM(1), CDUM(1),
+     $                   -1, IERR )
+            LWORK_ZUNGBR_Q_MM = INT( CDUM(1) )
+*
+            CALL ZUNGLQ( M, N, M, CDUM(1), M, CDUM(1), CDUM(1),
+     $                   -1, IERR )
+            LWORK_ZUNGLQ_MN = INT( CDUM(1) )
+*
+            CALL ZUNGLQ( N, N, M, CDUM(1), N, CDUM(1), CDUM(1),
+     $                   -1, IERR )
+            LWORK_ZUNGLQ_NN = INT( CDUM(1) )
+*
+            CALL ZUNMBR( 'P', 'R', 'C', M, M, M, CDUM(1), M, CDUM(1),
+     $                   CDUM(1), M, CDUM(1), -1, IERR )
+            LWORK_ZUNMBR_PRC_MM = INT( CDUM(1) )
+*
+            CALL ZUNMBR( 'P', 'R', 'C', M, N, M, CDUM(1), M, CDUM(1),
+     $                   CDUM(1), M, CDUM(1), -1, IERR )
+            LWORK_ZUNMBR_PRC_MN = INT( CDUM(1) )
+*
+            CALL ZUNMBR( 'P', 'R', 'C', N, N, M, CDUM(1), N, CDUM(1),
+     $                   CDUM(1), N, CDUM(1), -1, IERR )
+            LWORK_ZUNMBR_PRC_NN = INT( CDUM(1) )
+*
+            CALL ZUNMBR( 'Q', 'L', 'N', M, M, M, CDUM(1), M, CDUM(1),
+     $                   CDUM(1), M, CDUM(1), -1, IERR )
+            LWORK_ZUNMBR_QLN_MM = INT( CDUM(1) )
 *
             IF( N.GE.MNTHR1 ) THEN
                IF( WNTQN ) THEN
 *
-*                 Path 1t (N much larger than M, JOBZ='N')
+*                 Path 1t (N >> M, JOBZ='N')
 *
-                  MAXWRK = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1,
-     $                     -1 )
-                  MAXWRK = MAX( MAXWRK, 2*M+2*M*
-     $                     ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) )
+                  MAXWRK = M + LWORK_ZGELQF_MN
+                  MAXWRK = MAX( MAXWRK, 2*M + LWORK_ZGEBRD_MM )
                   MINWRK = 3*M
                ELSE IF( WNTQO ) THEN
 *
-*                 Path 2t (N much larger than M, JOBZ='O')
-*
-                  WRKBL = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1, -1 )
-                  WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'ZUNGLQ', ' ', M,
-     $                    N, M, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*M+2*M*
-     $                    ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*M+M*
-     $                    ILAENV( 1, 'ZUNMBR', 'PRC', M, M, M, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*M+M*
-     $                    ILAENV( 1, 'ZUNMBR', 'QLN', M, M, M, -1 ) )
+*                 Path 2t (N >> M, JOBZ='O')
+*
+                  WRKBL = M + LWORK_ZGELQF_MN
+                  WRKBL = MAX( WRKBL,   M + LWORK_ZUNGLQ_MN )
+                  WRKBL = MAX( WRKBL, 2*M + LWORK_ZGEBRD_MM )
+                  WRKBL = MAX( WRKBL, 2*M + LWORK_ZUNMBR_QLN_MM )
+                  WRKBL = MAX( WRKBL, 2*M + LWORK_ZUNMBR_PRC_MM )
                   MAXWRK = M*N + M*M + WRKBL
                   MINWRK = 2*M*M + 3*M
                ELSE IF( WNTQS ) THEN
 *
-*                 Path 3t (N much larger than M, JOBZ='S')
-*
-                  WRKBL = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1, -1 )
-                  WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'ZUNGLQ', ' ', M,
-     $                    N, M, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*M+2*M*
-     $                    ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*M+M*
-     $                    ILAENV( 1, 'ZUNMBR', 'PRC', M, M, M, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*M+M*
-     $                    ILAENV( 1, 'ZUNMBR', 'QLN', M, M, M, -1 ) )
+*                 Path 3t (N >> M, JOBZ='S')
+*
+                  WRKBL = M + LWORK_ZGELQF_MN
+                  WRKBL = MAX( WRKBL,   M + LWORK_ZUNGLQ_MN )
+                  WRKBL = MAX( WRKBL, 2*M + LWORK_ZGEBRD_MM )
+                  WRKBL = MAX( WRKBL, 2*M + LWORK_ZUNMBR_QLN_MM )
+                  WRKBL = MAX( WRKBL, 2*M + LWORK_ZUNMBR_PRC_MM )
                   MAXWRK = M*M + WRKBL
                   MINWRK = M*M + 3*M
                ELSE IF( WNTQA ) THEN
 *
-*                 Path 4t (N much larger than M, JOBZ='A')
-*
-                  WRKBL = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1, -1 )
-                  WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'ZUNGLQ', ' ', N,
-     $                    N, M, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*M+2*M*
-     $                    ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*M+M*
-     $                    ILAENV( 1, 'ZUNMBR', 'PRC', M, M, M, -1 ) )
-                  WRKBL = MAX( WRKBL, 2*M+M*
-     $                    ILAENV( 1, 'ZUNMBR', 'QLN', M, M, M, -1 ) )
+*                 Path 4t (N >> M, JOBZ='A')
+*
+                  WRKBL = M + LWORK_ZGELQF_MN
+                  WRKBL = MAX( WRKBL,   M + LWORK_ZUNGLQ_NN )
+                  WRKBL = MAX( WRKBL, 2*M + LWORK_ZGEBRD_MM )
+                  WRKBL = MAX( WRKBL, 2*M + LWORK_ZUNMBR_QLN_MM )
+                  WRKBL = MAX( WRKBL, 2*M + LWORK_ZUNMBR_PRC_MM )
                   MAXWRK = M*M + WRKBL
-                  MINWRK = M*M + 2*M + N
+                  MINWRK = M*M + MAX( 3*M, M + N )
                END IF
             ELSE IF( N.GE.MNTHR2 ) THEN
 *
-*              Path 5t (N much larger than M, but not as much as MNTHR1)
+*              Path 5t (N >> M, but not as much as MNTHR1)
 *
-               MAXWRK = 2*M + ( M+N )*ILAENV( 1, 'ZGEBRD', ' ', M, N,
-     $                  -1, -1 )
+               MAXWRK = 2*M + LWORK_ZGEBRD_MN
                MINWRK = 2*M + N
                IF( WNTQO ) THEN
-                  MAXWRK = MAX( MAXWRK, 2*M+M*
-     $                     ILAENV( 1, 'ZUNGBR', 'P', M, N, M, -1 ) )
-                  MAXWRK = MAX( MAXWRK, 2*M+M*
-     $                     ILAENV( 1, 'ZUNGBR', 'Q', M, M, N, -1 ) )
+*                 Path 5to (N >> M, JOBZ='O')
+                  MAXWRK = MAX( MAXWRK, 2*M + LWORK_ZUNGBR_Q_MM )
+                  MAXWRK = MAX( MAXWRK, 2*M + LWORK_ZUNGBR_P_MN )
                   MAXWRK = MAXWRK + M*N
                   MINWRK = MINWRK + M*M
                ELSE IF( WNTQS ) THEN
-                  MAXWRK = MAX( MAXWRK, 2*M+M*
-     $                     ILAENV( 1, 'ZUNGBR', 'P', M, N, M, -1 ) )
-                  MAXWRK = MAX( MAXWRK, 2*M+M*
-     $                     ILAENV( 1, 'ZUNGBR', 'Q', M, M, N, -1 ) )
+*                 Path 5ts (N >> M, JOBZ='S')
+                  MAXWRK = MAX( MAXWRK, 2*M + LWORK_ZUNGBR_Q_MM )
+                  MAXWRK = MAX( MAXWRK, 2*M + LWORK_ZUNGBR_P_MN )
                ELSE IF( WNTQA ) THEN
-                  MAXWRK = MAX( MAXWRK, 2*M+N*
-     $                     ILAENV( 1, 'ZUNGBR', 'P', N, N, M, -1 ) )
-                  MAXWRK = MAX( MAXWRK, 2*M+M*
-     $                     ILAENV( 1, 'ZUNGBR', 'Q', M, M, N, -1 ) )
+*                 Path 5ta (N >> M, JOBZ='A')
+                  MAXWRK = MAX( MAXWRK, 2*M + LWORK_ZUNGBR_Q_MM )
+                  MAXWRK = MAX( MAXWRK, 2*M + LWORK_ZUNGBR_P_NN )
                END IF
             ELSE
 *
-*              Path 6t (N greater than M, but not much larger)
+*              Path 6t (N > M, but not much larger)
 *
-               MAXWRK = 2*M + ( M+N )*ILAENV( 1, 'ZGEBRD', ' ', M, N,
-     $                  -1, -1 )
+               MAXWRK = 2*M + LWORK_ZGEBRD_MN
                MINWRK = 2*M + N
                IF( WNTQO ) THEN
-                  MAXWRK = MAX( MAXWRK, 2*M+M*
-     $                     ILAENV( 1, 'ZUNMBR', 'PRC', M, N, M, -1 ) )
-                  MAXWRK = MAX( MAXWRK, 2*M+M*
-     $                     ILAENV( 1, 'ZUNMBR', 'QLN', M, M, N, -1 ) )
+*                 Path 6to (N > M, JOBZ='O')
+                  MAXWRK = MAX( MAXWRK, 2*M + LWORK_ZUNMBR_QLN_MM )
+                  MAXWRK = MAX( MAXWRK, 2*M + LWORK_ZUNMBR_PRC_MN )
                   MAXWRK = MAXWRK + M*N
                   MINWRK = MINWRK + M*M
                ELSE IF( WNTQS ) THEN
-                  MAXWRK = MAX( MAXWRK, 2*M+M*
-     $                     ILAENV( 1, 'ZUNGBR', 'PRC', M, N, M, -1 ) )
-                  MAXWRK = MAX( MAXWRK, 2*M+M*
-     $                     ILAENV( 1, 'ZUNGBR', 'QLN', M, M, N, -1 ) )
+*                 Path 6ts (N > M, JOBZ='S')
+                  MAXWRK = MAX( MAXWRK, 2*M + LWORK_ZUNMBR_QLN_MM )
+                  MAXWRK = MAX( MAXWRK, 2*M + LWORK_ZUNMBR_PRC_MN )
                ELSE IF( WNTQA ) THEN
-                  MAXWRK = MAX( MAXWRK, 2*M+N*
-     $                     ILAENV( 1, 'ZUNGBR', 'PRC', N, N, M, -1 ) )
-                  MAXWRK = MAX( MAXWRK, 2*M+M*
-     $                     ILAENV( 1, 'ZUNGBR', 'QLN', M, M, N, -1 ) )
+*                 Path 6ta (N > M, JOBZ='A')
+                  MAXWRK = MAX( MAXWRK, 2*M + LWORK_ZUNMBR_QLN_MM )
+                  MAXWRK = MAX( MAXWRK, 2*M + LWORK_ZUNMBR_PRC_NN )
                END IF
             END IF
          END IF
       END IF
       IF( INFO.EQ.0 ) THEN
          WORK( 1 ) = MAXWRK
-         IF( LWORK.LT.MINWRK .AND. LWORK.NE.LQUERV )
-     $      INFO = -13
+         IF( LWORK.LT.MINWRK .AND. .NOT. LQUERY ) THEN
+            INFO = -12
+         END IF
       END IF
-*
-*     Quick returns
 *
       IF( INFO.NE.0 ) THEN
          CALL XERBLA( 'ZGESDD', -INFO )
          RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
       END IF
-      IF( LWORK.EQ.LQUERV )
-     $   RETURN
+*
+*     Quick return if possible
+*
       IF( M.EQ.0 .OR. N.EQ.0 ) THEN
          RETURN
       END IF
 *
             IF( WNTQN ) THEN
 *
-*              Path 1 (M much larger than N, JOBZ='N')
+*              Path 1 (M >> N, JOBZ='N')
 *              No singular vectors to be computed
 *
                ITAU = 1
                NWORK = ITAU + N
 *
 *              Compute A=Q*R
-*              (CWorkspace: need 2*N, prefer N+N*NB)
-*              (RWorkspace: need 0)
+*              CWorkspace: need   N [tau] + N    [work]
+*              CWorkspace: prefer N [tau] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
      $                      LWORK-NWORK+1, IERR )
                NWORK = ITAUP + N
 *
 *              Bidiagonalize R in A
-*              (CWorkspace: need 3*N, prefer 2*N+2*N*NB)
-*              (RWorkspace: need N)
+*              CWorkspace: need   2*N [tauq, taup] + N      [work]
+*              CWorkspace: prefer 2*N [tauq, taup] + 2*N*NB [work]
+*              RWorkspace: need   N [e]
 *
                CALL ZGEBRD( N, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
      $                      WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
                NRWORK = IE + N
 *
 *              Perform bidiagonal SVD, compute singular values only
-*              (CWorkspace: 0)
-*              (RWorkspace: need BDSPAN)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + BDSPAC
 *
-               CALL DBDSDC( 'U', 'N', N, S, RWORK( IE ), DUM, 1, DUM, 1,
+               CALL DBDSDC( 'U', 'N', N, S, RWORK( IE ), DUM,1,DUM,1,
      $                      DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
 *
             ELSE IF( WNTQO ) THEN
 *
-*              Path 2 (M much larger than N, JOBZ='O')
+*              Path 2 (M >> N, JOBZ='O')
 *              N left singular vectors to be overwritten on A and
 *              N right singular vectors to be computed in VT
 *
 *
                LDWRKU = N
                IR = IU + LDWRKU*N
-               IF( LWORK.GE.M*N+N*N+3*N ) THEN
+               IF( LWORK .GE. M*N + N*N + 3*N ) THEN
 *
 *                 WORK(IR) is M by N
 *
                   LDWRKR = M
                ELSE
-                  LDWRKR = ( LWORK-N*N-3*N ) / N
+                  LDWRKR = ( LWORK - N*N - 3*N ) / N
                END IF
                ITAU = IR + LDWRKR*N
                NWORK = ITAU + N
 *
 *              Compute A=Q*R
-*              (CWorkspace: need N*N+2*N, prefer M*N+N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   N*N [U] + N*N [R] + N [tau] + N    [work]
+*              CWorkspace: prefer N*N [U] + N*N [R] + N [tau] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
      $                      LWORK-NWORK+1, IERR )
      $                      LDWRKR )
 *
 *              Generate Q in A
-*              (CWorkspace: need 2*N, prefer N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   N*N [U] + N*N [R] + N [tau] + N    [work]
+*              CWorkspace: prefer N*N [U] + N*N [R] + N [tau] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZUNGQR( M, N, N, A, LDA, WORK( ITAU ),
      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                NWORK = ITAUP + N
 *
 *              Bidiagonalize R in WORK(IR)
-*              (CWorkspace: need N*N+3*N, prefer M*N+2*N+2*N*NB)
-*              (RWorkspace: need N)
+*              CWorkspace: need   N*N [U] + N*N [R] + 2*N [tauq, taup] + N      [work]
+*              CWorkspace: prefer N*N [U] + N*N [R] + 2*N [tauq, taup] + 2*N*NB [work]
+*              RWorkspace: need   N [e]
 *
                CALL ZGEBRD( N, N, WORK( IR ), LDWRKR, S, RWORK( IE ),
      $                      WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of R in WORK(IRU) and computing right singular vectors
 *              of R in WORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT] + BDSPAC
 *
                IRU = IE + N
                IRVT = IRU + N*N
 *
 *              Copy real matrix RWORK(IRU) to complex matrix WORK(IU)
 *              Overwrite WORK(IU) by the left singular vectors of R
-*              (CWorkspace: need 2*N*N+3*N, prefer M*N+N*N+2*N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   N*N [U] + N*N [R] + 2*N [tauq, taup] + N    [work]
+*              CWorkspace: prefer N*N [U] + N*N [R] + 2*N [tauq, taup] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZLACP2( 'F', N, N, RWORK( IRU ), N, WORK( IU ),
      $                      LDWRKU )
 *
 *              Copy real matrix RWORK(IRVT) to complex matrix VT
 *              Overwrite VT by the right singular vectors of R
-*              (CWorkspace: need N*N+3*N, prefer M*N+2*N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   N*N [U] + N*N [R] + 2*N [tauq, taup] + N    [work]
+*              CWorkspace: prefer N*N [U] + N*N [R] + 2*N [tauq, taup] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
                CALL ZUNMBR( 'P', 'R', 'C', N, N, N, WORK( IR ), LDWRKR,
 *
 *              Multiply Q in A by left singular vectors of R in
 *              WORK(IU), storing result in WORK(IR) and copying to A
-*              (CWorkspace: need 2*N*N, prefer N*N+M*N)
-*              (RWorkspace: 0)
+*              CWorkspace: need   N*N [U] + N*N [R]
+*              CWorkspace: prefer N*N [U] + M*N [R]
+*              RWorkspace: need   0
 *
                DO 10 I = 1, M, LDWRKR
                   CHUNK = MIN( M-I+1, LDWRKR )
 *
             ELSE IF( WNTQS ) THEN
 *
-*              Path 3 (M much larger than N, JOBZ='S')
+*              Path 3 (M >> N, JOBZ='S')
 *              N left singular vectors to be computed in U and
 *              N right singular vectors to be computed in VT
 *
                NWORK = ITAU + N
 *
 *              Compute A=Q*R
-*              (CWorkspace: need N*N+2*N, prefer N*N+N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   N*N [R] + N [tau] + N    [work]
+*              CWorkspace: prefer N*N [R] + N [tau] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
      $                      LWORK-NWORK+1, IERR )
      $                      LDWRKR )
 *
 *              Generate Q in A
-*              (CWorkspace: need 2*N, prefer N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   N*N [R] + N [tau] + N    [work]
+*              CWorkspace: prefer N*N [R] + N [tau] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZUNGQR( M, N, N, A, LDA, WORK( ITAU ),
      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                NWORK = ITAUP + N
 *
 *              Bidiagonalize R in WORK(IR)
-*              (CWorkspace: need N*N+3*N, prefer N*N+2*N+2*N*NB)
-*              (RWorkspace: need N)
+*              CWorkspace: need   N*N [R] + 2*N [tauq, taup] + N      [work]
+*              CWorkspace: prefer N*N [R] + 2*N [tauq, taup] + 2*N*NB [work]
+*              RWorkspace: need   N [e]
 *
                CALL ZGEBRD( N, N, WORK( IR ), LDWRKR, S, RWORK( IE ),
      $                      WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT] + BDSPAC
 *
                IRU = IE + N
                IRVT = IRU + N*N
 *
 *              Copy real matrix RWORK(IRU) to complex matrix U
 *              Overwrite U by left singular vectors of R
-*              (CWorkspace: need N*N+3*N, prefer N*N+2*N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   N*N [R] + 2*N [tauq, taup] + N    [work]
+*              CWorkspace: prefer N*N [R] + 2*N [tauq, taup] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZLACP2( 'F', N, N, RWORK( IRU ), N, U, LDU )
                CALL ZUNMBR( 'Q', 'L', 'N', N, N, N, WORK( IR ), LDWRKR,
 *
 *              Copy real matrix RWORK(IRVT) to complex matrix VT
 *              Overwrite VT by right singular vectors of R
-*              (CWorkspace: need N*N+3*N, prefer N*N+2*N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   N*N [R] + 2*N [tauq, taup] + N    [work]
+*              CWorkspace: prefer N*N [R] + 2*N [tauq, taup] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
                CALL ZUNMBR( 'P', 'R', 'C', N, N, N, WORK( IR ), LDWRKR,
 *
 *              Multiply Q in A by left singular vectors of R in
 *              WORK(IR), storing result in U
-*              (CWorkspace: need N*N)
-*              (RWorkspace: 0)
+*              CWorkspace: need   N*N [R]
+*              RWorkspace: need   0
 *
                CALL ZLACPY( 'F', N, N, U, LDU, WORK( IR ), LDWRKR )
                CALL ZGEMM( 'N', 'N', M, N, N, CONE, A, LDA, WORK( IR ),
 *
             ELSE IF( WNTQA ) THEN
 *
-*              Path 4 (M much larger than N, JOBZ='A')
+*              Path 4 (M >> N, JOBZ='A')
 *              M left singular vectors to be computed in U and
 *              N right singular vectors to be computed in VT
 *
                NWORK = ITAU + N
 *
 *              Compute A=Q*R, copying result to U
-*              (CWorkspace: need 2*N, prefer N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   N*N [U] + N [tau] + N    [work]
+*              CWorkspace: prefer N*N [U] + N [tau] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
      $                      LWORK-NWORK+1, IERR )
                CALL ZLACPY( 'L', M, N, A, LDA, U, LDU )
 *
 *              Generate Q in U
-*              (CWorkspace: need N+M, prefer N+M*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   N*N [U] + N [tau] + M    [work]
+*              CWorkspace: prefer N*N [U] + N [tau] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZUNGQR( M, M, N, U, LDU, WORK( ITAU ),
      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                NWORK = ITAUP + N
 *
 *              Bidiagonalize R in A
-*              (CWorkspace: need 3*N, prefer 2*N+2*N*NB)
-*              (RWorkspace: need N)
+*              CWorkspace: need   N*N [U] + 2*N [tauq, taup] + N      [work]
+*              CWorkspace: prefer N*N [U] + 2*N [tauq, taup] + 2*N*NB [work]
+*              RWorkspace: need   N [e]
 *
                CALL ZGEBRD( N, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
      $                      WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT] + BDSPAC
 *
                CALL DBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
      $                      N, RWORK( IRVT ), N, DUM, IDUM,
 *
 *              Copy real matrix RWORK(IRU) to complex matrix WORK(IU)
 *              Overwrite WORK(IU) by left singular vectors of R
-*              (CWorkspace: need N*N+3*N, prefer N*N+2*N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   N*N [U] + 2*N [tauq, taup] + N    [work]
+*              CWorkspace: prefer N*N [U] + 2*N [tauq, taup] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZLACP2( 'F', N, N, RWORK( IRU ), N, WORK( IU ),
      $                      LDWRKU )
 *
 *              Copy real matrix RWORK(IRVT) to complex matrix VT
 *              Overwrite VT by right singular vectors of R
-*              (CWorkspace: need 3*N, prefer 2*N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   N*N [U] + 2*N [tauq, taup] + N    [work]
+*              CWorkspace: prefer N*N [U] + 2*N [tauq, taup] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
                CALL ZUNMBR( 'P', 'R', 'C', N, N, N, A, LDA,
 *
 *              Multiply Q in U by left singular vectors of R in
 *              WORK(IU), storing result in A
-*              (CWorkspace: need N*N)
-*              (RWorkspace: 0)
+*              CWorkspace: need   N*N [U]
+*              RWorkspace: need   0
 *
                CALL ZGEMM( 'N', 'N', M, N, N, CONE, U, LDU, WORK( IU ),
      $                     LDWRKU, CZERO, A, LDA )
 *
 *           MNTHR2 <= M < MNTHR1
 *
-*           Path 5 (M much larger than N, but not as much as MNTHR1)
+*           Path 5 (M >> N, but not as much as MNTHR1)
 *           Reduce to bidiagonal form without QR decomposition, use
 *           ZUNGBR and matrix multiplication to compute singular vectors
 *
             NWORK = ITAUP + N
 *
 *           Bidiagonalize A
-*           (CWorkspace: need 2*N+M, prefer 2*N+(M+N)*NB)
-*           (RWorkspace: need N)
+*           CWorkspace: need   2*N [tauq, taup] + M        [work]
+*           CWorkspace: prefer 2*N [tauq, taup] + (M+N)*NB [work]
+*           RWorkspace: need   N [e]
 *
             CALL ZGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
      $                   WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
      $                   IERR )
             IF( WNTQN ) THEN
 *
+*              Path 5n (M >> N, JOBZ='N')
 *              Compute singular values only
-*              (Cworkspace: 0)
-*              (Rworkspace: need BDSPAN)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + BDSPAC
 *
-               CALL DBDSDC( 'U', 'N', N, S, RWORK( IE ), DUM, 1, DUM, 1,
+               CALL DBDSDC( 'U', 'N', N, S, RWORK( IE ), DUM, 1,DUM,1,
      $                      DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
             ELSE IF( WNTQO ) THEN
                IU = NWORK
                IRVT = IRU + N*N
                NRWORK = IRVT + N*N
 *
+*              Path 5o (M >> N, JOBZ='O')
 *              Copy A to VT, generate P**H
-*              (Cworkspace: need 2*N, prefer N+N*NB)
-*              (Rworkspace: 0)
+*              CWorkspace: need   2*N [tauq, taup] + N    [work]
+*              CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZLACPY( 'U', N, N, A, LDA, VT, LDVT )
                CALL ZUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
 *
 *              Generate Q in A
-*              (CWorkspace: need 2*N, prefer N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   2*N [tauq, taup] + N    [work]
+*              CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZUNGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
 *
-               IF( LWORK.GE.M*N+3*N ) THEN
+               IF( LWORK .GE. M*N + 3*N ) THEN
 *
 *                 WORK( IU ) is M by N
 *
 *
 *                 WORK(IU) is LDWRKU by N
 *
-                  LDWRKU = ( LWORK-3*N ) / N
+                  LDWRKU = ( LWORK - 3*N ) / N
                END IF
                NWORK = IU + LDWRKU*N
 *
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT] + BDSPAC
 *
                CALL DBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
      $                      N, RWORK( IRVT ), N, DUM, IDUM,
 *
 *              Multiply real matrix RWORK(IRVT) by P**H in VT,
 *              storing the result in WORK(IU), copying to VT
-*              (Cworkspace: need 0)
-*              (Rworkspace: need 3*N*N)
+*              CWorkspace: need   2*N [tauq, taup] + N*N [U]
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT] + 2*N*N [rwork]
 *
                CALL ZLARCM( N, N, RWORK( IRVT ), N, VT, LDVT,
      $                      WORK( IU ), LDWRKU, RWORK( NRWORK ) )
 *
 *              Multiply Q in A by real matrix RWORK(IRU), storing the
 *              result in WORK(IU), copying to A
-*              (CWorkspace: need N*N, prefer M*N)
-*              (Rworkspace: need 3*N*N, prefer N*N+2*M*N)
+*              CWorkspace: need   2*N [tauq, taup] + N*N [U]
+*              CWorkspace: prefer 2*N [tauq, taup] + M*N [U]
+*              RWorkspace: need   N [e] + N*N [RU] + 2*N*N [rwork]
+*              RWorkspace: prefer N [e] + N*N [RU] + 2*M*N [rwork] < N + 5*N*N since M < 2*N here
 *
                NRWORK = IRVT
                DO 20 I = 1, M, LDWRKU
 *
             ELSE IF( WNTQS ) THEN
 *
+*              Path 5s (M >> N, JOBZ='S')
 *              Copy A to VT, generate P**H
-*              (Cworkspace: need 2*N, prefer N+N*NB)
-*              (Rworkspace: 0)
+*              CWorkspace: need   2*N [tauq, taup] + N    [work]
+*              CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZLACPY( 'U', N, N, A, LDA, VT, LDVT )
                CALL ZUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
 *
 *              Copy A to U, generate Q
-*              (Cworkspace: need 2*N, prefer N+N*NB)
-*              (Rworkspace: 0)
+*              CWorkspace: need   2*N [tauq, taup] + N    [work]
+*              CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZLACPY( 'L', M, N, A, LDA, U, LDU )
                CALL ZUNGBR( 'Q', M, N, N, U, LDU, WORK( ITAUQ ),
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT] + BDSPAC
 *
                IRU = NRWORK
                IRVT = IRU + N*N
 *
 *              Multiply real matrix RWORK(IRVT) by P**H in VT,
 *              storing the result in A, copying to VT
-*              (Cworkspace: need 0)
-*              (Rworkspace: need 3*N*N)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT] + 2*N*N [rwork]
 *
                CALL ZLARCM( N, N, RWORK( IRVT ), N, VT, LDVT, A, LDA,
      $                      RWORK( NRWORK ) )
 *
 *              Multiply Q in U by real matrix RWORK(IRU), storing the
 *              result in A, copying to U
-*              (CWorkspace: need 0)
-*              (Rworkspace: need N*N+2*M*N)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + N*N [RU] + 2*M*N [rwork] < N + 5*N*N since M < 2*N here
 *
                NRWORK = IRVT
                CALL ZLACRM( M, N, U, LDU, RWORK( IRU ), N, A, LDA,
                CALL ZLACPY( 'F', M, N, A, LDA, U, LDU )
             ELSE
 *
+*              Path 5a (M >> N, JOBZ='A')
 *              Copy A to VT, generate P**H
-*              (Cworkspace: need 2*N, prefer N+N*NB)
-*              (Rworkspace: 0)
+*              CWorkspace: need   2*N [tauq, taup] + N    [work]
+*              CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZLACPY( 'U', N, N, A, LDA, VT, LDVT )
                CALL ZUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
 *
 *              Copy A to U, generate Q
-*              (Cworkspace: need 2*N, prefer N+N*NB)
-*              (Rworkspace: 0)
+*              CWorkspace: need   2*N [tauq, taup] + M    [work]
+*              CWorkspace: prefer 2*N [tauq, taup] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZLACPY( 'L', M, N, A, LDA, U, LDU )
                CALL ZUNGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT] + BDSPAC
 *
                IRU = NRWORK
                IRVT = IRU + N*N
 *
 *              Multiply real matrix RWORK(IRVT) by P**H in VT,
 *              storing the result in A, copying to VT
-*              (Cworkspace: need 0)
-*              (Rworkspace: need 3*N*N)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT] + 2*N*N [rwork]
 *
                CALL ZLARCM( N, N, RWORK( IRVT ), N, VT, LDVT, A, LDA,
      $                      RWORK( NRWORK ) )
 *
 *              Multiply Q in U by real matrix RWORK(IRU), storing the
 *              result in A, copying to U
-*              (CWorkspace: 0)
-*              (Rworkspace: need 3*N*N)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + N*N [RU] + 2*M*N [rwork] < N + 5*N*N since M < 2*N here
 *
                NRWORK = IRVT
                CALL ZLACRM( M, N, U, LDU, RWORK( IRU ), N, A, LDA,
 *
 *           M .LT. MNTHR2
 *
-*           Path 6 (M at least N, but not much larger)
+*           Path 6 (M >= N, but not much larger)
 *           Reduce to bidiagonal form without QR decomposition
 *           Use ZUNMBR to compute singular vectors
 *
             NWORK = ITAUP + N
 *
 *           Bidiagonalize A
-*           (CWorkspace: need 2*N+M, prefer 2*N+(M+N)*NB)
-*           (RWorkspace: need N)
+*           CWorkspace: need   2*N [tauq, taup] + M        [work]
+*           CWorkspace: prefer 2*N [tauq, taup] + (M+N)*NB [work]
+*           RWorkspace: need   N [e]
 *
             CALL ZGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
      $                   WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
      $                   IERR )
             IF( WNTQN ) THEN
 *
+*              Path 6n (M >= N, JOBZ='N')
 *              Compute singular values only
-*              (Cworkspace: 0)
-*              (Rworkspace: need BDSPAN)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + BDSPAC
 *
-               CALL DBDSDC( 'U', 'N', N, S, RWORK( IE ), DUM, 1, DUM, 1,
+               CALL DBDSDC( 'U', 'N', N, S, RWORK( IE ), DUM,1,DUM,1,
      $                      DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
             ELSE IF( WNTQO ) THEN
                IU = NWORK
                IRU = NRWORK
                IRVT = IRU + N*N
                NRWORK = IRVT + N*N
-               IF( LWORK.GE.M*N+3*N ) THEN
+               IF( LWORK .GE. M*N + 3*N ) THEN
 *
 *                 WORK( IU ) is M by N
 *
 *
 *                 WORK( IU ) is LDWRKU by N
 *
-                  LDWRKU = ( LWORK-3*N ) / N
+                  LDWRKU = ( LWORK - 3*N ) / N
                END IF
                NWORK = IU + LDWRKU*N
 *
+*              Path 6o (M >= N, JOBZ='O')
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT] + BDSPAC
 *
                CALL DBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
      $                      N, RWORK( IRVT ), N, DUM, IDUM,
 *
 *              Copy real matrix RWORK(IRVT) to complex matrix VT
 *              Overwrite VT by right singular vectors of A
-*              (Cworkspace: need 2*N, prefer N+N*NB)
-*              (Rworkspace: need 0)
+*              CWorkspace: need   2*N [tauq, taup] + N*N [U] + N    [work]
+*              CWorkspace: prefer 2*N [tauq, taup] + N*N [U] + N*NB [work]
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT]
 *
                CALL ZLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
                CALL ZUNMBR( 'P', 'R', 'C', N, N, N, A, LDA,
      $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
      $                      LWORK-NWORK+1, IERR )
 *
-               IF( LWORK.GE.M*N+3*N ) THEN
+               IF( LWORK .GE. M*N + 3*N ) THEN
 *
-*              Copy real matrix RWORK(IRU) to complex matrix WORK(IU)
-*              Overwrite WORK(IU) by left singular vectors of A, copying
-*              to A
-*              (Cworkspace: need M*N+2*N, prefer M*N+N+N*NB)
-*              (Rworkspace: need 0)
+*                 Path 6o-fast
+*                 Copy real matrix RWORK(IRU) to complex matrix WORK(IU)
+*                 Overwrite WORK(IU) by left singular vectors of A, copying
+*                 to A
+*                 CWorkspace: need   2*N [tauq, taup] + M*N [U] + N    [work]
+*                 CWorkspace: prefer 2*N [tauq, taup] + M*N [U] + N*NB [work]
+*                 RWorkspace: need   N [e] + N*N [RU]
 *
                   CALL ZLASET( 'F', M, N, CZERO, CZERO, WORK( IU ),
      $                         LDWRKU )
                   CALL ZLACPY( 'F', M, N, WORK( IU ), LDWRKU, A, LDA )
                ELSE
 *
+*                 Path 6o-slow
 *                 Generate Q in A
-*                 (Cworkspace: need 2*N, prefer N+N*NB)
-*                 (Rworkspace: need 0)
+*                 CWorkspace: need   2*N [tauq, taup] + N*N [U] + N    [work]
+*                 CWorkspace: prefer 2*N [tauq, taup] + N*N [U] + N*NB [work]
+*                 RWorkspace: need   0
 *
                   CALL ZUNGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
      $                         WORK( NWORK ), LWORK-NWORK+1, IERR )
 *
 *                 Multiply Q in A by real matrix RWORK(IRU), storing the
 *                 result in WORK(IU), copying to A
-*                 (CWorkspace: need N*N, prefer M*N)
-*                 (Rworkspace: need 3*N*N, prefer N*N+2*M*N)
+*                 CWorkspace: need   2*N [tauq, taup] + N*N [U]
+*                 CWorkspace: prefer 2*N [tauq, taup] + M*N [U]
+*                 RWorkspace: need   N [e] + N*N [RU] + 2*N*N [rwork]
+*                 RWorkspace: prefer N [e] + N*N [RU] + 2*M*N [rwork] < N + 5*N*N since M < 2*N here
 *
                   NRWORK = IRVT
                   DO 30 I = 1, M, LDWRKU
 *
             ELSE IF( WNTQS ) THEN
 *
+*              Path 6s (M >= N, JOBZ='S')
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT] + BDSPAC
 *
                IRU = NRWORK
                IRVT = IRU + N*N
 *
 *              Copy real matrix RWORK(IRU) to complex matrix U
 *              Overwrite U by left singular vectors of A
-*              (CWorkspace: need 3*N, prefer 2*N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   2*N [tauq, taup] + N    [work]
+*              CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT]
 *
                CALL ZLASET( 'F', M, N, CZERO, CZERO, U, LDU )
                CALL ZLACP2( 'F', N, N, RWORK( IRU ), N, U, LDU )
 *
 *              Copy real matrix RWORK(IRVT) to complex matrix VT
 *              Overwrite VT by right singular vectors of A
-*              (CWorkspace: need 3*N, prefer 2*N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   2*N [tauq, taup] + N    [work]
+*              CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT]
 *
                CALL ZLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
                CALL ZUNMBR( 'P', 'R', 'C', N, N, N, A, LDA,
      $                      LWORK-NWORK+1, IERR )
             ELSE
 *
+*              Path 6a (M >= N, JOBZ='A')
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT] + BDSPAC
 *
                IRU = NRWORK
                IRVT = IRU + N*N
 *
 *              Copy real matrix RWORK(IRU) to complex matrix U
 *              Overwrite U by left singular vectors of A
-*              (CWorkspace: need 2*N+M, prefer 2*N+M*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   2*N [tauq, taup] + M    [work]
+*              CWorkspace: prefer 2*N [tauq, taup] + M*NB [work]
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT]
 *
                CALL ZLACP2( 'F', N, N, RWORK( IRU ), N, U, LDU )
                CALL ZUNMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
 *
 *              Copy real matrix RWORK(IRVT) to complex matrix VT
 *              Overwrite VT by right singular vectors of A
-*              (CWorkspace: need 3*N, prefer 2*N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   2*N [tauq, taup] + N    [work]
+*              CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
+*              RWorkspace: need   N [e] + N*N [RU] + N*N [RVT]
 *
                CALL ZLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
                CALL ZUNMBR( 'P', 'R', 'C', N, N, N, A, LDA,
 *
             IF( WNTQN ) THEN
 *
-*              Path 1t (N much larger than M, JOBZ='N')
+*              Path 1t (N >> M, JOBZ='N')
 *              No singular vectors to be computed
 *
                ITAU = 1
                NWORK = ITAU + M
 *
 *              Compute A=L*Q
-*              (CWorkspace: need 2*M, prefer M+M*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   M [tau] + M    [work]
+*              CWorkspace: prefer M [tau] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
      $                      LWORK-NWORK+1, IERR )
                NWORK = ITAUP + M
 *
 *              Bidiagonalize L in A
-*              (CWorkspace: need 3*M, prefer 2*M+2*M*NB)
-*              (RWorkspace: need M)
+*              CWorkspace: need   2*M [tauq, taup] + M      [work]
+*              CWorkspace: prefer 2*M [tauq, taup] + 2*M*NB [work]
+*              RWorkspace: need   M [e]
 *
                CALL ZGEBRD( M, M, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
      $                      WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
                NRWORK = IE + M
 *
 *              Perform bidiagonal SVD, compute singular values only
-*              (CWorkspace: 0)
-*              (RWorkspace: need BDSPAN)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + BDSPAC
 *
-               CALL DBDSDC( 'U', 'N', M, S, RWORK( IE ), DUM, 1, DUM, 1,
+               CALL DBDSDC( 'U', 'N', M, S, RWORK( IE ), DUM,1,DUM,1,
      $                      DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
 *
             ELSE IF( WNTQO ) THEN
 *
-*              Path 2t (N much larger than M, JOBZ='O')
+*              Path 2t (N >> M, JOBZ='O')
 *              M right singular vectors to be overwritten on A and
 *              M left singular vectors to be computed in U
 *
 *              WORK(IVT) is M by M
 *
                IL = IVT + LDWKVT*M
-               IF( LWORK.GE.M*N+M*M+3*M ) THEN
+               IF( LWORK .GE. M*N + M*M + 3*M ) THEN
 *
 *                 WORK(IL) M by N
 *
 *                 WORK(IL) is M by CHUNK
 *
                   LDWRKL = M
-                  CHUNK = ( LWORK-M*M-3*M ) / M
+                  CHUNK = ( LWORK - M*M - 3*M ) / M
                END IF
                ITAU = IL + LDWRKL*CHUNK
                NWORK = ITAU + M
 *
 *              Compute A=L*Q
-*              (CWorkspace: need 2*M, prefer M+M*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   M*M [VT] + M*M [L] + M [tau] + M    [work]
+*              CWorkspace: prefer M*M [VT] + M*M [L] + M [tau] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
      $                      LWORK-NWORK+1, IERR )
      $                      WORK( IL+LDWRKL ), LDWRKL )
 *
 *              Generate Q in A
-*              (CWorkspace: need M*M+2*M, prefer M*M+M+M*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   M*M [VT] + M*M [L] + M [tau] + M    [work]
+*              CWorkspace: prefer M*M [VT] + M*M [L] + M [tau] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZUNGLQ( M, N, M, A, LDA, WORK( ITAU ),
      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                NWORK = ITAUP + M
 *
 *              Bidiagonalize L in WORK(IL)
-*              (CWorkspace: need M*M+3*M, prefer M*M+2*M+2*M*NB)
-*              (RWorkspace: need M)
+*              CWorkspace: need   M*M [VT] + M*M [L] + 2*M [tauq, taup] + M      [work]
+*              CWorkspace: prefer M*M [VT] + M*M [L] + 2*M [tauq, taup] + 2*M*NB [work]
+*              RWorkspace: need   M [e]
 *
                CALL ZGEBRD( M, M, WORK( IL ), LDWRKL, S, RWORK( IE ),
      $                      WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + M*M [RU] + M*M [RVT] + BDSPAC
 *
                IRU = IE + M
                IRVT = IRU + M*M
 *
 *              Copy real matrix RWORK(IRU) to complex matrix WORK(IU)
 *              Overwrite WORK(IU) by the left singular vectors of L
-*              (CWorkspace: need N*N+3*N, prefer M*N+2*N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   M*M [VT] + M*M [L] + 2*M [tauq, taup] + M    [work]
+*              CWorkspace: prefer M*M [VT] + M*M [L] + 2*M [tauq, taup] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
                CALL ZUNMBR( 'Q', 'L', 'N', M, M, M, WORK( IL ), LDWRKL,
 *
 *              Copy real matrix RWORK(IRVT) to complex matrix WORK(IVT)
 *              Overwrite WORK(IVT) by the right singular vectors of L
-*              (CWorkspace: need N*N+3*N, prefer M*N+2*N+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   M*M [VT] + M*M [L] + 2*M [tauq, taup] + M    [work]
+*              CWorkspace: prefer M*M [VT] + M*M [L] + 2*M [tauq, taup] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZLACP2( 'F', M, M, RWORK( IRVT ), M, WORK( IVT ),
      $                      LDWKVT )
 *
 *              Multiply right singular vectors of L in WORK(IL) by Q
 *              in A, storing result in WORK(IL) and copying to A
-*              (CWorkspace: need 2*M*M, prefer M*M+M*N))
-*              (RWorkspace: 0)
+*              CWorkspace: need   M*M [VT] + M*M [L]
+*              CWorkspace: prefer M*M [VT] + M*N [L]
+*              RWorkspace: need   0
 *
                DO 40 I = 1, N, CHUNK
                   BLK = MIN( N-I+1, CHUNK )
 *
             ELSE IF( WNTQS ) THEN
 *
-*             Path 3t (N much larger than M, JOBZ='S')
-*             M right singular vectors to be computed in VT and
-*             M left singular vectors to be computed in U
+*              Path 3t (N >> M, JOBZ='S')
+*              M right singular vectors to be computed in VT and
+*              M left singular vectors to be computed in U
 *
                IL = 1
 *
                NWORK = ITAU + M
 *
 *              Compute A=L*Q
-*              (CWorkspace: need 2*M, prefer M+M*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   M*M [L] + M [tau] + M    [work]
+*              CWorkspace: prefer M*M [L] + M [tau] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
      $                      LWORK-NWORK+1, IERR )
      $                      WORK( IL+LDWRKL ), LDWRKL )
 *
 *              Generate Q in A
-*              (CWorkspace: need M*M+2*M, prefer M*M+M+M*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   M*M [L] + M [tau] + M    [work]
+*              CWorkspace: prefer M*M [L] + M [tau] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZUNGLQ( M, N, M, A, LDA, WORK( ITAU ),
      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                NWORK = ITAUP + M
 *
 *              Bidiagonalize L in WORK(IL)
-*              (CWorkspace: need M*M+3*M, prefer M*M+2*M+2*M*NB)
-*              (RWorkspace: need M)
+*              CWorkspace: need   M*M [L] + 2*M [tauq, taup] + M      [work]
+*              CWorkspace: prefer M*M [L] + 2*M [tauq, taup] + 2*M*NB [work]
+*              RWorkspace: need   M [e]
 *
                CALL ZGEBRD( M, M, WORK( IL ), LDWRKL, S, RWORK( IE ),
      $                      WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + M*M [RU] + M*M [RVT] + BDSPAC
 *
                IRU = IE + M
                IRVT = IRU + M*M
 *
 *              Copy real matrix RWORK(IRU) to complex matrix U
 *              Overwrite U by left singular vectors of L
-*              (CWorkspace: need M*M+3*M, prefer M*M+2*M+M*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   M*M [L] + 2*M [tauq, taup] + M    [work]
+*              CWorkspace: prefer M*M [L] + 2*M [tauq, taup] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
                CALL ZUNMBR( 'Q', 'L', 'N', M, M, M, WORK( IL ), LDWRKL,
 *
 *              Copy real matrix RWORK(IRVT) to complex matrix VT
 *              Overwrite VT by left singular vectors of L
-*              (CWorkspace: need M*M+3*M, prefer M*M+2*M+M*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   M*M [L] + 2*M [tauq, taup] + M    [work]
+*              CWorkspace: prefer M*M [L] + 2*M [tauq, taup] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZLACP2( 'F', M, M, RWORK( IRVT ), M, VT, LDVT )
                CALL ZUNMBR( 'P', 'R', 'C', M, M, M, WORK( IL ), LDWRKL,
 *
 *              Copy VT to WORK(IL), multiply right singular vectors of L
 *              in WORK(IL) by Q in A, storing result in VT
-*              (CWorkspace: need M*M)
-*              (RWorkspace: 0)
+*              CWorkspace: need   M*M [L]
+*              RWorkspace: need   0
 *
                CALL ZLACPY( 'F', M, M, VT, LDVT, WORK( IL ), LDWRKL )
                CALL ZGEMM( 'N', 'N', M, N, M, CONE, WORK( IL ), LDWRKL,
 *
             ELSE IF( WNTQA ) THEN
 *
-*              Path 9t (N much larger than M, JOBZ='A')
+*              Path 4t (N >> M, JOBZ='A')
 *              N right singular vectors to be computed in VT and
 *              M left singular vectors to be computed in U
 *
                NWORK = ITAU + M
 *
 *              Compute A=L*Q, copying result to VT
-*              (CWorkspace: need 2*M, prefer M+M*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   M*M [VT] + M [tau] + M    [work]
+*              CWorkspace: prefer M*M [VT] + M [tau] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
      $                      LWORK-NWORK+1, IERR )
                CALL ZLACPY( 'U', M, N, A, LDA, VT, LDVT )
 *
 *              Generate Q in VT
-*              (CWorkspace: need M+N, prefer M+N*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   M*M [VT] + M [tau] + N    [work]
+*              CWorkspace: prefer M*M [VT] + M [tau] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZUNGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                NWORK = ITAUP + M
 *
 *              Bidiagonalize L in A
-*              (CWorkspace: need M*M+3*M, prefer M*M+2*M+2*M*NB)
-*              (RWorkspace: need M)
+*              CWorkspace: need   M*M [VT] + 2*M [tauq, taup] + M      [work]
+*              CWorkspace: prefer M*M [VT] + 2*M [tauq, taup] + 2*M*NB [work]
+*              RWorkspace: need   M [e]
 *
                CALL ZGEBRD( M, M, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
      $                      WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + M*M [RU] + M*M [RVT] + BDSPAC
 *
                IRU = IE + M
                IRVT = IRU + M*M
 *
 *              Copy real matrix RWORK(IRU) to complex matrix U
 *              Overwrite U by left singular vectors of L
-*              (CWorkspace: need 3*M, prefer 2*M+M*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   M*M [VT] + 2*M [tauq, taup] + M    [work]
+*              CWorkspace: prefer M*M [VT] + 2*M [tauq, taup] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
                CALL ZUNMBR( 'Q', 'L', 'N', M, M, M, A, LDA,
 *
 *              Copy real matrix RWORK(IRVT) to complex matrix WORK(IVT)
 *              Overwrite WORK(IVT) by right singular vectors of L
-*              (CWorkspace: need M*M+3*M, prefer M*M+2*M+M*NB)
-*              (RWorkspace: 0)
+*              CWorkspace: need   M*M [VT] + 2*M [tauq, taup] + M    [work]
+*              CWorkspace: prefer M*M [VT] + 2*M [tauq, taup] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZLACP2( 'F', M, M, RWORK( IRVT ), M, WORK( IVT ),
      $                      LDWKVT )
 *
 *              Multiply right singular vectors of L in WORK(IVT) by
 *              Q in VT, storing result in A
-*              (CWorkspace: need M*M)
-*              (RWorkspace: 0)
+*              CWorkspace: need   M*M [VT]
+*              RWorkspace: need   0
 *
                CALL ZGEMM( 'N', 'N', M, N, M, CONE, WORK( IVT ), LDWKVT,
      $                     VT, LDVT, CZERO, A, LDA )
 *
 *           MNTHR2 <= N < MNTHR1
 *
-*           Path 5t (N much larger than M, but not as much as MNTHR1)
+*           Path 5t (N >> M, but not as much as MNTHR1)
 *           Reduce to bidiagonal form without QR decomposition, use
 *           ZUNGBR and matrix multiplication to compute singular vectors
-*
 *
             IE = 1
             NRWORK = IE + M
             NWORK = ITAUP + M
 *
 *           Bidiagonalize A
-*           (CWorkspace: need 2*M+N, prefer 2*M+(M+N)*NB)
-*           (RWorkspace: M)
+*           CWorkspace: need   2*M [tauq, taup] + N        [work]
+*           CWorkspace: prefer 2*M [tauq, taup] + (M+N)*NB [work]
+*           RWorkspace: need   M [e]
 *
             CALL ZGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
      $                   WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
 *
             IF( WNTQN ) THEN
 *
+*              Path 5tn (N >> M, JOBZ='N')
 *              Compute singular values only
-*              (Cworkspace: 0)
-*              (Rworkspace: need BDSPAN)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + BDSPAC
 *
-               CALL DBDSDC( 'L', 'N', M, S, RWORK( IE ), DUM, 1, DUM, 1,
+               CALL DBDSDC( 'L', 'N', M, S, RWORK( IE ), DUM,1,DUM,1,
      $                      DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
             ELSE IF( WNTQO ) THEN
                IRVT = NRWORK
                NRWORK = IRU + M*M
                IVT = NWORK
 *
+*              Path 5to (N >> M, JOBZ='O')
 *              Copy A to U, generate Q
-*              (Cworkspace: need 2*M, prefer M+M*NB)
-*              (Rworkspace: 0)
+*              CWorkspace: need   2*M [tauq, taup] + M    [work]
+*              CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZLACPY( 'L', M, M, A, LDA, U, LDU )
                CALL ZUNGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
 *
 *              Generate P**H in A
-*              (Cworkspace: need 2*M, prefer M+M*NB)
-*              (Rworkspace: 0)
+*              CWorkspace: need   2*M [tauq, taup] + M    [work]
+*              CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZUNGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
 *
                LDWKVT = M
-               IF( LWORK.GE.M*N+3*M ) THEN
+               IF( LWORK .GE. M*N + 3*M ) THEN
 *
 *                 WORK( IVT ) is M by N
 *
 *
 *                 WORK( IVT ) is M by CHUNK
 *
-                  CHUNK = ( LWORK-3*M ) / M
+                  CHUNK = ( LWORK - 3*M ) / M
                   NWORK = IVT + LDWKVT*CHUNK
                END IF
 *
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + M*M [RVT] + M*M [RU] + BDSPAC
 *
                CALL DBDSDC( 'L', 'I', M, S, RWORK( IE ), RWORK( IRU ),
      $                      M, RWORK( IRVT ), M, DUM, IDUM,
 *
 *              Multiply Q in U by real matrix RWORK(IRVT)
 *              storing the result in WORK(IVT), copying to U
-*              (Cworkspace: need 0)
-*              (Rworkspace: need 2*M*M)
+*              CWorkspace: need   2*M [tauq, taup] + M*M [VT]
+*              RWorkspace: need   M [e] + M*M [RVT] + M*M [RU] + 2*M*M [rwork]
 *
                CALL ZLACRM( M, M, U, LDU, RWORK( IRU ), M, WORK( IVT ),
      $                      LDWKVT, RWORK( NRWORK ) )
 *
 *              Multiply RWORK(IRVT) by P**H in A, storing the
 *              result in WORK(IVT), copying to A
-*              (CWorkspace: need M*M, prefer M*N)
-*              (Rworkspace: need 2*M*M, prefer 2*M*N)
+*              CWorkspace: need   2*M [tauq, taup] + M*M [VT]
+*              CWorkspace: prefer 2*M [tauq, taup] + M*N [VT]
+*              RWorkspace: need   M [e] + M*M [RVT] + 2*M*M [rwork]
+*              RWorkspace: prefer M [e] + M*M [RVT] + 2*M*N [rwork] < M + 5*M*M since N < 2*M here
 *
                NRWORK = IRU
                DO 50 I = 1, N, CHUNK
    50          CONTINUE
             ELSE IF( WNTQS ) THEN
 *
+*              Path 5ts (N >> M, JOBZ='S')
 *              Copy A to U, generate Q
-*              (Cworkspace: need 2*M, prefer M+M*NB)
-*              (Rworkspace: 0)
+*              CWorkspace: need   2*M [tauq, taup] + M    [work]
+*              CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZLACPY( 'L', M, M, A, LDA, U, LDU )
                CALL ZUNGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
 *
 *              Copy A to VT, generate P**H
-*              (Cworkspace: need 2*M, prefer M+M*NB)
-*              (Rworkspace: 0)
+*              CWorkspace: need   2*M [tauq, taup] + M    [work]
+*              CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZLACPY( 'U', M, N, A, LDA, VT, LDVT )
                CALL ZUNGBR( 'P', M, N, M, VT, LDVT, WORK( ITAUP ),
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + M*M [RVT] + M*M [RU] + BDSPAC
 *
                IRVT = NRWORK
                IRU = IRVT + M*M
 *
 *              Multiply Q in U by real matrix RWORK(IRU), storing the
 *              result in A, copying to U
-*              (CWorkspace: need 0)
-*              (Rworkspace: need 3*M*M)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + M*M [RVT] + M*M [RU] + 2*M*M [rwork]
 *
                CALL ZLACRM( M, M, U, LDU, RWORK( IRU ), M, A, LDA,
      $                      RWORK( NRWORK ) )
 *
 *              Multiply real matrix RWORK(IRVT) by P**H in VT,
 *              storing the result in A, copying to VT
-*              (Cworkspace: need 0)
-*              (Rworkspace: need M*M+2*M*N)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + M*M [RVT] + 2*M*N [rwork] < M + 5*M*M since N < 2*M here
 *
                NRWORK = IRU
                CALL ZLARCM( M, N, RWORK( IRVT ), M, VT, LDVT, A, LDA,
                CALL ZLACPY( 'F', M, N, A, LDA, VT, LDVT )
             ELSE
 *
+*              Path 5ta (N >> M, JOBZ='A')
 *              Copy A to U, generate Q
-*              (Cworkspace: need 2*M, prefer M+M*NB)
-*              (Rworkspace: 0)
+*              CWorkspace: need   2*M [tauq, taup] + M    [work]
+*              CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZLACPY( 'L', M, M, A, LDA, U, LDU )
                CALL ZUNGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
 *
 *              Copy A to VT, generate P**H
-*              (Cworkspace: need 2*M, prefer M+M*NB)
-*              (Rworkspace: 0)
+*              CWorkspace: need   2*M [tauq, taup] + N    [work]
+*              CWorkspace: prefer 2*M [tauq, taup] + N*NB [work]
+*              RWorkspace: need   0
 *
                CALL ZLACPY( 'U', M, N, A, LDA, VT, LDVT )
                CALL ZUNGBR( 'P', N, N, M, VT, LDVT, WORK( ITAUP ),
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + M*M [RVT] + M*M [RU] + BDSPAC
 *
                IRVT = NRWORK
                IRU = IRVT + M*M
 *
 *              Multiply Q in U by real matrix RWORK(IRU), storing the
 *              result in A, copying to U
-*              (CWorkspace: need 0)
-*              (Rworkspace: need 3*M*M)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + M*M [RVT] + M*M [RU] + 2*M*M [rwork]
 *
                CALL ZLACRM( M, M, U, LDU, RWORK( IRU ), M, A, LDA,
      $                      RWORK( NRWORK ) )
 *
 *              Multiply real matrix RWORK(IRVT) by P**H in VT,
 *              storing the result in A, copying to VT
-*              (Cworkspace: need 0)
-*              (Rworkspace: need M*M+2*M*N)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + M*M [RVT] + 2*M*N [rwork] < M + 5*M*M since N < 2*M here
 *
+               NRWORK = IRU
                CALL ZLARCM( M, N, RWORK( IRVT ), M, VT, LDVT, A, LDA,
      $                      RWORK( NRWORK ) )
                CALL ZLACPY( 'F', M, N, A, LDA, VT, LDVT )
 *
 *           N .LT. MNTHR2
 *
-*           Path 6t (N greater than M, but not much larger)
+*           Path 6t (N > M, but not much larger)
 *           Reduce to bidiagonal form without LQ decomposition
 *           Use ZUNMBR to compute singular vectors
 *
             NWORK = ITAUP + M
 *
 *           Bidiagonalize A
-*           (CWorkspace: need 2*M+N, prefer 2*M+(M+N)*NB)
-*           (RWorkspace: M)
+*           CWorkspace: need   2*M [tauq, taup] + N        [work]
+*           CWorkspace: prefer 2*M [tauq, taup] + (M+N)*NB [work]
+*           RWorkspace: need   M [e]
 *
             CALL ZGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
      $                   WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
      $                   IERR )
             IF( WNTQN ) THEN
 *
+*              Path 6tn (N > M, JOBZ='N')
 *              Compute singular values only
-*              (Cworkspace: 0)
-*              (Rworkspace: need BDSPAN)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + BDSPAC
 *
-               CALL DBDSDC( 'L', 'N', M, S, RWORK( IE ), DUM, 1, DUM, 1,
+               CALL DBDSDC( 'L', 'N', M, S, RWORK( IE ), DUM,1,DUM,1,
      $                      DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
             ELSE IF( WNTQO ) THEN
+*              Path 6to (N > M, JOBZ='O')
                LDWKVT = M
                IVT = NWORK
-               IF( LWORK.GE.M*N+3*M ) THEN
+               IF( LWORK .GE. M*N + 3*M ) THEN
 *
 *                 WORK( IVT ) is M by N
 *
 *
 *                 WORK( IVT ) is M by CHUNK
 *
-                  CHUNK = ( LWORK-3*M ) / M
+                  CHUNK = ( LWORK - 3*M ) / M
                   NWORK = IVT + LDWKVT*CHUNK
                END IF
 *
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + M*M [RVT] + M*M [RU] + BDSPAC
 *
                IRVT = NRWORK
                IRU = IRVT + M*M
 *
 *              Copy real matrix RWORK(IRU) to complex matrix U
 *              Overwrite U by left singular vectors of A
-*              (Cworkspace: need 2*M, prefer M+M*NB)
-*              (Rworkspace: need 0)
+*              CWorkspace: need   2*M [tauq, taup] + M*M [VT] + M    [work]
+*              CWorkspace: prefer 2*M [tauq, taup] + M*M [VT] + M*NB [work]
+*              RWorkspace: need   M [e] + M*M [RVT] + M*M [RU]
 *
                CALL ZLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
                CALL ZUNMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
      $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),
      $                      LWORK-NWORK+1, IERR )
 *
-               IF( LWORK.GE.M*N+3*M ) THEN
+               IF( LWORK .GE. M*N + 3*M ) THEN
 *
-*              Copy real matrix RWORK(IRVT) to complex matrix WORK(IVT)
-*              Overwrite WORK(IVT) by right singular vectors of A,
-*              copying to A
-*              (Cworkspace: need M*N+2*M, prefer M*N+M+M*NB)
-*              (Rworkspace: need 0)
+*                 Path 6to-fast
+*                 Copy real matrix RWORK(IRVT) to complex matrix WORK(IVT)
+*                 Overwrite WORK(IVT) by right singular vectors of A,
+*                 copying to A
+*                 CWorkspace: need   2*M [tauq, taup] + M*N [VT] + M    [work]
+*                 CWorkspace: prefer 2*M [tauq, taup] + M*N [VT] + M*NB [work]
+*                 RWorkspace: need   M [e] + M*M [RVT]
 *
                   CALL ZLACP2( 'F', M, M, RWORK( IRVT ), M, WORK( IVT ),
      $                         LDWKVT )
                   CALL ZLACPY( 'F', M, N, WORK( IVT ), LDWKVT, A, LDA )
                ELSE
 *
+*                 Path 6to-slow
 *                 Generate P**H in A
-*                 (Cworkspace: need 2*M, prefer M+M*NB)
-*                 (Rworkspace: need 0)
+*                 CWorkspace: need   2*M [tauq, taup] + M*M [VT] + M    [work]
+*                 CWorkspace: prefer 2*M [tauq, taup] + M*M [VT] + M*NB [work]
+*                 RWorkspace: need   0
 *
                   CALL ZUNGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
      $                         WORK( NWORK ), LWORK-NWORK+1, IERR )
 *
 *                 Multiply Q in A by real matrix RWORK(IRU), storing the
 *                 result in WORK(IU), copying to A
-*                 (CWorkspace: need M*M, prefer M*N)
-*                 (Rworkspace: need 3*M*M, prefer M*M+2*M*N)
+*                 CWorkspace: need   2*M [tauq, taup] + M*M [VT]
+*                 CWorkspace: prefer 2*M [tauq, taup] + M*N [VT]
+*                 RWorkspace: need   M [e] + M*M [RVT] + 2*M*M [rwork]
+*                 RWorkspace: prefer M [e] + M*M [RVT] + 2*M*N [rwork] < M + 5*M*M since N < 2*M here
 *
                   NRWORK = IRU
                   DO 60 I = 1, N, CHUNK
                END IF
             ELSE IF( WNTQS ) THEN
 *
+*              Path 6ts (N > M, JOBZ='S')
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + M*M [RVT] + M*M [RU] + BDSPAC
 *
                IRVT = NRWORK
                IRU = IRVT + M*M
 *
 *              Copy real matrix RWORK(IRU) to complex matrix U
 *              Overwrite U by left singular vectors of A
-*              (CWorkspace: need 3*M, prefer 2*M+M*NB)
-*              (RWorkspace: M*M)
+*              CWorkspace: need   2*M [tauq, taup] + M    [work]
+*              CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
+*              RWorkspace: need   M [e] + M*M [RVT] + M*M [RU]
 *
                CALL ZLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
                CALL ZUNMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
 *
 *              Copy real matrix RWORK(IRVT) to complex matrix VT
 *              Overwrite VT by right singular vectors of A
-*              (CWorkspace: need 3*M, prefer 2*M+M*NB)
-*              (RWorkspace: M*M)
+*              CWorkspace: need   2*M [tauq, taup] + M    [work]
+*              CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
+*              RWorkspace: need   M [e] + M*M [RVT]
 *
                CALL ZLASET( 'F', M, N, CZERO, CZERO, VT, LDVT )
                CALL ZLACP2( 'F', M, M, RWORK( IRVT ), M, VT, LDVT )
      $                      LWORK-NWORK+1, IERR )
             ELSE
 *
+*              Path 6ta (N > M, JOBZ='A')
 *              Perform bidiagonal SVD, computing left singular vectors
 *              of bidiagonal matrix in RWORK(IRU) and computing right
 *              singular vectors of bidiagonal matrix in RWORK(IRVT)
-*              (CWorkspace: need 0)
-*              (RWorkspace: need BDSPAC)
+*              CWorkspace: need   0
+*              RWorkspace: need   M [e] + M*M [RVT] + M*M [RU] + BDSPAC
 *
                IRVT = NRWORK
                IRU = IRVT + M*M
 *
 *              Copy real matrix RWORK(IRU) to complex matrix U
 *              Overwrite U by left singular vectors of A
-*              (CWorkspace: need 3*M, prefer 2*M+M*NB)
-*              (RWorkspace: M*M)
+*              CWorkspace: need   2*M [tauq, taup] + M    [work]
+*              CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
+*              RWorkspace: need   M [e] + M*M [RVT] + M*M [RU]
 *
                CALL ZLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
                CALL ZUNMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
 *
 *              Copy real matrix RWORK(IRVT) to complex matrix VT
 *              Overwrite VT by right singular vectors of A
-*              (CWorkspace: need 2*M+N, prefer 2*M+N*NB)
-*              (RWorkspace: M*M)
+*              CWorkspace: need   2*M [tauq, taup] + N    [work]
+*              CWorkspace: prefer 2*M [tauq, taup] + N*NB [work]
+*              RWorkspace: need   M [e] + M*M [RVT]
 *
                CALL ZLACP2( 'F', M, M, RWORK( IRVT ), M, VT, LDVT )
                CALL ZUNMBR( 'P', 'R', 'C', N, N, M, A, LDA,
index 966e02273f83dfa996be32bcc5640d656304b1b3..5f66bcb1e1c557d3f77f0a2baf281c457e448295 100644 (file)
       SUBROUTINE ZGESVD( JOBU, JOBVT, M, N, A, LDA, S, U, LDU, 
      $                   VT, LDVT, WORK, LWORK, RWORK, INFO )
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     April 2012
             MNTHR = ILAENV( 6, 'ZGESVD', JOBU // JOBVT, M, N, 0, 0 )
 *           Compute space needed for ZGEQRF
             CALL ZGEQRF( M, N, A, LDA, CDUM(1), CDUM(1), -1, IERR )
-            LWORK_ZGEQRF=CDUM(1)
+            LWORK_ZGEQRF = INT( CDUM(1) )
 *           Compute space needed for ZUNGQR
             CALL ZUNGQR( M, N, N, A, LDA, CDUM(1), CDUM(1), -1, IERR )
-            LWORK_ZUNGQR_N=CDUM(1)
+            LWORK_ZUNGQR_N = INT( CDUM(1) )
             CALL ZUNGQR( M, M, N, A, LDA, CDUM(1), CDUM(1), -1, IERR )
-            LWORK_ZUNGQR_M=CDUM(1)
+            LWORK_ZUNGQR_M = INT( CDUM(1) )
 *           Compute space needed for ZGEBRD
             CALL ZGEBRD( N, N, A, LDA, S, DUM(1), CDUM(1),
      $                   CDUM(1), CDUM(1), -1, IERR )
-            LWORK_ZGEBRD=CDUM(1)
+            LWORK_ZGEBRD = INT( CDUM(1) )
 *           Compute space needed for ZUNGBR
             CALL ZUNGBR( 'P', N, N, N, A, LDA, CDUM(1),
      $                   CDUM(1), -1, IERR )
-            LWORK_ZUNGBR_P=CDUM(1)
+            LWORK_ZUNGBR_P = INT( CDUM(1) )
             CALL ZUNGBR( 'Q', N, N, N, A, LDA, CDUM(1),
      $                   CDUM(1), -1, IERR )
-            LWORK_ZUNGBR_Q=CDUM(1)
+            LWORK_ZUNGBR_Q = INT( CDUM(1) )
 *
             IF( M.GE.MNTHR ) THEN
                IF( WNTUN ) THEN
 *
                CALL ZGEBRD( M, N, A, LDA, S, DUM(1), CDUM(1),
      $                   CDUM(1), CDUM(1), -1, IERR )
-               LWORK_ZGEBRD=CDUM(1)
+               LWORK_ZGEBRD = INT( CDUM(1) )
                MAXWRK = 2*N + LWORK_ZGEBRD
                IF( WNTUS .OR. WNTUO ) THEN
                   CALL ZUNGBR( 'Q', M, N, N, A, LDA, CDUM(1),
      $                   CDUM(1), -1, IERR )
-                  LWORK_ZUNGBR_Q=CDUM(1)
+                  LWORK_ZUNGBR_Q = INT( CDUM(1) )
                   MAXWRK = MAX( MAXWRK, 2*N+LWORK_ZUNGBR_Q )
                END IF
                IF( WNTUA ) THEN
                   CALL ZUNGBR( 'Q', M, M, N, A, LDA, CDUM(1),
      $                   CDUM(1), -1, IERR )
-                  LWORK_ZUNGBR_Q=CDUM(1)
+                  LWORK_ZUNGBR_Q = INT( CDUM(1) )
                   MAXWRK = MAX( MAXWRK, 2*N+LWORK_ZUNGBR_Q )
                END IF
                IF( .NOT.WNTVN ) THEN
                   MAXWRK = MAX( MAXWRK, 2*N+LWORK_ZUNGBR_P )
-               MINWRK = 2*N + M
                END IF
+               MINWRK = 2*N + M
             END IF
          ELSE IF( MINMN.GT.0 ) THEN
 *
             MNTHR = ILAENV( 6, 'ZGESVD', JOBU // JOBVT, M, N, 0, 0 )
 *           Compute space needed for ZGELQF
             CALL ZGELQF( M, N, A, LDA, CDUM(1), CDUM(1), -1, IERR )
-            LWORK_ZGELQF=CDUM(1)
+            LWORK_ZGELQF = INT( CDUM(1) )
 *           Compute space needed for ZUNGLQ
             CALL ZUNGLQ( N, N, M, CDUM(1), N, CDUM(1), CDUM(1), -1,
      $                   IERR )
-            LWORK_ZUNGLQ_N=CDUM(1)
+            LWORK_ZUNGLQ_N = INT( CDUM(1) )
             CALL ZUNGLQ( M, N, M, A, LDA, CDUM(1), CDUM(1), -1, IERR )
-            LWORK_ZUNGLQ_M=CDUM(1)
+            LWORK_ZUNGLQ_M = INT( CDUM(1) )
 *           Compute space needed for ZGEBRD
             CALL ZGEBRD( M, M, A, LDA, S, DUM(1), CDUM(1),
      $                   CDUM(1), CDUM(1), -1, IERR )
-            LWORK_ZGEBRD=CDUM(1)
+            LWORK_ZGEBRD = INT( CDUM(1) )
 *            Compute space needed for ZUNGBR P
             CALL ZUNGBR( 'P', M, M, M, A, N, CDUM(1),
      $                   CDUM(1), -1, IERR )
-            LWORK_ZUNGBR_P=CDUM(1)
+            LWORK_ZUNGBR_P = INT( CDUM(1) )
 *           Compute space needed for ZUNGBR Q
             CALL ZUNGBR( 'Q', M, M, M, A, N, CDUM(1),
      $                   CDUM(1), -1, IERR )
-            LWORK_ZUNGBR_Q=CDUM(1)
+            LWORK_ZUNGBR_Q = INT( CDUM(1) )
             IF( N.GE.MNTHR ) THEN
                IF( WNTVN ) THEN
 *
 *
                CALL ZGEBRD( M, N, A, LDA, S, DUM(1), CDUM(1),
      $                   CDUM(1), CDUM(1), -1, IERR )
-               LWORK_ZGEBRD=CDUM(1)
+               LWORK_ZGEBRD = INT( CDUM(1) )
                MAXWRK = 2*M + LWORK_ZGEBRD
                IF( WNTVS .OR. WNTVO ) THEN
 *                Compute space needed for ZUNGBR P
                  CALL ZUNGBR( 'P', M, N, M, A, N, CDUM(1),
      $                   CDUM(1), -1, IERR )
-                 LWORK_ZUNGBR_P=CDUM(1)
+                 LWORK_ZUNGBR_P = INT( CDUM(1) )
                  MAXWRK = MAX( MAXWRK, 2*M+LWORK_ZUNGBR_P )
                END IF
                IF( WNTVA ) THEN
                  CALL ZUNGBR( 'P', N,  N, M, A, N, CDUM(1),
      $                   CDUM(1), -1, IERR )
-                 LWORK_ZUNGBR_P=CDUM(1)
+                 LWORK_ZUNGBR_P = INT( CDUM(1) )
                  MAXWRK = MAX( MAXWRK, 2*M+LWORK_ZUNGBR_P )
                END IF
                IF( .NOT.WNTUN ) THEN
                   MAXWRK = MAX( MAXWRK, 2*M+LWORK_ZUNGBR_Q )
-               MINWRK = 2*M + N
                END IF
+               MINWRK = 2*M + N
             END IF
          END IF
          MAXWRK = MAX( MAXWRK, MINWRK )
 *
 *              Zero out below R
 *
-               CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO, A( 2, 1 ),
-     $                      LDA )
+               IF( N .GT. 1 ) THEN
+                  CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO, A( 2, 1 ),
+     $                         LDA )
+               END IF
                IE = 1
                ITAUQ = 1
                ITAUP = ITAUQ + N
 *
 *                    Zero out below R in A
 *
-                     CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO,
-     $                            A( 2, 1 ), LDA )
+                     IF( N .GT. 1 ) THEN
+                        CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                               A( 2, 1 ), LDA )
+                     END IF
 *
 *                    Bidiagonalize R in A
 *                    (CWorkspace: need 3*N, prefer 2*N+2*N*NB)
 *
 *                    Zero out below R in A
 *
-                     CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO,
-     $                            A( 2, 1 ), LDA )
+                     IF( N .GT. 1 ) THEN
+                        CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                               A( 2, 1 ), LDA )
+                     END IF
 *
 *                    Bidiagonalize R in A
 *                    (CWorkspace: need 3*N, prefer 2*N+2*N*NB)
 *
 *                    Zero out below R in A
 *
-                     CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO,
-     $                            A( 2, 1 ), LDA )
+                     IF( N .GT. 1 ) THEN
+                        CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                               A( 2, 1 ), LDA )
+                     END IF
 *
 *                    Bidiagonalize R in A
 *                    (CWorkspace: need 3*N, prefer 2*N+2*N*NB)
 *
 *                    Zero out below R in A
 *
-                     CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO,
-     $                            A( 2, 1 ), LDA )
+                     IF( N .GT. 1 ) THEN
+                        CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO,
+     $                               A( 2, 1 ), LDA )
+                     END IF
 *
 *                    Bidiagonalize R in A
 *                    (CWorkspace: need 3*N, prefer 2*N+2*N*NB)
index 6f7d5ba04d11f602cf0e98c6314b29ecb548da67..27428732ca869686c1c75ef304ea78c1766dfc49 100644 (file)
 *     ..
 *
 *
-*  Purpose
-*  =======
-*
-*  ZGESVDX computes the singular value decomposition (SVD) of a complex
-*  M-by-N matrix A, optionally computing the left and/or right singular
-*  vectors. The SVD is written
-* 
-*       A = U * SIGMA * transpose(V)
-* 
-*  where SIGMA is an M-by-N matrix which is zero except for its
-*  min(m,n) diagonal elements, U is an M-by-M unitary matrix, and
-*  V is an N-by-N unitary matrix.  The diagonal elements of SIGMA
-*  are the singular values of A; they are real and non-negative, and
-*  are returned in descending order.  The first min(m,n) columns of
-*  U and V are the left and right singular vectors of A.
-* 
-*  ZGESVDX uses an eigenvalue problem for obtaining the SVD, which 
-*  allows for the computation of a subset of singular values and 
-*  vectors. See DBDSVDX for details.
-* 
-*  Note that the routine returns V**T, not V.
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>  ZGESVDX computes the singular value decomposition (SVD) of a complex
+*>  M-by-N matrix A, optionally computing the left and/or right singular
+*>  vectors. The SVD is written
+*>
+*>      A = U * SIGMA * transpose(V)
+*>
+*>  where SIGMA is an M-by-N matrix which is zero except for its
+*>  min(m,n) diagonal elements, U is an M-by-M unitary matrix, and
+*>  V is an N-by-N unitary matrix.  The diagonal elements of SIGMA
+*>  are the singular values of A; they are real and non-negative, and
+*>  are returned in descending order.  The first min(m,n) columns of
+*>  U and V are the left and right singular vectors of A.
+*>
+*>  ZGESVDX uses an eigenvalue problem for obtaining the SVD, which
+*>  allows for the computation of a subset of singular values and
+*>  vectors. See DBDSVDX for details.
+*>
+*>  Note that the routine returns V**T, not V.
+*> \endverbatim
 *   
 *  Arguments:
 *  ==========
 *>
 *> \param[in,out] A
 *> \verbatim
-*>          A is COMPLEX array, dimension (LDA,N)
+*>          A is COMPLEX*16 array, dimension (LDA,N)
 *>          On entry, the M-by-N matrix A.
 *>          On exit, the contents of A are destroyed.
 *> \endverbatim
 *> \param[in] VL
 *> \verbatim
 *>          VL is DOUBLE PRECISION
-*>          VL >=0.
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for singular values. VU > VL.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is DOUBLE PRECISION
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for singular values. VU > VL.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest singular value to be returned.
+*>          1 <= IL <= IU <= min(M,N), if min(M,N) > 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest singular values to be returned.
+*>          If RANGE='I', the index of the
+*>          largest singular value to be returned.
 *>          1 <= IL <= IU <= min(M,N), if min(M,N) > 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>          vectors, stored columnwise) as specified by RANGE; if 
 *>          JOBU = 'N', U is not referenced.
 *>          Note: The user must ensure that UCOL >= NS; if RANGE = 'V', 
-*>          the exact value of NS is not known ILQFin advance and an upper 
+*>          the exact value of NS is not known in advance and an upper
 *>          bound must be used.
 *> \endverbatim
 *>
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complex16GEsing
 *
      $                    IL, IU, NS, S, U, LDU, VT, LDVT, WORK, 
      $                    LWORK, RWORK, IWORK, INFO )
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBU, JOBVT, RANGE
       CHARACTER          JOBZ, RNGTGK
       LOGICAL            ALLS, INDS, LQUERY, VALS, WANTU, WANTVT
       INTEGER            I, ID, IE, IERR, ILQF, ILTGK, IQRF, ISCL,
-     $                   ITAU, ITAUP, ITAUQ, ITEMP, ITGKZ, IUTGK,
-     $                   J, K, MAXWRK, MINMN, MINWRK, MNTHR
+     $                   ITAU, ITAUP, ITAUQ, ITEMP, ITEMPR, ITGKZ, 
+     $                   IUTGK, J, K, MAXWRK, MINMN, MINWRK, MNTHR
       DOUBLE PRECISION   ABSTOL, ANRM, BIGNUM, EPS, SMLNUM
 *     ..
 *     .. Local Arrays ..
          IF( INFO.EQ.0 ) THEN
             IF( WANTU .AND. LDU.LT.M ) THEN
                INFO = -15
-            ELSE IF( WANTVT .AND. LDVT.LT.MINMN ) THEN
-               INFO = -16
+            ELSE IF( WANTVT ) THEN
+               IF( INDS ) THEN
+                   IF( LDVT.LT.IU-IL+1 ) THEN
+                       INFO = -17
+                   END IF
+               ELSE IF( LDVT.LT.MINMN ) THEN
+                   INFO = -17
+               END IF
             END IF
          END IF
       END IF
 *
 *                 Path 1 (M much larger than N)
 *
-                  MAXWRK = N + N*
-     $                     ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
-                  MAXWRK = MAX( MAXWRK, N*N + N + 2*N*
-     $                     ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
-                  MINWRK = N*(N+4)
+                  MINWRK = N*(N+5)
+                  MAXWRK = N + N*ILAENV(1,'ZGEQRF',' ',M,N,-1,-1)
+                  MAXWRK = MAX(MAXWRK,
+     $                     N*N+2*N+2*N*ILAENV(1,'ZGEBRD',' ',N,N,-1,-1))
+                  IF (WANTU .OR. WANTVT) THEN
+                     MAXWRK = MAX(MAXWRK,
+     $                       N*N+2*N+N*ILAENV(1,'ZUNMQR','LN',N,N,N,-1))
+                  END IF
                ELSE
 *
 *                 Path 2 (M at least N, but not much larger)
 *
-                  MAXWRK = 2*N + ( M+N )*
-     $                     ILAENV( 1, 'ZGEBRD', ' ', M, N, -1, -1 )
-                  MINWRK = 2*N + M
+                  MINWRK = 3*N + M
+                  MAXWRK = 2*N + (M+N)*ILAENV(1,'ZGEBRD',' ',M,N,-1,-1)
+                  IF (WANTU .OR. WANTVT) THEN
+                     MAXWRK = MAX(MAXWRK,
+     $                        2*N+N*ILAENV(1,'ZUNMQR','LN',N,N,N,-1))
+                  END IF
                END IF
             ELSE
                MNTHR = ILAENV( 6, 'ZGESVD', JOBU // JOBVT, M, N, 0, 0 )
 *
 *                 Path 1t (N much larger than M)
 *
-                  MAXWRK = M + M*
-     $                     ILAENV( 1, 'ZGELQF', ' ', M, N, -1, -1 )
-                  MAXWRK = MAX( MAXWRK, M*M + M + 2*M*
-     $                     ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) )
-                  MINWRK = M*(M+4)
+                  MINWRK = M*(M+5)
+                  MAXWRK = M + M*ILAENV(1,'ZGELQF',' ',M,N,-1,-1)
+                  MAXWRK = MAX(MAXWRK,
+     $                     M*M+2*M+2*M*ILAENV(1,'ZGEBRD',' ',M,M,-1,-1))
+                  IF (WANTU .OR. WANTVT) THEN
+                     MAXWRK = MAX(MAXWRK,
+     $                       M*M+2*M+M*ILAENV(1,'ZUNMQR','LN',M,M,M,-1))
+                  END IF
                ELSE
 *
 *                 Path 2t (N greater than M, but not much larger)
 *
-                  MAXWRK = M*(M*2+19) + ( M+N )*
-     $                     ILAENV( 1, 'ZGEBRD', ' ', M, N, -1, -1 )
-                  MINWRK = 2*M + N
+*
+                  MINWRK = 3*M + N
+                  MAXWRK = 2*M + (M+N)*ILAENV(1,'ZGEBRD',' ',M,N,-1,-1)
+                  IF (WANTU .OR. WANTVT) THEN
+                     MAXWRK = MAX(MAXWRK,
+     $                        2*M+M*ILAENV(1,'ZUNMQR','LN',M,M,M,-1))
+                  END IF
                END IF
             END IF
          END IF
 *
 *     Set singular values indices accord to RANGE='A'.
 *
-      ALLS = LSAME( RANGE, 'A' )
-      INDS = LSAME( RANGE, 'I' )
       IF( ALLS ) THEN
          RNGTGK = 'I'
          ILTGK = 1
             CALL ZGEBRD( N, N, WORK( IQRF ), N, RWORK( ID ), 
      $                   RWORK( IE ), WORK( ITAUQ ), WORK( ITAUP ),
      $                   WORK( ITEMP ), LWORK-ITEMP+1, INFO )
-            ITEMP = ITGKZ + N*(N*2+1)
+            ITEMPR = ITGKZ + N*(N*2+1)
 *
 *           Solve eigenvalue problem TGK*Z=Z*S.
 *           (Workspace: need 2*N*N+14*N)          
 *                   
             CALL DBDSVDX( 'U', JOBZ, RNGTGK, N, RWORK( ID ),
      $                    RWORK( IE ), VL, VU, ILTGK, IUTGK, NS, S,
-     $                    RWORK( ITGKZ ), N*2, RWORK( ITEMP ),
+     $                    RWORK( ITGKZ ), N*2, RWORK( ITEMPR ),
      $                    IWORK, INFO)
 *
 *           If needed, compute left singular vectors.
                   END DO
                   K = K + N
                END DO
-               CALL ZLASET( 'A', M-N, N, CZERO, CZERO, U( N+1,1 ), LDU )
+               CALL ZLASET( 'A', M-N, NS, CZERO, CZERO, U( N+1,1 ), LDU)
 *
 *              Call ZUNMBR to compute QB*UB.
 *              (Workspace in WORK( ITEMP ): need N, prefer N*NB)
             CALL ZGEBRD( M, N, A, LDA, RWORK( ID ), RWORK( IE ), 
      $                   WORK( ITAUQ ), WORK( ITAUP ), WORK( ITEMP ),
      $                   LWORK-ITEMP+1, INFO )
-            ITEMP = ITGKZ + N*(N*2+1)
+            ITEMPR = ITGKZ + N*(N*2+1)
 *
 *           Solve eigenvalue problem TGK*Z=Z*S.
 *           (Workspace: need 2*N*N+14*N)          
 *                     
             CALL DBDSVDX( 'U', JOBZ, RNGTGK, N, RWORK( ID ),
      $                    RWORK( IE ), VL, VU, ILTGK, IUTGK, NS, S, 
-     $                    RWORK( ITGKZ ), N*2, RWORK( ITEMP ), 
+     $                    RWORK( ITGKZ ), N*2, RWORK( ITEMPR ), 
      $                    IWORK, INFO)
 *
 *           If needed, compute left singular vectors.
                   END DO
                   K = K + N
                END DO
-               CALL ZLASET( 'A', M-N, N, CZERO, CZERO, U( N+1,1 ), LDU )
+               CALL ZLASET( 'A', M-N, NS, CZERO, CZERO, U( N+1,1 ), LDU)
 *
 *              Call ZUNMBR to compute QB*UB.
 *              (Workspace in WORK( ITEMP ): need N, prefer N*NB)
             CALL ZGEBRD( M, M, WORK( ILQF ), M, RWORK( ID ),
      $                   RWORK( IE ), WORK( ITAUQ ), WORK( ITAUP ), 
      $                   WORK( ITEMP ), LWORK-ITEMP+1, INFO )
-            ITEMP = ITGKZ + M*(M*2+1)
+            ITEMPR = ITGKZ + M*(M*2+1)
 *
 *           Solve eigenvalue problem TGK*Z=Z*S.
 *           (Workspace: need 2*M*M+14*M)          
 *
             CALL DBDSVDX( 'U', JOBZ, RNGTGK, M, RWORK( ID ),
      $                    RWORK( IE ), VL, VU, ILTGK, IUTGK, NS, S, 
-     $                    RWORK( ITGKZ ), M*2, RWORK( ITEMP ), 
+     $                    RWORK( ITGKZ ), M*2, RWORK( ITEMPR ), 
      $                    IWORK, INFO)
 *
 *           If needed, compute left singular vectors.
                   END DO
                   K = K + M
                END DO
-               CALL ZLASET( 'A', M, N-M, CZERO, CZERO, 
+               CALL ZLASET( 'A', NS, N-M, CZERO, CZERO,
      $                      VT( 1,M+1 ), LDVT )
 *
 *              Call ZUNMBR to compute (VB**T)*(PB**T)
             CALL ZGEBRD( M, N, A, LDA, RWORK( ID ), RWORK( IE ), 
      $                   WORK( ITAUQ ), WORK( ITAUP ), WORK( ITEMP ),
      $                   LWORK-ITEMP+1, INFO )
-            ITEMP = ITGKZ + M*(M*2+1)
+            ITEMPR = ITGKZ + M*(M*2+1)
 *
 *           Solve eigenvalue problem TGK*Z=Z*S.
 *           (Workspace: need 2*M*M+14*M)          
 *          
             CALL DBDSVDX( 'L', JOBZ, RNGTGK, M, RWORK( ID ), 
      $                    RWORK( IE ), VL, VU, ILTGK, IUTGK, NS, S, 
-     $                    RWORK( ITGKZ ), M*2, RWORK( ITEMP ), 
+     $                    RWORK( ITGKZ ), M*2, RWORK( ITEMPR ), 
      $                    IWORK, INFO)
 * 
 *           If needed, compute left singular vectors.
                   END DO
                   K = K + M
                END DO
-               CALL ZLASET( 'A', M, N-M, CZERO, CZERO, 
+               CALL ZLASET( 'A', NS, N-M, CZERO, CZERO,
      $                      VT( 1,M+1 ), LDVT )
 *
 *              Call ZUNMBR to compute VB**T * PB**T
index 930a3530958975318856e8bb5696dd98a02e4fc8..e4b6969f72aed4442a5ba46a9368d3a2d21962da 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup doubleGEcomputational
 *
       SUBROUTINE ZGESVJ( JOBA, JOBU, JOBV, M, N, A, LDA, SVA, MV, V, 
      $                   LDV, CWORK, LWORK, RWORK, LRWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
       IMPLICIT NONE 
 *     .. Scalar Arguments ..
 *     ..
 *     ..
 *     .. Intrinsic Functions ..
-      INTRINSIC ABS, DMAX1, DMIN1, DCONJG, DFLOAT, MIN0, MAX0, 
+      INTRINSIC ABS, DMAX1, DMIN1, DCONJG, DBLE, MIN0, MAX0, 
      $          DSIGN, DSQRT
 *     ..
 *     .. External Functions ..
 *     from BLAS
       EXTERNAL           ZCOPY, ZROT, ZDSCAL, ZSWAP
 *     from LAPACK
-      EXTERNAL           ZLASCL, ZLASET, ZLASSQ, XERBLA
+      EXTERNAL           DLASCL, ZLASCL, ZLASET, ZLASSQ, XERBLA
       EXTERNAL           ZGSVJ0, ZGSVJ1
 *     ..
 *     .. Executable Statements ..
       ELSE
 *        ... default
          IF( LSVEC .OR. RSVEC .OR. APPLV ) THEN
-            CTOL = DSQRT( DFLOAT( M ) )
+            CTOL = DSQRT( DBLE( M ) )
          ELSE
-            CTOL = DFLOAT( M )
+            CTOL = DBLE( M )
          END IF
       END IF
 *     ... and the machine dependent parameters are
       BIG = DLAMCH( 'Overflow' )
 *     BIG         = ONE    / SFMIN
       ROOTBIG = ONE / ROOTSFMIN
-      LARGE = BIG / DSQRT( DFLOAT( M*N ) )
+      LARGE = BIG / DSQRT( DBLE( M*N ) )
       BIGTHETA = ONE / ROOTEPS
 *
       TOL = CTOL*EPSLN
       ROOTTOL = DSQRT( TOL )
 *
-      IF( DFLOAT( M )*EPSLN.GE.ONE ) THEN
+      IF( DBLE( M )*EPSLN.GE.ONE ) THEN
          INFO = -4
          CALL XERBLA( 'ZGESVJ', -INFO )
          RETURN
 *     SQRT(N)*max_i SVA(i) does not overflow. If INFinite entries
 *     in A are detected, the procedure returns with INFO=-6.
 *
-      SKL = ONE / DSQRT( DFLOAT( M )*DFLOAT( N ) )
+      SKL = ONE / DSQRT( DBLE( M )*DBLE( N ) )
       NOSCALE = .TRUE.
       GOSCALE = .TRUE.
 *
 *     avoid underflows/overflows in computing Jacobi rotations.
 *
       SN = DSQRT( SFMIN / EPSLN )
-      TEMP1 = DSQRT( BIG / DFLOAT( N ) )
+      TEMP1 = DSQRT( BIG / DBLE( N ) )
       IF( ( AAPP.LE.SN ) .OR. ( AAQQ.GE.TEMP1 ) .OR.    
      $    ( ( SN.LE.AAQQ ) .AND. ( AAPP.LE.TEMP1 ) ) ) THEN
          TEMP1 = DMIN1( BIG, TEMP1 / AAPP )
 *         AAQQ  = AAQQ*TEMP1
 *         AAPP  = AAPP*TEMP1
       ELSE IF( ( AAQQ.LE.SN ) .AND. ( AAPP.LE.TEMP1 ) ) THEN
-         TEMP1 = DMIN1( SN / AAQQ, BIG / (AAPP*DSQRT( DFLOAT(N)) ) )
+         TEMP1 = DMIN1( SN / AAQQ, BIG / (AAPP*DSQRT( DBLE(N)) ) )
 *         AAQQ  = AAQQ*TEMP1
 *         AAPP  = AAPP*TEMP1
       ELSE IF( ( AAQQ.GE.SN ) .AND. ( AAPP.GE.TEMP1 ) ) THEN
 *         AAQQ  = AAQQ*TEMP1
 *         AAPP  = AAPP*TEMP1
       ELSE IF( ( AAQQ.LE.SN ) .AND. ( AAPP.GE.TEMP1 ) ) THEN
-         TEMP1 = DMIN1( SN / AAQQ, BIG / ( DSQRT( DFLOAT( N ) )*AAPP ) )
+         TEMP1 = DMIN1( SN / AAQQ, BIG / ( DSQRT( DBLE( N ) )*AAPP ) )
 *         AAQQ  = AAQQ*TEMP1
 *         AAPP  = AAPP*TEMP1
       ELSE
 *     Scale, if necessary
 *
       IF( TEMP1.NE.ONE ) THEN
-         CALL ZLASCL( 'G', 0, 0, ONE, TEMP1, N, 1, SVA, N, IERR )
+         CALL DLASCL( 'G', 0, 0, ONE, TEMP1, N, 1, SVA, N, IERR )
       END IF
       SKL = TEMP1*SKL
       IF( SKL.NE.ONE ) THEN
                               END IF
                            END IF
 *
-                           OMPQ = AAPQ / ABS(AAPQ) 
 *                           AAPQ = AAPQ * DCONJG( CWORK(p) ) * CWORK(q) 
                            AAPQ1  = -ABS(AAPQ) 
                            MXAAPQ = DMAX1( MXAAPQ, -AAPQ1 )
 *
                               IF( ROTOK ) THEN
 *
-                                 AQOAP = AAQQ / AAPP
+                               OMPQ = AAPQ / ABS(AAPQ) 
+                                AQOAP = AAQQ / AAPP
                                  APOAQ = AAPP / AAQQ
                                  THETA = -HALF*ABS( AQOAP-APOAQ )/AAPQ1
 *
                               END IF
                            END IF
 *
-                           OMPQ = AAPQ / ABS(AAPQ) 
 *                           AAPQ = AAPQ * DCONJG(CWORK(p))*CWORK(q)   
                            AAPQ1  = -ABS(AAPQ)
                            MXAAPQ = DMAX1( MXAAPQ, -AAPQ1 )
 *
                               IF( ROTOK ) THEN
 *
+                                        OMPQ = AAPQ / ABS(AAPQ) 
                                  AQOAP = AAQQ / AAPP
                                  APOAQ = AAPP / AAQQ
                                  THETA = -HALF*ABS( AQOAP-APOAQ )/ AAPQ1
          IF( ( i.LT.SWBAND ) .AND. ( ( MXAAPQ.LE.ROOTTOL ) .OR.
      $       ( ISWROT.LE.N ) ) )SWBAND = i
 *
-         IF( ( i.GT.SWBAND+1 ) .AND. ( MXAAPQ.LT.DSQRT( DFLOAT( N ) )*
-     $       TOL ) .AND. ( DFLOAT( N )*MXAAPQ*MXSINJ.LT.TOL ) ) THEN
+         IF( ( i.GT.SWBAND+1 ) .AND. ( MXAAPQ.LT.DSQRT( DBLE( N ) )*
+     $       TOL ) .AND. ( DBLE( N )*MXAAPQ*MXSINJ.LT.TOL ) ) THEN
             GO TO 1994
          END IF
 *
 *     then some of the singular values may overflow or underflow and
 *     the spectrum is given in this factored representation.
 *
-      RWORK( 2 ) = DFLOAT( N4 )
+      RWORK( 2 ) = DBLE( N4 )
 *     N4 is the number of computed nonzero singular values of A.
 *
-      RWORK( 3 ) = DFLOAT( N2 )
+      RWORK( 3 ) = DBLE( N2 )
 *     N2 is the number of singular values of A greater than SFMIN.
 *     If N2<N, SVA(N2:N) contains ZEROS and/or denormalized numbers
 *     that may carry some information.
 *
-      RWORK( 4 ) = DFLOAT( i )
+      RWORK( 4 ) = DBLE( i )
 *     i is the index of the last sweep before declaring convergence.
 *
       RWORK( 5 ) = MXAAPQ
index bf59415b5afa129af6dffe3757b937c0c19a0424..f41b6f09ca558fb9065eed8a9ca0fc57fa9528ff 100644 (file)
@@ -98,7 +98,7 @@
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2013
+*> \date June 2016
 *
 *> \ingroup complex16GEauxiliary
 *
 *  =====================================================================
       SUBROUTINE ZGETC2( N, A, LDA, IPIV, JPIV, INFO )
 *
-*  -- LAPACK auxiliary routine (version 3.5.0) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2013
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            INFO, LDA, N
index 7d28b58129bab43f2febc2342ea37c7cab97e8fd..9b2e956c801dc1cca3345b9c9e5fcb63575414ac 100644 (file)
@@ -37,7 +37,7 @@
 *> 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)
+*>    A = [ -----|----- ]  with n1 = min(m,n)/2
 *>        [  A21 | A22  ]       n2 = n-n1
 *>            
 *>                                       [ A11 ]
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complex16GEcomputational
 *
 *  =====================================================================
       RECURSIVE SUBROUTINE ZGETRF2( M, N, A, LDA, IPIV, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            INFO, LDA, M, N
index 7298da397638b8884a2a2853c79c93a710b19ea3..7771c4c16a913a073bb6866a7314b04845e67378 100644 (file)
 *>
 *> \param[out] WORK
 *> \verbatim
-*>          WORK is REAL array, dimension (lwork)
+*>          WORK is DOUBLE PRECISION array, dimension (lwork)
 *>          lwork must be at least max(1,6*N) when JOB = 'S' or 'B', and
 *>          at least 1 when JOB = 'N' or 'P'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complex16GBcomputational
 *
       SUBROUTINE ZGGBAL( JOB, N, A, LDA, B, LDB, ILO, IHI, LSCALE,
      $                   RSCALE, WORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOB
index 1a7dbccc7b6397a3b45f54b0199aab061da1e35d..08557b134d9deaf78dc36f8aff0d3e0ebddd8dc6 100644 (file)
      $                   LDB, SDIM, ALPHA, BETA, VSL, LDVSL, VSR, LDVSR,
      $                   WORK, LWORK, RWORK, BWORK, INFO )
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     January 2015
      $                LDVSL, VSR, LDVSR, WORK, -1, IERR )
          LWKOPT = MAX( LWKOPT, N + INT ( WORK( 1 ) ) )
          CALL ZHGEQZ( 'S', JOBVSL, JOBVSR, N, 1, N, A, LDA, B, LDB,
-     $                ALPHA, BETA, VSL, LDVSL, VSR, LDVSR, WORK,
-     $        -1, RWORK, IERR )
+     $                ALPHA, BETA, VSL, LDVSL, VSR, LDVSR, WORK, -1,
+     $                RWORK, IERR )
          LWKOPT = MAX( LWKOPT, INT ( WORK( 1 ) ) )
          IF( WANTST ) THEN
             CALL ZTGSEN( 0, ILVSL, ILVSR, BWORK, N, A, LDA, B, LDB,
index 78337fd073aaef0a0ea228d82735900cbfac7874..2e88adedc3b9064edcfd51f80132914f3059ea3a 100644 (file)
       SUBROUTINE ZGGEV3( JOBVL, JOBVR, N, A, LDA, B, LDB, ALPHA, BETA,
      $                   VL, LDVL, VR, LDVR, WORK, LWORK, RWORK, INFO )
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     January 2015
index 9d6e36285cf496f70b2d01874717c46f6f2b07d7..94ae93b98b449bc29535d5f761157713eca73244 100644 (file)
       SUBROUTINE ZGGHD3( COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB, Q,
      $                   LDQ, Z, LDZ, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     January 2015
 *
       INFO = 0
       NB = ILAENV( 1, 'ZGGHD3', ' ', N, ILO, IHI, -1 )
-      LWKOPT = 6*N*NB
+      LWKOPT = MAX( 6*N*NB, 1 )
       WORK( 1 ) = DCMPLX( LWKOPT )
       INITQ = LSAME( COMPQ, 'I' )
       WANTQ = INITQ .OR. LSAME( COMPQ, 'V' )
index d478d2922e009c908a0aab9926db20d755aa1ffc..da479793dc1d1584561221b0ff674341fd8249b1 100644 (file)
      $                    LDB, ALPHA, BETA, U, LDU, V, LDV, Q, LDQ,
      $                    WORK, LWORK, RWORK, IWORK, INFO )
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     August 2015
       EXTERNAL           LSAME, DLAMCH, ZLANGE
 *     ..
 *     .. External Subroutines ..
-      EXTERNAL           DCOPY, XERBLA, ZGGSVP, ZTGSJA
+      EXTERNAL           DCOPY, XERBLA, ZGGSVP3, ZTGSJA
 *     ..
 *     .. Intrinsic Functions ..
       INTRINSIC          MAX, MIN
index b397651ccce6ef9c15d6b2de70e3dd734d1f3a57..88566f75047e2af6ae04a753e7dac4717ef1f27d 100644 (file)
      $                    TOLA, TOLB, K, L, U, LDU, V, LDV, Q, LDQ,
      $                    IWORK, RWORK, TAU, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     August 2015
 *     .. Local Scalars ..
       LOGICAL            FORWRD, WANTQ, WANTU, WANTV, LQUERY
       INTEGER            I, J, LWKOPT
-      COMPLEX*16         T
 *     ..
 *     .. External Functions ..
       LOGICAL            LSAME
index a9e663d4bfc0a275e8e5af02d5ecc66cd1bad46a..e547eebb207dbf81994fe0e632970f17ab5b9f69 100644 (file)
@@ -1,4 +1,4 @@
-*> \brief \b ZGSVJ0 pre-processor for the routine dgesvj.
+*> \brief \b ZGSVJ0 pre-processor for the routine zgesvj.
 *
 *  =========== DOCUMENTATION ===========
 *
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complex16OTHERcomputational
 *>
       SUBROUTINE ZGSVJ0( JOBV, M, N, A, LDA, D, SVA, MV, V, LDV, EPS,
      $                   SFMIN, TOL, NSWEEP, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
       IMPLICIT NONE
 *     .. Scalar Arguments ..
 *     ..
 *     ..
 *     .. Intrinsic Functions ..
-      INTRINSIC ABS, DMAX1, DCONJG, DFLOAT, MIN0, DSIGN, DSQRT
+      INTRINSIC ABS, DMAX1, DCONJG, DBLE, MIN0, DSIGN, DSQRT
 *     ..
 *     .. External Functions ..
       DOUBLE PRECISION   DZNRM2
          IF( ( i.LT.SWBAND ) .AND. ( ( MXAAPQ.LE.ROOTTOL ) .OR.
      $       ( ISWROT.LE.N ) ) )SWBAND = i
 *
-         IF( ( i.GT.SWBAND+1 ) .AND. ( MXAAPQ.LT.DSQRT( DFLOAT( N ) )*
-     $       TOL ) .AND. ( DFLOAT( N )*MXAAPQ*MXSINJ.LT.TOL ) ) THEN
+         IF( ( i.GT.SWBAND+1 ) .AND. ( MXAAPQ.LT.DSQRT( DBLE( N ) )*
+     $       TOL ) .AND. ( DBLE( N )*MXAAPQ*MXSINJ.LT.TOL ) ) THEN
             GO TO 1994
          END IF
 *
index 54410cc0fa2fcb00a81cc2154d4ac0f2ed001a40..65b383b78f2d59060a4585f9db4ae4b274732544 100644 (file)
@@ -1,4 +1,4 @@
-*> \brief \b ZGSVJ1 pre-processor for the routine sgesvj, applies Jacobi rotations targeting only particular pivots.
+*> \brief \b ZGSVJ1 pre-processor for the routine zgesvj, applies Jacobi rotations targeting only particular pivots.
 *
 *  =========== DOCUMENTATION ===========
 *
 *>
 *> \param[in,out] A
 *> \verbatim
-*>          A is DOUBLE PRECISION array, dimension (LDA,N)
+*>          A is COMPLEX*16 array, dimension (LDA,N)
 *>          On entry, M-by-N matrix A, such that A*diag(D) represents
 *>          the input matrix.
 *>          On exit,
 *>
 *> \param[in,out] D
 *> \verbatim
-*>          D is DOUBLE PRECISION array, dimension (N)
+*>          D is COMPLEX*16 array, dimension (N)
 *>          The array D accumulates the scaling factors from the fast scaled
 *>          Jacobi rotations.
 *>          On entry, A*diag(D) represents the input matrix.
 *>
 *> \param[in,out] V
 *> \verbatim
-*>          V is DOUBLE PRECISION array, dimension (LDV,N)
+*>          V is COMPLEX*16 array, dimension (LDV,N)
 *>          If JOBV .EQ. 'V' then N rows of V are post-multipled by a
 *>                           sequence of Jacobi rotations.
 *>          If JOBV .EQ. 'A' then MV rows of V are post-multipled by a
 *>
 *> \param[out] WORK
 *> \verbatim
-*>          WORK is DOUBLE PRECISION array, dimension (LWORK)
+*>          WORK is COMPLEX*16 array, dimension (LWORK)
 *> \endverbatim
 *>
 *> \param[in] LWORK
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complex16OTHERcomputational
 *
       SUBROUTINE ZGSVJ1( JOBV, M, N, N1, A, LDA, D, SVA, MV, V, LDV,
      $                   EPS, SFMIN, TOL, NSWEEP, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
       IMPLICIT NONE 
 *     .. Scalar Arguments ..
 *     ..
 *     ..
 *     .. Intrinsic Functions ..
-      INTRINSIC          ABS, DCONJG, DMAX1, DFLOAT, MIN0, DSIGN, DSQRT
+      INTRINSIC          ABS, DCONJG, DMAX1, DBLE, MIN0, DSIGN, DSQRT
 *     ..
 *     .. External Functions ..
       DOUBLE PRECISION   DZNRM2
       SMALL = SFMIN / EPS
       BIG = ONE / SFMIN
       ROOTBIG = ONE / ROOTSFMIN
-      LARGE = BIG / DSQRT( DFLOAT( M*N ) )
+      LARGE = BIG / DSQRT( DBLE( M*N ) )
       BIGTHETA = ONE / ROOTEPS
       ROOTTOL = DSQRT( TOL )
 *
          IF( ( i.LT.SWBAND ) .AND. ( ( MXAAPQ.LE.ROOTTOL ) .OR.
      $       ( ISWROT.LE.N ) ) )SWBAND = i
 *
-         IF( ( i.GT.SWBAND+1 ) .AND. ( MXAAPQ.LT.DSQRT( DFLOAT( N ) )*
-     $       TOL ) .AND. ( DFLOAT( N )*MXAAPQ*MXSINJ.LT.TOL ) ) THEN
+         IF( ( i.GT.SWBAND+1 ) .AND. ( MXAAPQ.LT.DSQRT( DBLE( N ) )*
+     $       TOL ) .AND. ( DBLE( N )*MXAAPQ*MXSINJ.LT.TOL ) ) THEN
             GO TO 1994
          END IF
 *
index f060029ece7bd18e1b03e4a17974f7dca492542f..09322be4080ac972f5a27e90f3741d86dd7669c1 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is DOUBLE PRECISION
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is DOUBLE PRECISION
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup complex16OTHEReigen
 *
      $                   VU, IL, IU, ABSTOL, M, W, Z, LDZ, WORK, RWORK,
      $                   IWORK, IFAIL, INFO )
 *
-*  -- LAPACK driver routine (version 3.4.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE, UPLO
index f60d6b017ab2d13c0e5dabf333260c9b2886f1ab..333e4377fbe9bfdd870d1531f8d1b16684266d1b 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complex16OTHEReigen
 *
      $                   Z, LDZ, WORK, LWORK, RWORK, LRWORK, IWORK,
      $                   LIWORK, INFO )
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, UPLO
       LLWK2 = LWORK - INDWK2 + 2
       LLRWK = LRWORK - INDWRK + 2
       CALL ZHBGST( JOBZ, UPLO, N, KA, KB, AB, LDAB, BB, LDBB, Z, LDZ,
-     $             WORK, RWORK( INDWRK ), IINFO )
+     $             WORK, RWORK, IINFO )
 *
 *     Reduce Hermitian band matrix to tridiagonal form.
 *
index e8596e4516c64dccfa4641cb1cba11287da3c9cb..4d42b503ec7bd058441af93f727bdc8d50cc06b5 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is DOUBLE PRECISION
+*>
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is DOUBLE PRECISION
 *>
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
 *>
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complex16OTHEReigen
 *
      $                   LDBB, Q, LDQ, VL, VU, IL, IU, ABSTOL, M, W, Z,
      $                   LDZ, WORK, RWORK, IWORK, IFAIL, INFO )
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE, UPLO
index 86e05b0657393c398c1b6e6912295026c7014adc..1ea82200f91f75330ae25959eb7f562e72e3b621 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is DOUBLE PRECISION
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is DOUBLE PRECISION
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup complex16HEeigen
 *
      $                   ABSTOL, M, W, Z, LDZ, ISUPPZ, WORK, LWORK,
      $                   RWORK, LRWORK, IWORK, LIWORK, INFO )
 *
-*  -- LAPACK driver routine (version 3.4.2) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE, UPLO
index 376d4c1b9bb896bd9d3c221f60250ad59822c0b5..fe4422f6c3946f892a720ed672bf049ddd82e4b9 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is DOUBLE PRECISION
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is DOUBLE PRECISION
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup complex16HEeigen
 *
      $                   ABSTOL, M, W, Z, LDZ, WORK, LWORK, RWORK,
      $                   IWORK, IFAIL, INFO )
 *
-*  -- LAPACK driver routine (version 3.4.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE, UPLO
index 932e070e274e0ff17d6acb72f5d5396ba9b4dd75..2aaa335900feeaa3e8eb8832ddcb7dc7a8b200bd 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is DOUBLE PRECISION
+*>
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is DOUBLE PRECISION
 *>
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
 *>
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complex16HEeigen
 *
      $                   VL, VU, IL, IU, ABSTOL, M, W, Z, LDZ, WORK,
      $                   LWORK, RWORK, IWORK, IFAIL, INFO )
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE, UPLO
index 64e59aab581aeef7129891248143d0c77411072b..afbad21c3f6f1e1e61334aff978066fa817ebdf2 100644 (file)
 *> \author Univ. of Colorado Denver
 *> \author NAG Ltd.
 *
-*> \date November 2013
+*> \date June 2016
 *
 *> \ingroup complex16HEcomputational
 *
 *>
 *> \verbatim
 *>
-*>  November 2013,  Igor Kozachenko,
+*>  June 2016,  Igor Kozachenko,
 *>                  Computer Science Division,
 *>                  University of California, Berkeley
 *>
 *  =====================================================================
       SUBROUTINE ZHETRF_ROOK( UPLO, N, A, LDA, IPIV, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.5.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2013
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          UPLO
 *        Determine the block size
 *
          NB = ILAENV( 1, 'ZHETRF_ROOK', UPLO, N, -1, -1, -1 )
-         LWKOPT = N*NB
+         LWKOPT = MAX( 1, N*NB )
          WORK( 1 ) = LWKOPT
       END IF
 *
index 15b460b448bef0c3bc7d805e198b6fa80d2185d3..7f72c18feb884c055f0ec5a21ff07d39c77ba9f2 100644 (file)
 *>
 *> \param[out] WORK
 *> \verbatim
-*>          WORK is REAL array, dimension (N)
+*>          WORK is COMPLEX*16 array, dimension (N)
 *> \endverbatim
 *>
 *> \param[out] INFO
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup complex16HEcomputational
 *
       SUBROUTINE ZHETRS2( UPLO, N, NRHS, A, LDA, IPIV, B, LDB, 
      $                    WORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.4.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          UPLO
index 98d1fb06d22e78873f07dc5cd27d186d3ebf043b..fb2df81ef219d8180ffeabf282b788c2dbb0b6cc 100644 (file)
 *> \param[in,out] Q
 *> \verbatim
 *>          Q is COMPLEX*16 array, dimension (LDQ, N)
-*>          On entry, if COMPZ = 'V', the unitary matrix Q1 used in the
+*>          On entry, if COMPQ = 'V', the unitary matrix Q1 used in the
 *>          reduction of (A,B) to generalized Hessenberg form.
-*>          On exit, if COMPZ = 'I', the unitary matrix of left Schur
-*>          vectors of (H,T), and if COMPZ = 'V', the unitary matrix of
+*>          On exit, if COMPQ = 'I', the unitary matrix of left Schur
+*>          vectors of (H,T), and if COMPQ = 'V', the unitary matrix of
 *>          left Schur vectors of (A,B).
-*>          Not referenced if COMPZ = 'N'.
+*>          Not referenced if COMPQ = 'N'.
 *> \endverbatim
 *>
 *> \param[in] LDQ
      $                   ALPHA, BETA, Q, LDQ, Z, LDZ, WORK, LWORK,
      $                   RWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     April 2012
index e804355671aa44c7d4939bb295410dec51ffe0c5..a7a6abc4d59f3e9bb5565d17be0eca1c6b55eb87 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is DOUBLE PRECISION
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is DOUBLE PRECISION
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup complex16OTHEReigen
 *
      $                   ABSTOL, M, W, Z, LDZ, WORK, RWORK, IWORK,
      $                   IFAIL, INFO )
 *
-*  -- LAPACK driver routine (version 3.4.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE, UPLO
index 5495c003417e71393997eb772a91533215d71c39..ef7e119776295e84de6a26c3b03caf326799fab2 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is DOUBLE PRECISION
+*>
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is DOUBLE PRECISION
 *>
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
 *>
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complex16OTHEReigen
 *
      $                   IL, IU, ABSTOL, M, W, Z, LDZ, WORK, RWORK,
      $                   IWORK, IFAIL, INFO )
 *
-*  -- LAPACK driver routine (version 3.6.0) --
+*  -- LAPACK driver routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE, UPLO
index aae5e6667eca9dd8a23c1a9443cbd2ef0eb49ab9..096ab3733014f27f02ad1b798649e7394c454bdf 100644 (file)
@@ -61,7 +61,7 @@
 *>
 *> \param[in] A
 *> \verbatim
-*>          A is DOUBLE PRECISION array, dimension (LDA,N)
+*>          A is COMPLEX*16 array, dimension (LDA,N)
 *>     On entry, the N-by-N matrix A.
 *> \endverbatim
 *>
@@ -73,7 +73,7 @@
 *>
 *> \param[in] AF
 *> \verbatim
-*>          AF is DOUBLE PRECISION array, dimension (LDAF,N)
+*>          AF is COMPLEX*16 array, dimension (LDAF,N)
 *>     The factors L and U from the factorization
 *>     A = P*L*U as computed by ZGETRF.
 *> \endverbatim
@@ -92,7 +92,7 @@
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup complex16GEcomputational
 *
       DOUBLE PRECISION FUNCTION ZLA_GERPVGRW( N, NCOLS, A, LDA, AF,
      $         LDAF )
 *
-*  -- LAPACK computational routine (version 3.4.2) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            N, NCOLS, LDA, LDAF
index e1fb5c4dc17634350be80bf5fb6925cd77b6afd8..8d9e2a23f86b14671f6d20a32aedd9d280d055ff 100644 (file)
 *>
 *> \param[in] WORK
 *> \verbatim
-*>          WORK is COMPLEX*16 array, dimension (2*N)
+*>          WORK is DOUBLE PRECISION array, dimension (2*N)
 *> \endverbatim
 *
 *  Authors:
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup complex16HEcomputational
 *
       DOUBLE PRECISION FUNCTION ZLA_HERPVGRW( UPLO, N, INFO, A, LDA, AF,
      $                                        LDAF, IPIV, WORK )
 *
-*  -- LAPACK computational routine (version 3.4.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER*1        UPLO
index 161eed970f6d10748d5b91e865c9fb7c0e545d3f..212c3582f44438b19031cf9aa96dceac5e8bda1c 100644 (file)
@@ -67,7 +67,7 @@
 *>
 *> \param[in] RES
 *> \verbatim
-*>          RES is DOUBLE PRECISION array, dimension (N,NRHS)
+*>          RES is COMPLEX*16 array, dimension (N,NRHS)
 *>     The residual matrix, i.e., the matrix R in the relative backward
 *>     error formula above.
 *> \endverbatim
@@ -82,7 +82,7 @@
 *>     
 *> \param[out] BERR
 *> \verbatim
-*>          BERR is COMPLEX*16 array, dimension (NRHS)
+*>          BERR is DOUBLE PRECISION array, dimension (NRHS)
 *>     The componentwise relative backward error from the formula above.
 *> \endverbatim
 *
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup complex16OTHERcomputational
 *
 *  =====================================================================
       SUBROUTINE ZLA_LIN_BERR ( N, NZ, NRHS, RES, AYB, BERR )
 *
-*  -- LAPACK computational routine (version 3.4.2) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            N, NZ, NRHS
index 682a670a9e9333d0f9385efb2cde12b9608f4321..1cf63cdba8d4ddcbf2a19ea507b6781ee4c168d7 100644 (file)
@@ -88,7 +88,7 @@
 *>
 *> \param[in] WORK
 *> \verbatim
-*>          WORK is COMPLEX*16 array, dimension (2*N)
+*>          WORK is DOUBLE PRECISION array, dimension (2*N)
 *> \endverbatim
 *
 *  Authors:
@@ -99,7 +99,7 @@
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup complex16POcomputational
 *
       DOUBLE PRECISION FUNCTION ZLA_PORPVGRW( UPLO, NCOLS, A, LDA, AF, 
      $                                        LDAF, WORK )
 *
-*  -- LAPACK computational routine (version 3.4.2) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER*1        UPLO
index ae6e9a36a42cffc8ccab5a04c5503207f731c9ac..26a0534f63cd75c0dcab051bc22c74ea49065f36 100644 (file)
@@ -57,7 +57,7 @@
 *>
 *>       The first stage consists of deflating the size of the problem
 *>       when there are multiple eigenvalues or if there is a zero in
-*>       the Z vector.  For each such occurence the dimension of the
+*>       the Z vector.  For each such occurrence the dimension of the
 *>       secular equation problem is reduced by one.  This stage is
 *>       performed by the routine DLAED2.
 *>
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup complex16OTHERcomputational
 *
      $                   GIVPTR, GIVCOL, GIVNUM, WORK, RWORK, IWORK,
      $                   INFO )
 *
-*  -- LAPACK computational routine (version 3.4.2) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            CURLVL, CURPBM, CUTPNT, INFO, LDQ, N, QSIZ,
index 39880147165e53d7c281cfd585f8c7682f92b9b7..b09c3ef7cb7aa10ba92fc23e1b7bf55e5e0bba50 100644 (file)
 *>          Z is COMPLEX*16 array, dimension (LDZ,N)
 *>          IF WANTZ is .TRUE., then on output, the unitary
 *>          similarity transformation mentioned above has been
-*>          accumulated into Z(ILOZ:IHIZ,ILO:IHI) from the right.
+*>          accumulated into Z(ILOZ:IHIZ,ILOZ:IHIZ) from the right.
 *>          If WANTZ is .FALSE., then Z is unreferenced.
 *> \endverbatim
 *>
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup complex16OTHERauxiliary
 *
      $                   IHIZ, Z, LDZ, NS, ND, SH, V, LDV, NH, T, LDT,
      $                   NV, WV, LDWV, WORK, LWORK )
 *
-*  -- LAPACK auxiliary routine (version 3.4.2) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            IHIZ, ILOZ, KBOT, KTOP, LDH, LDT, LDV, LDWV,
index e33a30d6524be08ba816db2f8e938805a1486772..66f550fcec455c3e50c3afcadff4b63e7160420a 100644 (file)
 *>
 *> \param[in,out] Z
 *> \verbatim
-*>          Z is COMPLEX*16 array of size (LDZ,IHI)
+*>          Z is COMPLEX*16 array of size (LDZ,IHIZ)
 *>             If WANTZ = .TRUE., then the QR Sweep unitary
 *>             similarity transformation is accumulated into
-*>             Z(ILOZ:IHIZ,ILO:IHI) from the right.
+*>             Z(ILOZ:IHIZ,ILOZ:IHIZ) from the right.
 *>             If WANTZ = .FALSE., then Z is unreferenced.
 *> \endverbatim
 *>
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup complex16OTHERauxiliary
 *
      $                   H, LDH, ILOZ, IHIZ, Z, LDZ, V, LDV, U, LDU, NV,
      $                   WV, LDWV, NH, WH, LDWH )
 *
-*  -- LAPACK auxiliary routine (version 3.4.2) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            IHIZ, ILOZ, KACC22, KBOT, KTOP, LDH, LDU, LDV,
index e72c1061b60f6158453c384bf043fe2854df1b13..90af72ef74f205b599e903663e128e5d0cb6e8f6 100644 (file)
@@ -72,7 +72,7 @@
 *>
 *> \param[in] B
 *> \verbatim
-*>          B is DOUBLE PRECISION array, dimension (LDB, N)
+*>          B is COMPLEX*16 array, dimension (LDB, N)
 *>          B contains the M by N matrix B.
 *> \endverbatim
 *>
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup complex16OTHERauxiliary
 *
 *  =====================================================================
       SUBROUTINE ZLARCM( M, N, A, LDA, B, LDB, C, LDC, RWORK )
 *
-*  -- LAPACK auxiliary routine (version 3.4.2) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            LDA, LDB, LDC, M, N
index b9ac939763c88c37c71acc4c6da3d926ff418f2f..7e1013f2fe709c464e9870555956738fa2758d10 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complex16OTHERauxiliary
 *
 *  =====================================================================
       SUBROUTINE ZLARFT( DIRECT, STOREV, N, K, V, LDV, TAU, T, LDT )
 *
-*  -- LAPACK auxiliary routine (version 3.6.0) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          DIRECT, STOREV
 *
                      CALL ZGEMM( 'N', 'C', K-I, 1, N-K+I-J, -TAU( I ),
      $                           V( I+1, J ), LDV, V( I, J ), LDV,
-     $                           ONE, T( I+1, I ), LDT )                     
+     $                           ONE, T( I+1, I ), LDT )
                   END IF
 *
 *                 T(i+1:k,i) := T(i+1:k,i+1:k) * T(i+1:k,i)
index 3992f14d54a29cb2ebc782a9bf28b17f149af4c1..c29dda1bcc012a13a34938da0cb7191a5fa44345 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is DOUBLE PRECISION
+*>          Lower bound of the interval that contains the desired
+*>          eigenvalues. VL < VU. Needed to compute gaps on the left or right
+*>          end of the extremal eigenvalues in the desired RANGE.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is DOUBLE PRECISION
-*>          Lower and upper bounds of the interval that contains the desired
+*>          Upper bound of the interval that contains the desired
 *>          eigenvalues. VL < VU. Needed to compute gaps on the left or right
 *>          end of the extremal eigenvalues in the desired RANGE.
 *> \endverbatim
@@ -81,7 +84,7 @@
 *>          L is DOUBLE PRECISION array, dimension (N)
 *>          On entry, the (N-1) subdiagonal elements of the unit
 *>          bidiagonal matrix L are in elements 1 to N-1 of L
-*>          (if the matrix is not splitted.) At the end of each block
+*>          (if the matrix is not split.) At the end of each block
 *>          is stored the corresponding shift as given by DLARRE.
 *>          On exit, L is overwritten.
 *> \endverbatim
 *>          INFO is INTEGER
 *>          = 0:  successful exit
 *>
-*>          > 0:  A problem occured in ZLARRV.
+*>          > 0:  A problem occurred in ZLARRV.
 *>          < 0:  One of the called subroutines signaled an internal problem.
 *>                Needs inspection of the corresponding parameter IINFO
 *>                for further information.
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complex16OTHERauxiliary
 *
      $                   IBLOCK, INDEXW, GERS, Z, LDZ, ISUPPZ,
      $                   WORK, IWORK, INFO )
 *
-*  -- LAPACK auxiliary routine (version 3.6.0) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            DOL, DOU, INFO, LDZ, M, N
index b54f02c988a1befbc138ddafbfd8a87feae6faf7..2b47d6ba2973f89a0c5525030dee4d8734079a50 100644 (file)
@@ -73,7 +73,7 @@
 *> \param[in] LDX
 *> \verbatim
 *>          LDX is INTEGER
-*>     The leading dimension of the vector X. LDX >= 0.
+*>     The leading dimension of the vector X. LDX >= M.
 *> \endverbatim
 *
 *  Authors:
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complex16OTHERcomputational
 *
 *  =====================================================================
       SUBROUTINE ZLARSCL2 ( M, N, D, X, LDX )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            M, N, LDX
index 51a4f0f61494c3507dde135c77a2efa21c1d8053..1618fdbaa5066b73033219694139048ba1c464a9 100644 (file)
 *> \param[in] LDA
 *> \verbatim
 *>          LDA is INTEGER
-*>          The leading dimension of the array A.  LDA >= max(1,M).
+*>          The leading dimension of the array A.
+*>          If TYPE = 'G', 'L', 'U', 'H', LDA >= max(1,M);
+*>             TYPE = 'B', LDA >= KL+1;
+*>             TYPE = 'Q', LDA >= KU+1;
+*>             TYPE = 'Z', LDA >= 2*KL+KU+1.
 *> \endverbatim
 *>
 *> \param[out] INFO
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup complex16OTHERauxiliary
 *
 *  =====================================================================
       SUBROUTINE ZLASCL( TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO )
 *
-*  -- LAPACK auxiliary routine (version 3.4.2) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          TYPE
index eebdebb4da56360540527d5c18bed0b3ba359f73..78b94b3d510ca75116cd1525a122cb4d2e1ddd8e 100644 (file)
@@ -73,7 +73,7 @@
 *> \param[in] LDX
 *> \verbatim
 *>          LDX is INTEGER
-*>     The leading dimension of the vector X. LDX >= 0.
+*>     The leading dimension of the vector X. LDX >= M.
 *> \endverbatim
 *
 *  Authors:
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complex16OTHERcomputational
 *
 *  =====================================================================
       SUBROUTINE ZLASCL2 ( M, N, D, X, LDX )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            M, N, LDX
index e90bfede016a687c518aadf8b7797a0a5618ae21..8551ca4f180f91d562a9abdf5f0a2243882e7dbd 100644 (file)
@@ -58,7 +58,7 @@
 *>              Zx = +-e - f with the sign giving the greater value of
 *>              2-norm(x).  About 5 times as expensive as Default.
 *>          IJOB .ne. 2: Local look ahead strategy where
-*>              all entries of the r.h.s. b is choosen as either +1 or
+*>              all entries of the r.h.s. b is chosen as either +1 or
 *>              -1.  Default.
 *> \endverbatim
 *>
@@ -70,7 +70,7 @@
 *>
 *> \param[in] Z
 *> \verbatim
-*>          Z is DOUBLE PRECISION array, dimension (LDZ, N)
+*>          Z is COMPLEX*16 array, dimension (LDZ, N)
 *>          On entry, the LU part of the factorization of the n-by-n
 *>          matrix Z computed by ZGETC2:  Z = P * L * U * Q
 *> \endverbatim
@@ -83,7 +83,7 @@
 *>
 *> \param[in,out] RHS
 *> \verbatim
-*>          RHS is DOUBLE PRECISION array, dimension (N).
+*>          RHS is COMPLEX*16 array, dimension (N).
 *>          On entry, RHS contains contributions from other subsystems.
 *>          On exit, RHS contains the solution of the subsystem with
 *>          entries according to the value of IJOB (see above).
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup complex16OTHERauxiliary
 *
       SUBROUTINE ZLATDF( IJOB, N, Z, LDZ, RHS, RDSUM, RDSCAL, IPIV,
      $                   JPIV )
 *
-*  -- LAPACK auxiliary routine (version 3.4.2) --
+*  -- LAPACK auxiliary routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            IJOB, LDZ, N
index a75f563ae99e88f72801bb1173b79b9c7e09279e..a47cd17a74a6263a4e580fbfa398962138557e89 100644 (file)
@@ -75,7 +75,7 @@
 *>
 *> \param[in] AB
 *> \verbatim
-*>          AB is DOUBLE PRECISION array, dimension (LDAB,N)
+*>          AB is COMPLEX*16 array, dimension (LDAB,N)
 *>          The upper or lower triangle of the Hermitian band matrix A,
 *>          stored in the first KD+1 rows of the array.  The j-th column
 *>          of A is stored in the j-th column of the array AB as follows:
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup complex16OTHERcomputational
 *
       SUBROUTINE ZPBRFS( UPLO, N, KD, NRHS, AB, LDAB, AFB, LDAFB, B,
      $                   LDB, X, LDX, FERR, BERR, WORK, RWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.4.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          UPLO
index 179bcac00a3f3b134efc813070af3b8e632a4806..de07310a6c7c5b335e9dfaea98d29250dd14e198 100644 (file)
@@ -69,7 +69,7 @@
 *>
 *> \param[in,out] A
 *> \verbatim
-*>          A is COMPLEX array, dimension ( N*(N+1)/2 );
+*>          A is COMPLEX*16 array, dimension ( N*(N+1)/2 );
 *>          On entry, the Hermitian matrix A in RFP format. RFP format is
 *>          described by TRANSR, UPLO, and N as follows: If TRANSR = 'N'
 *>          then RFP A is (0:N,0:k-1) when N is even; k=N/2. RFP A is
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup complex16OTHERcomputational
 *
 *  =====================================================================
       SUBROUTINE ZPFTRF( TRANSR, UPLO, N, A, INFO )
 *
-*  -- LAPACK computational routine (version 3.4.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          TRANSR, UPLO
index 8d6aa3912095496fad7322ae40b19ff61643bc98..4940b3e00d705ed7ed7daddf56b4ba6cc3b9919f 100644 (file)
@@ -87,7 +87,7 @@
 *>
 *> \param[in,out] B
 *> \verbatim
-*>          B is DOUBLE PRECISION array, dimension (LDB,NRHS)
+*>          B is COMPLEX*16 array, dimension (LDB,NRHS)
 *>          On entry, the right hand side vectors B for the system of
 *>          linear equations.
 *>          On exit, the solution vectors, X.
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup complex16PTcomputational
 *
 *  =====================================================================
       SUBROUTINE ZPTTRS( UPLO, N, NRHS, D, E, B, LDB, INFO )
 *
-*  -- LAPACK computational routine (version 3.4.2) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          UPLO
index 3be100a2317389e75e512be7d788dd943881d67e..434dbcedae33fbf69f81773cf589a81ce2fc0e88 100644 (file)
@@ -86,7 +86,7 @@
 *>
 *> \param[in,out] B
 *> \verbatim
-*>          B is DOUBLE PRECISION array, dimension (LDB,NRHS)
+*>          B is COMPLEX*16 array, dimension (LDB,NRHS)
 *>          On entry, the right hand side vectors B for the system of
 *>          linear equations.
 *>          On exit, the solution vectors, X.
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date September 2012
+*> \date June 2016
 *
 *> \ingroup complex16PTcomputational
 *
 *  =====================================================================
       SUBROUTINE ZPTTS2( IUPLO, N, NRHS, D, E, B, LDB )
 *
-*  -- LAPACK computational routine (version 3.4.2) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     September 2012
+*     June 2016
 *
 *     .. Scalar Arguments ..
       INTEGER            IUPLO, LDB, N, NRHS
index 16a4e789c63dcb58f68b77c0cc934a94bc927d18..b68a4c447931ced02ad6234fd79bcfb7fb9135f5 100644 (file)
@@ -48,7 +48,7 @@
 *> either an interval (VL,VU] or a range of indices IL:IU for the desired
 *> eigenvalues.
 *>
-*> ZSTEGR is a compatability wrapper around the improved ZSTEMR routine.
+*> ZSTEGR is a compatibility wrapper around the improved ZSTEMR routine.
 *> See DSTEMR for further details.
 *>
 *> One important change is that the ABSTOL parameter no longer provides any
 *> \param[in] VL
 *> \verbatim
 *>          VL is DOUBLE PRECISION
+*>
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is DOUBLE PRECISION
 *>
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
 *>
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup complex16OTHERcomputational
 *
      $           ABSTOL, M, W, Z, LDZ, ISUPPZ, WORK, LWORK, IWORK,
      $           LIWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.4.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE
index cc815666adb622b95f6ba6a1da93ae72567bb1f1..0de085271832b5f1f53dd31b0956149cbf66d0b6 100644 (file)
 *> \param[in] VL
 *> \verbatim
 *>          VL is DOUBLE PRECISION
+*>
+*>          If RANGE='V', the lower bound of the interval to
+*>          be searched for eigenvalues. VL < VU.
+*>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *>
 *> \param[in] VU
 *> \verbatim
 *>          VU is DOUBLE PRECISION
 *>
-*>          If RANGE='V', the lower and upper bounds of the interval to
+*>          If RANGE='V', the upper bound of the interval to
 *>          be searched for eigenvalues. VL < VU.
 *>          Not referenced if RANGE = 'A' or 'I'.
 *> \endverbatim
 *> \param[in] IL
 *> \verbatim
 *>          IL is INTEGER
+*>
+*>          If RANGE='I', the index of the
+*>          smallest eigenvalue to be returned.
+*>          1 <= IL <= IU <= N, if N > 0.
+*>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *>
 *> \param[in] IU
 *> \verbatim
 *>          IU is INTEGER
 *>
-*>          If RANGE='I', the indices (in ascending order) of the
-*>          smallest and largest eigenvalues to be returned.
+*>          If RANGE='I', the index of the
+*>          largest eigenvalue to be returned.
 *>          1 <= IL <= IU <= N, if N > 0.
 *>          Not referenced if RANGE = 'A' or 'V'.
 *> \endverbatim
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complex16OTHERcomputational
 *
      $                   M, W, Z, LDZ, NZC, ISUPPZ, TRYRAC, WORK, LWORK,
      $                   IWORK, LIWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          JOBZ, RANGE
index f5d3e51bf14bb5d1dee240ecd1f7df550d4d5782..9ba446abc0a661683c5b1697f229a3e46c9b050d 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complex16SYcomputational
 *
 *>
 *> \verbatim
 *>
-*>   November 2015, Igor Kozachenko,
+*>   June 2016, Igor Kozachenko,
 *>                  Computer Science Division,
 *>                  University of California, Berkeley
 *>
 *  =====================================================================
       SUBROUTINE ZSYTRF_ROOK( UPLO, N, A, LDA, IPIV, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          UPLO
 *        Determine the block size
 *
          NB = ILAENV( 1, 'ZSYTRF_ROOK', UPLO, N, -1, -1, -1 )
-         LWKOPT = N*NB
+         LWKOPT = MAX( 1, N*NB )
          WORK( 1 ) = LWKOPT
       END IF
 *
index 6321197f9fd256632e0947adb12628b65088c752..890c07a978c3a224b88520ed707ca5963200dbf0 100644 (file)
 *>
 *> \param[out] WORK
 *> \verbatim
-*>          WORK is REAL array, dimension (N)
+*>          WORK is COMPLEX*16 array, dimension (N)
 *> \endverbatim
 *>
 *> \param[out] INFO
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2015
+*> \date June 2016
 *
 *> \ingroup complex16SYcomputational
 *
       SUBROUTINE ZSYTRS2( UPLO, N, NRHS, A, LDA, IPIV, B, LDB, 
      $                    WORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2015
+*     June 2016
 *
 *     .. Scalar Arguments ..
       CHARACTER          UPLO
index 4c991ec40a8d617cf99f838de5522524b93fd885..87e0f99ac7f6e2fed5d276e58d25790bae83516f 100644 (file)
 *> \author Univ. of Colorado Denver 
 *> \author NAG Ltd. 
 *
-*> \date November 2011
+*> \date June 2016
 *
 *> \ingroup complex16OTHERcomputational
 *
      $                   ALPHA, BETA, Q, LDQ, Z, LDZ, M, PL, PR, DIF,
      $                   WORK, LWORK, IWORK, LIWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.4.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
-*     November 2011
+*     June 2016
 *
 *     .. Scalar Arguments ..
       LOGICAL            WANTQ, WANTZ
 *     subspaces.
 *
       M = 0
+      IF( .NOT.LQUERY .OR. IJOB.NE.0 ) THEN
       DO 10 K = 1, N
          ALPHA( K ) = A( K, K )
          BETA( K ) = B( K, K )
      $         M = M + 1
          END IF
    10 CONTINUE
+      END IF
 *
       IF( IJOB.EQ.1 .OR. IJOB.EQ.2 .OR. IJOB.EQ.4 ) THEN
          LWMIN = MAX( 1, 2*M*( N-M ) )
diff --git a/lapack-netlib/SRC/ztrevc3.f b/lapack-netlib/SRC/ztrevc3.f
new file mode 100644 (file)
index 0000000..2265485
--- /dev/null
@@ -0,0 +1,630 @@
+*> \brief \b ZTREVC3
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at 
+*            http://www.netlib.org/lapack/explore-html/ 
+*
+*> \htmlonly
+*> Download ZTREVC3 + dependencies 
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ztrevc3.f"> 
+*> [TGZ]</a> 
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ztrevc3.f"> 
+*> [ZIP]</a> 
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ztrevc3.f"> 
+*> [TXT]</a>
+*> \endhtmlonly 
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZTREVC3( SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL,
+*                           VR, LDVR, MM, M, WORK, LWORK, RWORK, INFO )
+*
+*       .. Scalar Arguments ..
+*       CHARACTER          HOWMNY, SIDE
+*       INTEGER            INFO, LDT, LDVL, LDVR, LWORK, M, MM, N
+*       ..
+*       .. Array Arguments ..
+*       LOGICAL            SELECT( * )
+*       DOUBLE PRECISION   RWORK( * )
+*       COMPLEX*16         T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ),
+*      $                   WORK( * )
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> ZTREVC3 computes some or all of the right and/or left eigenvectors of
+*> a complex upper triangular matrix T.
+*> Matrices of this type are produced by the Schur factorization of
+*> a complex general matrix:  A = Q*T*Q**H, as computed by ZHSEQR.
+*>
+*> The right eigenvector x and the left eigenvector y of T corresponding
+*> to an eigenvalue w are defined by:
+*>
+*>              T*x = w*x,     (y**H)*T = w*(y**H)
+*>
+*> where y**H denotes the conjugate transpose of the vector y.
+*> The eigenvalues are not input to this routine, but are read directly
+*> from the diagonal of T.
+*>
+*> This routine returns the matrices X and/or Y of right and left
+*> eigenvectors of T, or the products Q*X and/or Q*Y, where Q is an
+*> input matrix. If Q is the unitary factor that reduces a matrix A to
+*> Schur form T, then Q*X and Q*Y are the matrices of right and left
+*> eigenvectors of A.
+*>
+*> This uses a Level 3 BLAS version of the back transformation.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] SIDE
+*> \verbatim
+*>          SIDE is CHARACTER*1
+*>          = 'R':  compute right eigenvectors only;
+*>          = 'L':  compute left eigenvectors only;
+*>          = 'B':  compute both right and left eigenvectors.
+*> \endverbatim
+*>
+*> \param[in] HOWMNY
+*> \verbatim
+*>          HOWMNY is CHARACTER*1
+*>          = 'A':  compute all right and/or left eigenvectors;
+*>          = 'B':  compute all right and/or left eigenvectors,
+*>                  backtransformed using the matrices supplied in
+*>                  VR and/or VL;
+*>          = 'S':  compute selected right and/or left eigenvectors,
+*>                  as indicated by the logical array SELECT.
+*> \endverbatim
+*>
+*> \param[in] SELECT
+*> \verbatim
+*>          SELECT is LOGICAL array, dimension (N)
+*>          If HOWMNY = 'S', SELECT specifies the eigenvectors to be
+*>          computed.
+*>          The eigenvector corresponding to the j-th eigenvalue is
+*>          computed if SELECT(j) = .TRUE..
+*>          Not referenced if HOWMNY = 'A' or 'B'.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>          The order of the matrix T. N >= 0.
+*> \endverbatim
+*>
+*> \param[in,out] T
+*> \verbatim
+*>          T is COMPLEX*16 array, dimension (LDT,N)
+*>          The upper triangular matrix T.  T is modified, but restored
+*>          on exit.
+*> \endverbatim
+*>
+*> \param[in] LDT
+*> \verbatim
+*>          LDT is INTEGER
+*>          The leading dimension of the array T. LDT >= max(1,N).
+*> \endverbatim
+*>
+*> \param[in,out] VL
+*> \verbatim
+*>          VL is COMPLEX*16 array, dimension (LDVL,MM)
+*>          On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL must
+*>          contain an N-by-N matrix Q (usually the unitary matrix Q of
+*>          Schur vectors returned by ZHSEQR).
+*>          On exit, if SIDE = 'L' or 'B', VL contains:
+*>          if HOWMNY = 'A', the matrix Y of left eigenvectors of T;
+*>          if HOWMNY = 'B', the matrix Q*Y;
+*>          if HOWMNY = 'S', the left eigenvectors of T specified by
+*>                           SELECT, stored consecutively in the columns
+*>                           of VL, in the same order as their
+*>                           eigenvalues.
+*>          Not referenced if SIDE = 'R'.
+*> \endverbatim
+*>
+*> \param[in] LDVL
+*> \verbatim
+*>          LDVL is INTEGER
+*>          The leading dimension of the array VL.
+*>          LDVL >= 1, and if SIDE = 'L' or 'B', LDVL >= N.
+*> \endverbatim
+*>
+*> \param[in,out] VR
+*> \verbatim
+*>          VR is COMPLEX*16 array, dimension (LDVR,MM)
+*>          On entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', VR must
+*>          contain an N-by-N matrix Q (usually the unitary matrix Q of
+*>          Schur vectors returned by ZHSEQR).
+*>          On exit, if SIDE = 'R' or 'B', VR contains:
+*>          if HOWMNY = 'A', the matrix X of right eigenvectors of T;
+*>          if HOWMNY = 'B', the matrix Q*X;
+*>          if HOWMNY = 'S', the right eigenvectors of T specified by
+*>                           SELECT, stored consecutively in the columns
+*>                           of VR, in the same order as their
+*>                           eigenvalues.
+*>          Not referenced if SIDE = 'L'.
+*> \endverbatim
+*>
+*> \param[in] LDVR
+*> \verbatim
+*>          LDVR is INTEGER
+*>          The leading dimension of the array VR.
+*>          LDVR >= 1, and if SIDE = 'R' or 'B', LDVR >= N.
+*> \endverbatim
+*>
+*> \param[in] MM
+*> \verbatim
+*>          MM is INTEGER
+*>          The number of columns in the arrays VL and/or VR. MM >= M.
+*> \endverbatim
+*>
+*> \param[out] M
+*> \verbatim
+*>          M is INTEGER
+*>          The number of columns in the arrays VL and/or VR actually
+*>          used to store the eigenvectors.
+*>          If HOWMNY = 'A' or 'B', M is set to N.
+*>          Each selected eigenvector occupies one column.
+*> \endverbatim
+*>
+*> \param[out] WORK
+*> \verbatim
+*>          WORK is COMPLEX*16 array, dimension (MAX(1,LWORK))
+*> \endverbatim
+*>
+*> \param[in] LWORK
+*> \verbatim
+*>          LWORK is INTEGER
+*>          The dimension of array WORK. LWORK >= max(1,2*N).
+*>          For optimum performance, LWORK >= N + 2*N*NB, where NB is
+*>          the optimal blocksize.
+*>
+*>          If LWORK = -1, then a workspace query is assumed; the routine
+*>          only calculates the optimal size of the WORK array, returns
+*>          this value as the first entry of the WORK array, and no error
+*>          message related to LWORK is issued by XERBLA.
+*> \endverbatim
+*>
+*> \param[out] RWORK
+*> \verbatim
+*>          RWORK is DOUBLE PRECISION array, dimension (LRWORK)
+*> \endverbatim
+*>
+*> \param[in] LRWORK
+*> \verbatim
+*>          LRWORK is INTEGER
+*>          The dimension of array RWORK. LRWORK >= max(1,N).
+*>
+*>          If LRWORK = -1, then a workspace query is assumed; the routine
+*>          only calculates the optimal size of the RWORK array, returns
+*>          this value as the first entry of the RWORK array, and no error
+*>          message related to LRWORK is issued by XERBLA.
+*> \endverbatim
+*>
+*> \param[out] INFO
+*> \verbatim
+*>          INFO is INTEGER
+*>          = 0:  successful exit
+*>          < 0:  if INFO = -i, the i-th argument had an illegal value
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date November 2011
+*
+*  @precisions fortran z -> c
+*
+*> \ingroup complex16OTHERcomputational
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  The algorithm used in this program is basically backward (forward)
+*>  substitution, with scaling to make the the code robust against
+*>  possible overflow.
+*>
+*>  Each eigenvector is normalized so that the element of largest
+*>  magnitude has magnitude 1; here the magnitude of a complex number
+*>  (x,y) is taken to be |x| + |y|.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZTREVC3( SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR,
+     $                    LDVR, MM, M, WORK, LWORK, RWORK, LRWORK, INFO)
+      IMPLICIT NONE
+*
+*  -- LAPACK computational routine (version 3.4.0) --
+*  -- LAPACK is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     November 2011
+*
+*     .. Scalar Arguments ..
+      CHARACTER          HOWMNY, SIDE
+      INTEGER            INFO, LDT, LDVL, LDVR, LWORK, LRWORK, M, MM, N
+*     ..
+*     .. Array Arguments ..
+      LOGICAL            SELECT( * )
+      DOUBLE PRECISION   RWORK( * )
+      COMPLEX*16         T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ),
+     $                   WORK( * )
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION   ZERO, ONE
+      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
+      COMPLEX*16         CZERO, CONE
+      PARAMETER          ( CZERO = ( 0.0D+0, 0.0D+0 ),
+     $                     CONE  = ( 1.0D+0, 0.0D+0 ) )
+      INTEGER            NBMIN, NBMAX
+      PARAMETER          ( NBMIN = 8, NBMAX = 128 )
+*     ..
+*     .. Local Scalars ..
+      LOGICAL            ALLV, BOTHV, LEFTV, LQUERY, OVER, RIGHTV, SOMEV
+      INTEGER            I, II, IS, J, K, KI, IV, MAXWRK, NB
+      DOUBLE PRECISION   OVFL, REMAX, SCALE, SMIN, SMLNUM, ULP, UNFL
+      COMPLEX*16         CDUM
+*     ..
+*     .. External Functions ..
+      LOGICAL            LSAME
+      INTEGER            ILAENV, IZAMAX
+      DOUBLE PRECISION   DLAMCH, DZASUM
+      EXTERNAL           LSAME, ILAENV, IZAMAX, DLAMCH, DZASUM
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL           XERBLA, ZCOPY, ZDSCAL, ZGEMV, ZLATRS
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC          ABS, DBLE, DCMPLX, CONJG, AIMAG, MAX
+*     ..
+*     .. Statement Functions ..
+      DOUBLE PRECISION   CABS1
+*     ..
+*     .. Statement Function definitions ..
+      CABS1( CDUM ) = ABS( DBLE( CDUM ) ) + ABS( AIMAG( CDUM ) )
+*     ..
+*     .. Executable Statements ..
+*
+*     Decode and test the input parameters
+*
+      BOTHV  = LSAME( SIDE, 'B' )
+      RIGHTV = LSAME( SIDE, 'R' ) .OR. BOTHV
+      LEFTV  = LSAME( SIDE, 'L' ) .OR. BOTHV
+*
+      ALLV  = LSAME( HOWMNY, 'A' )
+      OVER  = LSAME( HOWMNY, 'B' )
+      SOMEV = LSAME( HOWMNY, 'S' )
+*
+*     Set M to the number of columns required to store the selected
+*     eigenvectors.
+*
+      IF( SOMEV ) THEN
+         M = 0
+         DO 10 J = 1, N
+            IF( SELECT( J ) )
+     $         M = M + 1
+   10    CONTINUE
+      ELSE
+         M = N
+      END IF
+*
+      INFO = 0
+      NB = ILAENV( 1, 'ZTREVC', SIDE // HOWMNY, N, -1, -1, -1 )
+      MAXWRK = N + 2*N*NB
+      WORK(1) = MAXWRK
+      RWORK(1) = N
+      LQUERY = ( LWORK.EQ.-1 .OR. LRWORK.EQ.-1 )
+      IF( .NOT.RIGHTV .AND. .NOT.LEFTV ) THEN
+         INFO = -1
+      ELSE IF( .NOT.ALLV .AND. .NOT.OVER .AND. .NOT.SOMEV ) THEN
+         INFO = -2
+      ELSE IF( N.LT.0 ) THEN
+         INFO = -4
+      ELSE IF( LDT.LT.MAX( 1, N ) ) THEN
+         INFO = -6
+      ELSE IF( LDVL.LT.1 .OR. ( LEFTV .AND. LDVL.LT.N ) ) THEN
+         INFO = -8
+      ELSE IF( LDVR.LT.1 .OR. ( RIGHTV .AND. LDVR.LT.N ) ) THEN
+         INFO = -10
+      ELSE IF( MM.LT.M ) THEN
+         INFO = -11
+      ELSE IF( LWORK.LT.MAX( 1, 2*N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -14
+      ELSE IF ( LRWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
+         INFO = -16
+      END IF
+      IF( INFO.NE.0 ) THEN
+         CALL XERBLA( 'ZTREVC3', -INFO )
+         RETURN
+      ELSE IF( LQUERY ) THEN
+         RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF( N.EQ.0 )
+     $   RETURN
+*
+*     Use blocked version of back-transformation if sufficient workspace.
+*     Zero-out the workspace to avoid potential NaN propagation.
+*
+      IF( OVER .AND. LWORK .GE. N + 2*N*NBMIN ) THEN
+         NB = (LWORK - N) / (2*N)
+         NB = MIN( NB, NBMAX )
+         CALL ZLASET( 'F', N, 1+2*NB, CZERO, CZERO, WORK, N )
+      ELSE
+         NB = 1
+      END IF
+*
+*     Set the constants to control overflow.
+*
+      UNFL = DLAMCH( 'Safe minimum' )
+      OVFL = ONE / UNFL
+      CALL DLABAD( UNFL, OVFL )
+      ULP = DLAMCH( 'Precision' )
+      SMLNUM = UNFL*( N / ULP )
+*
+*     Store the diagonal elements of T in working array WORK.
+*
+      DO 20 I = 1, N
+         WORK( I ) = T( I, I )
+   20 CONTINUE
+*
+*     Compute 1-norm of each column of strictly upper triangular
+*     part of T to control overflow in triangular solver.
+*
+      RWORK( 1 ) = ZERO
+      DO 30 J = 2, N
+         RWORK( J ) = DZASUM( J-1, T( 1, J ), 1 )
+   30 CONTINUE
+*
+      IF( RIGHTV ) THEN
+*
+*        ============================================================
+*        Compute right eigenvectors.
+*
+*        IV is index of column in current block.
+*        Non-blocked version always uses IV=NB=1;
+*        blocked     version starts with IV=NB, goes down to 1.
+*        (Note the "0-th" column is used to store the original diagonal.)
+         IV = NB
+         IS = M
+         DO 80 KI = N, 1, -1
+            IF( SOMEV ) THEN
+               IF( .NOT.SELECT( KI ) )
+     $            GO TO 80
+            END IF
+            SMIN = MAX( ULP*( CABS1( T( KI, KI ) ) ), SMLNUM )
+*
+*           --------------------------------------------------------
+*           Complex right eigenvector
+*
+            WORK( KI + IV*N ) = CONE
+*
+*           Form right-hand side.
+*
+            DO 40 K = 1, KI - 1
+               WORK( K + IV*N ) = -T( K, KI )
+   40       CONTINUE
+*
+*           Solve upper triangular system:
+*           [ T(1:KI-1,1:KI-1) - T(KI,KI) ]*X = SCALE*WORK.
+*
+            DO 50 K = 1, KI - 1
+               T( K, K ) = T( K, K ) - T( KI, KI )
+               IF( CABS1( T( K, K ) ).LT.SMIN )
+     $            T( K, K ) = SMIN
+   50       CONTINUE
+*
+            IF( KI.GT.1 ) THEN
+               CALL ZLATRS( 'Upper', 'No transpose', 'Non-unit', 'Y',
+     $                      KI-1, T, LDT, WORK( 1 + IV*N ), SCALE,
+     $                      RWORK, INFO )
+               WORK( KI + IV*N ) = SCALE
+            END IF
+*
+*           Copy the vector x or Q*x to VR and normalize.
+*
+            IF( .NOT.OVER ) THEN
+*              ------------------------------
+*              no back-transform: copy x to VR and normalize.
+               CALL ZCOPY( KI, WORK( 1 + IV*N ), 1, VR( 1, IS ), 1 )
+*
+               II = IZAMAX( KI, VR( 1, IS ), 1 )
+               REMAX = ONE / CABS1( VR( II, IS ) )
+               CALL ZDSCAL( KI, REMAX, VR( 1, IS ), 1 )
+*
+               DO 60 K = KI + 1, N
+                  VR( K, IS ) = CZERO
+   60          CONTINUE
+*
+            ELSE IF( NB.EQ.1 ) THEN
+*              ------------------------------
+*              version 1: back-transform each vector with GEMV, Q*x.
+               IF( KI.GT.1 )
+     $            CALL ZGEMV( 'N', N, KI-1, CONE, VR, LDVR,
+     $                        WORK( 1 + IV*N ), 1, DCMPLX( SCALE ),
+     $                        VR( 1, KI ), 1 )
+*
+               II = IZAMAX( N, VR( 1, KI ), 1 )
+               REMAX = ONE / CABS1( VR( II, KI ) )
+               CALL ZDSCAL( N, REMAX, VR( 1, KI ), 1 )
+*
+            ELSE
+*              ------------------------------
+*              version 2: back-transform block of vectors with GEMM
+*              zero out below vector
+               DO K = KI + 1, N
+                  WORK( K + IV*N ) = CZERO
+               END DO
+*
+*              Columns IV:NB of work are valid vectors.
+*              When the number of vectors stored reaches NB,
+*              or if this was last vector, do the GEMM
+               IF( (IV.EQ.1) .OR. (KI.EQ.1) ) THEN
+                  CALL ZGEMM( 'N', 'N', N, NB-IV+1, KI+NB-IV, CONE,
+     $                        VR, LDVR,
+     $                        WORK( 1 + (IV)*N    ), N,
+     $                        CZERO,
+     $                        WORK( 1 + (NB+IV)*N ), N )
+*                 normalize vectors
+                  DO K = IV, NB
+                     II = IZAMAX( N, WORK( 1 + (NB+K)*N ), 1 )
+                     REMAX = ONE / CABS1( WORK( II + (NB+K)*N ) )
+                     CALL ZDSCAL( N, REMAX, WORK( 1 + (NB+K)*N ), 1 )
+                  END DO
+                  CALL ZLACPY( 'F', N, NB-IV+1,
+     $                         WORK( 1 + (NB+IV)*N ), N,
+     $                         VR( 1, KI ), LDVR )
+                  IV = NB
+               ELSE
+                  IV = IV - 1
+               END IF
+            END IF
+*
+*           Restore the original diagonal elements of T.
+*
+            DO 70 K = 1, KI - 1
+               T( K, K ) = WORK( K )
+   70       CONTINUE
+*
+            IS = IS - 1
+   80    CONTINUE
+      END IF
+*
+      IF( LEFTV ) THEN
+*
+*        ============================================================
+*        Compute left eigenvectors.
+*
+*        IV is index of column in current block.
+*        Non-blocked version always uses IV=1;
+*        blocked     version starts with IV=1, goes up to NB.
+*        (Note the "0-th" column is used to store the original diagonal.)
+         IV = 1
+         IS = 1
+         DO 130 KI = 1, N
+*
+            IF( SOMEV ) THEN
+               IF( .NOT.SELECT( KI ) )
+     $            GO TO 130
+            END IF
+            SMIN = MAX( ULP*( CABS1( T( KI, KI ) ) ), SMLNUM )
+*
+*           --------------------------------------------------------
+*           Complex left eigenvector
+*
+            WORK( KI + IV*N ) = CONE
+*
+*           Form right-hand side.
+*
+            DO 90 K = KI + 1, N
+               WORK( K + IV*N ) = -CONJG( T( KI, K ) )
+   90       CONTINUE
+*
+*           Solve conjugate-transposed triangular system:
+*           [ T(KI+1:N,KI+1:N) - T(KI,KI) ]**H * X = SCALE*WORK.
+*
+            DO 100 K = KI + 1, N
+               T( K, K ) = T( K, K ) - T( KI, KI )
+               IF( CABS1( T( K, K ) ).LT.SMIN )
+     $            T( K, K ) = SMIN
+  100       CONTINUE
+*
+            IF( KI.LT.N ) THEN
+               CALL ZLATRS( 'Upper', 'Conjugate transpose', 'Non-unit',
+     $                      'Y', N-KI, T( KI+1, KI+1 ), LDT,
+     $                      WORK( KI+1 + IV*N ), SCALE, RWORK, INFO )
+               WORK( KI + IV*N ) = SCALE
+            END IF
+*
+*           Copy the vector x or Q*x to VL and normalize.
+*
+            IF( .NOT.OVER ) THEN
+*              ------------------------------
+*              no back-transform: copy x to VL and normalize.
+               CALL ZCOPY( N-KI+1, WORK( KI + IV*N ), 1, VL(KI,IS), 1 )
+*
+               II = IZAMAX( N-KI+1, VL( KI, IS ), 1 ) + KI - 1
+               REMAX = ONE / CABS1( VL( II, IS ) )
+               CALL ZDSCAL( N-KI+1, REMAX, VL( KI, IS ), 1 )
+*
+               DO 110 K = 1, KI - 1
+                  VL( K, IS ) = CZERO
+  110          CONTINUE
+*
+            ELSE IF( NB.EQ.1 ) THEN
+*              ------------------------------
+*              version 1: back-transform each vector with GEMV, Q*x.
+               IF( KI.LT.N )
+     $            CALL ZGEMV( 'N', N, N-KI, CONE, VL( 1, KI+1 ), LDVL,
+     $                        WORK( KI+1 + IV*N ), 1, DCMPLX( SCALE ),
+     $                        VL( 1, KI ), 1 )
+*
+               II = IZAMAX( N, VL( 1, KI ), 1 )
+               REMAX = ONE / CABS1( VL( II, KI ) )
+               CALL ZDSCAL( N, REMAX, VL( 1, KI ), 1 )
+*
+            ELSE
+*              ------------------------------
+*              version 2: back-transform block of vectors with GEMM
+*              zero out above vector
+*              could go from KI-NV+1 to KI-1
+               DO K = 1, KI - 1
+                  WORK( K + IV*N ) = CZERO
+               END DO
+*
+*              Columns 1:IV of work are valid vectors.
+*              When the number of vectors stored reaches NB,
+*              or if this was last vector, do the GEMM
+               IF( (IV.EQ.NB) .OR. (KI.EQ.N) ) THEN
+                  CALL ZGEMM( 'N', 'N', N, IV, N-KI+IV, ONE,
+     $                        VL( 1, KI-IV+1 ), LDVL,
+     $                        WORK( KI-IV+1 + (1)*N ), N,
+     $                        CZERO,
+     $                        WORK( 1 + (NB+1)*N ), N )
+*                 normalize vectors
+                  DO K = 1, IV
+                     II = IZAMAX( N, WORK( 1 + (NB+K)*N ), 1 )
+                     REMAX = ONE / CABS1( WORK( II + (NB+K)*N ) )
+                     CALL ZDSCAL( N, REMAX, WORK( 1 + (NB+K)*N ), 1 )
+                  END DO
+                  CALL ZLACPY( 'F', N, IV,
+     $                         WORK( 1 + (NB+1)*N ), N,
+     $                         VL( 1, KI-IV+1 ), LDVL )
+                  IV = 1
+               ELSE
+                  IV = IV + 1
+               END IF
+            END IF
+*
+*           Restore the original diagonal elements of T.
+*
+            DO 120 K = KI + 1, N
+               T( K, K ) = WORK( K )
+  120       CONTINUE
+*
+            IS = IS + 1
+  130    CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of ZTREVC3
+*
+      END
index 4125450c7aff83d243611b38733be4f4177425c0..02375224ebe8ab5c4a074548d3de4e773de3e38d 100644 (file)
       SUBROUTINE ZUNBDB1( M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI,
      $                    TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.5.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     July 2012
             CALL ZLARF( 'R', M-P-I, Q-I, X21(I,I+1), LDX21, TAUQ1(I),
      $                  X21(I+1,I+1), LDX21, WORK(ILARF) )
             CALL ZLACGV( Q-I, X21(I,I+1), LDX21 )
-            C = SQRT( DZNRM2( P-I, X11(I+1,I+1), 1, X11(I+1,I+1),
-     $          1 )**2 + DZNRM2( M-P-I, X21(I+1,I+1), 1, X21(I+1,I+1),
-     $          1 )**2 )
+            C = SQRT( DZNRM2( P-I, X11(I+1,I+1), 1 )**2 
+     $          + DZNRM2( M-P-I, X21(I+1,I+1), 1 )**2 )
             PHI(I) = ATAN2( S, C )
             CALL ZUNBDB5( P-I, M-P-I, Q-I-1, X11(I+1,I+1), 1,
      $                    X21(I+1,I+1), 1, X11(I+1,I+2), LDX11,
index 89104f650f73bac8d7b0fc91cf55f7b115b747e6..65508ec1e46e2fb312f9119d0d31f7dfb27405ac 100644 (file)
       SUBROUTINE ZUNBDB2( M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI,
      $                    TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.5.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     July 2012
          CALL ZLARF( 'R', M-P-I+1, Q-I+1, X11(I,I), LDX11, TAUQ1(I),
      $               X21(I,I), LDX21, WORK(ILARF) )
          CALL ZLACGV( Q-I+1, X11(I,I), LDX11 )
-         S = SQRT( DZNRM2( P-I, X11(I+1,I), 1, X11(I+1,I),
-     $       1 )**2 + DZNRM2( M-P-I+1, X21(I,I), 1, X21(I,I), 1 )**2 )
+         S = SQRT( DZNRM2( P-I, X11(I+1,I), 1 )**2
+     $           + DZNRM2( M-P-I+1, X21(I,I), 1 )**2 )
          THETA(I) = ATAN2( S, C )
 *
          CALL ZUNBDB5( P-I, M-P-I+1, Q-I, X11(I+1,I), 1, X21(I,I), 1,
index 37a5c89f400e164d27752e339f15540b945c993f..c1336c48c7304a36bc34cc388af887d9a61aaf13 100644 (file)
       SUBROUTINE ZUNBDB3( M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI,
      $                    TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO )
 *
-*  -- LAPACK computational routine (version 3.5.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     July 2012
          CALL ZLARF( 'R', M-P-I, Q-I+1, X21(I,I), LDX21, TAUQ1(I),
      $               X21(I+1,I), LDX21, WORK(ILARF) )
          CALL ZLACGV( Q-I+1, X21(I,I), LDX21 )
-         C = SQRT( DZNRM2( P-I+1, X11(I,I), 1, X11(I,I),
-     $       1 )**2 + DZNRM2( M-P-I, X21(I+1,I), 1, X21(I+1,I), 1 )**2 )
+         C = SQRT( DZNRM2( P-I+1, X11(I,I), 1 )**2
+     $           + DZNRM2( M-P-I, X21(I+1,I), 1 )**2 )
          THETA(I) = ATAN2( S, C )
 *
          CALL ZUNBDB5( P-I+1, M-P-I, Q-I, X11(I,I), 1, X21(I+1,I), 1,
index 91ed9d052f095d0bd8fe11bd5e62b7cab21f7790..17f529ee86166cd0e9ecaad1ccfe72ccdedfa367 100644 (file)
      $                    TAUP1, TAUP2, TAUQ1, PHANTOM, WORK, LWORK,
      $                    INFO )
 *
-*  -- LAPACK computational routine (version 3.5.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     July 2012
      $               X21(I+1,I), LDX21, WORK(ILARF) )
          CALL ZLACGV( Q-I+1, X21(I,I), LDX21 )
          IF( I .LT. M-Q ) THEN
-            S = SQRT( DZNRM2( P-I, X11(I+1,I), 1, X11(I+1,I),
-     $          1 )**2 + DZNRM2( M-P-I, X21(I+1,I), 1, X21(I+1,I),
-     $          1 )**2 )
+            S = SQRT( DZNRM2( P-I, X11(I+1,I), 1 )**2
+     $              + DZNRM2( M-P-I, X21(I+1,I), 1 )**2 )
             PHI(I) = ATAN2( S, C )
          END IF
 *
index 432471fe2242e847f28f53b0b3e07e6776e0af88..d4ab1eef5bd0fecfbdf9d931e0cfdbe72dd62eda 100644 (file)
      $                       LDV1T, WORK, LWORK, RWORK, LRWORK, IWORK,
      $                       INFO )
 *
-*  -- LAPACK computational routine (version 3.6.0) --
+*  -- LAPACK computational routine (version 3.6.1) --
 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
 *     July 2012
      $                   LWORKMIN, LWORKOPT, R
       LOGICAL            LQUERY, WANTU1, WANTU2, WANTV1T
 *     ..
+*     .. Local Arrays ..
+      DOUBLE PRECISION   DUM( 1 )
+      COMPLEX*16         CDUM( 1, 1 )
+*     ..
 *     .. External Subroutines ..
       EXTERNAL           ZBBCSD, ZCOPY, ZLACPY, ZLAPMR, ZLAPMT, ZUNBDB1,
      $                   ZUNBDB2, ZUNBDB3, ZUNBDB4, ZUNGLQ, ZUNGQR,
          INFO = -8
       ELSE IF( LDX21 .LT. MAX( 1, M-P ) ) THEN
          INFO = -10
-      ELSE IF( WANTU1 .AND. LDU1 .LT. P ) THEN
+      ELSE IF( WANTU1 .AND. LDU1 .LT. MAX( 1, P ) ) THEN
          INFO = -13
-      ELSE IF( WANTU2 .AND. LDU2 .LT. M - P ) THEN
+      ELSE IF( WANTU2 .AND. LDU2 .LT. MAX( 1, M - P ) ) THEN
          INFO = -15
-      ELSE IF( WANTV1T .AND. LDV1T .LT. Q ) THEN
+      ELSE IF( WANTV1T .AND. LDV1T .LT. MAX( 1, Q ) ) THEN
          INFO = -17
       END IF
 *
          IORBDB = ITAUQ1 + MAX( 1, Q )
          IORGQR = ITAUQ1 + MAX( 1, Q )
          IORGLQ = ITAUQ1 + MAX( 1, Q )
+         LORGQRMIN = 1
+         LORGQROPT = 1
+         LORGLQMIN = 1
+         LORGLQOPT = 1
          IF( R .EQ. Q ) THEN
-            CALL ZUNBDB1( M, P, Q, X11, LDX11, X21, LDX21, THETA, 0, 0,
-     $                    0, 0, WORK, -1, CHILDINFO )
+            CALL ZUNBDB1( M, P, Q, X11, LDX11, X21, LDX21, THETA, DUM,
+     $                    CDUM, CDUM, CDUM, WORK, -1, CHILDINFO )
             LORBDB = INT( WORK(1) )
-            IF( P .GE. M-P ) THEN
-               CALL ZUNGQR( P, P, Q, U1, LDU1, 0, WORK(1), -1,
+            IF( WANTU1 .AND. P .GT. 0 ) THEN
+               CALL ZUNGQR( P, P, Q, U1, LDU1, CDUM, WORK(1), -1,
      $                      CHILDINFO )
-               LORGQRMIN = MAX( 1, P )
-               LORGQROPT = INT( WORK(1) )
-            ELSE
-               CALL ZUNGQR( M-P, M-P, Q, U2, LDU2, 0, WORK(1), -1,
+               LORGQRMIN = MAX( LORGQRMIN, P )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            ENDIF
+            IF( WANTU2 .AND. M-P .GT. 0 ) THEN
+               CALL ZUNGQR( M-P, M-P, Q, U2, LDU2, CDUM, WORK(1), -1,
      $                      CHILDINFO )
-               LORGQRMIN = MAX( 1, M-P )
-               LORGQROPT = INT( WORK(1) )
+               LORGQRMIN = MAX( LORGQRMIN, M-P )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            END IF
+            IF( WANTV1T .AND. Q .GT. 0 ) THEN
+               CALL ZUNGLQ( Q-1, Q-1, Q-1, V1T, LDV1T,
+     $                      CDUM, WORK(1), -1, CHILDINFO )
+               LORGLQMIN = MAX( LORGLQMIN, Q-1 )
+               LORGLQOPT = MAX( LORGLQOPT, INT( WORK(1) ) )
             END IF
-            CALL ZUNGLQ( MAX(0,Q-1), MAX(0,Q-1), MAX(0,Q-1), V1T, LDV1T,
-     $                   0, WORK(1), -1, CHILDINFO )
-            LORGLQMIN = MAX( 1, Q-1 )
-            LORGLQOPT = INT( WORK(1) )
             CALL ZBBCSD( JOBU1, JOBU2, JOBV1T, 'N', 'N', M, P, Q, THETA,
-     $                   0, U1, LDU1, U2, LDU2, V1T, LDV1T, 0, 1, 0, 0,
-     $                   0, 0, 0, 0, 0, 0, RWORK(1), -1, CHILDINFO )
+     $                   DUM, U1, LDU1, U2, LDU2, V1T, LDV1T, CDUM, 1,
+     $                   DUM, DUM, DUM, DUM, DUM, DUM, DUM, DUM,
+     $                   RWORK(1), -1, CHILDINFO )
             LBBCSD = INT( RWORK(1) )
          ELSE IF( R .EQ. P ) THEN
-            CALL ZUNBDB2( M, P, Q, X11, LDX11, X21, LDX21, THETA, 0, 0,
-     $                    0, 0, WORK(1), -1, CHILDINFO )
+            CALL ZUNBDB2( M, P, Q, X11, LDX11, X21, LDX21, THETA, DUM,
+     $                    CDUM, CDUM, CDUM, WORK(1), -1, CHILDINFO )
             LORBDB = INT( WORK(1) )
-            IF( P-1 .GE. M-P ) THEN
-               CALL ZUNGQR( P-1, P-1, P-1, U1(2,2), LDU1, 0, WORK(1),
+            IF( WANTU1 .AND. P .GT. 0 ) THEN
+               CALL ZUNGQR( P-1, P-1, P-1, U1(2,2), LDU1, CDUM, WORK(1),
      $                      -1, CHILDINFO )
-               LORGQRMIN = MAX( 1, P-1 )
-               LORGQROPT = INT( WORK(1) )
-            ELSE
-               CALL ZUNGQR( M-P, M-P, Q, U2, LDU2, 0, WORK(1), -1,
+               LORGQRMIN = MAX( LORGQRMIN, P-1 )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            END IF
+            IF( WANTU2 .AND. M-P .GT. 0 ) THEN
+               CALL ZUNGQR( M-P, M-P, Q, U2, LDU2, CDUM, WORK(1), -1,
+     $                      CHILDINFO )
+               LORGQRMIN = MAX( LORGQRMIN, M-P )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            END IF
+            IF( WANTV1T .AND. Q .GT. 0 ) THEN
+               CALL ZUNGLQ( Q, Q, R, V1T, LDV1T, CDUM, WORK(1), -1,
      $                      CHILDINFO )
-               LORGQRMIN = MAX( 1, M-P )
-               LORGQROPT = INT( WORK(1) )
+               LORGLQMIN = MAX( LORGLQMIN, Q )
+               LORGLQOPT = MAX( LORGLQOPT, INT( WORK(1) ) )
             END IF
-            CALL ZUNGLQ( Q, Q, R, V1T, LDV1T, 0, WORK(1), -1,
-     $                   CHILDINFO )
-            LORGLQMIN = MAX( 1, Q )
-            LORGLQOPT = INT( WORK(1) )
             CALL ZBBCSD( JOBV1T, 'N', JOBU1, JOBU2, 'T', M, Q, P, THETA,
-     $                   0, V1T, LDV1T, 0, 1, U1, LDU1, U2, LDU2, 0, 0,
-     $                   0, 0, 0, 0, 0, 0, RWORK(1), -1, CHILDINFO )
+     $                   DUM, V1T, LDV1T, CDUM, 1, U1, LDU1, U2, LDU2,
+     $                   DUM, DUM, DUM, DUM, DUM, DUM, DUM, DUM,
+     $                   RWORK(1), -1, CHILDINFO )
             LBBCSD = INT( RWORK(1) )
          ELSE IF( R .EQ. M-P ) THEN
-            CALL ZUNBDB3( M, P, Q, X11, LDX11, X21, LDX21, THETA, 0, 0,
-     $                    0, 0, WORK(1), -1, CHILDINFO )
+            CALL ZUNBDB3( M, P, Q, X11, LDX11, X21, LDX21, THETA, DUM,
+     $                    CDUM, CDUM, CDUM, WORK(1), -1, CHILDINFO )
             LORBDB = INT( WORK(1) )
-            IF( P .GE. M-P-1 ) THEN
-               CALL ZUNGQR( P, P, Q, U1, LDU1, 0, WORK(1), -1,
+            IF( WANTU1 .AND. P .GT. 0 ) THEN
+               CALL ZUNGQR( P, P, Q, U1, LDU1, CDUM, WORK(1), -1,
      $                      CHILDINFO )
-               LORGQRMIN = MAX( 1, P )
-               LORGQROPT = INT( WORK(1) )
-            ELSE
-               CALL ZUNGQR( M-P-1, M-P-1, M-P-1, U2(2,2), LDU2, 0,
+               LORGQRMIN = MAX( LORGQRMIN, P )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            END IF
+            IF( WANTU2 .AND. M-P .GT. 0 ) THEN
+               CALL ZUNGQR( M-P-1, M-P-1, M-P-1, U2(2,2), LDU2, CDUM,
      $                      WORK(1), -1, CHILDINFO )
-               LORGQRMIN = MAX( 1, M-P-1 )
-               LORGQROPT = INT( WORK(1) )
+               LORGQRMIN = MAX( LORGQRMIN, M-P-1 )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            END IF
+            IF( WANTV1T .AND. Q .GT. 0 ) THEN
+               CALL ZUNGLQ( Q, Q, R, V1T, LDV1T, CDUM, WORK(1), -1,
+     $                      CHILDINFO )
+               LORGLQMIN = MAX( LORGLQMIN, Q )
+               LORGLQOPT = MAX( LORGLQOPT, INT( WORK(1) ) )
             END IF
-            CALL ZUNGLQ( Q, Q, R, V1T, LDV1T, 0, WORK(1), -1,
-     $                   CHILDINFO )
-            LORGLQMIN = MAX( 1, Q )
-            LORGLQOPT = INT( WORK(1) )
             CALL ZBBCSD( 'N', JOBV1T, JOBU2, JOBU1, 'T', M, M-Q, M-P,
-     $                   THETA, 0, 0, 1, V1T, LDV1T, U2, LDU2, U1, LDU1,
-     $                   0, 0, 0, 0, 0, 0, 0, 0, RWORK(1), -1,
-     $                   CHILDINFO )
+     $                   THETA, DUM, CDUM, 1, V1T, LDV1T, U2, LDU2, U1,
+     $                   LDU1, DUM, DUM, DUM, DUM, DUM, DUM, DUM, DUM,
+     $                   RWORK(1), -1, CHILDINFO )
             LBBCSD = INT( RWORK(1) )
          ELSE
-            CALL ZUNBDB4( M, P, Q, X11, LDX11, X21, LDX21, THETA, 0, 0,
-     $                    0, 0, 0, WORK(1), -1, CHILDINFO )
+            CALL ZUNBDB4( M, P, Q, X11, LDX11, X21, LDX21, THETA, DUM,
+     $                    CDUM, CDUM, CDUM, CDUM, WORK(1), -1, CHILDINFO
+     $                  )
             LORBDB = M + INT( WORK(1) )
-            IF( P .GE. M-P ) THEN
-               CALL ZUNGQR( P, P, M-Q, U1, LDU1, 0, WORK(1), -1,
+            IF( WANTU1 .AND. P .GT. 0 ) THEN
+               CALL ZUNGQR( P, P, M-Q, U1, LDU1, CDUM, WORK(1), -1,
      $                      CHILDINFO )
-               LORGQRMIN = MAX( 1, P )
-               LORGQROPT = INT( WORK(1) )
-            ELSE
-               CALL ZUNGQR( M-P, M-P, M-Q, U2, LDU2, 0, WORK(1), -1,
+               LORGQRMIN = MAX( LORGQRMIN, P )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            END IF
+            IF( WANTU2 .AND. M-P .GT. 0 ) THEN
+               CALL ZUNGQR( M-P, M-P, M-Q, U2, LDU2, CDUM, WORK(1), -1,
      $                      CHILDINFO )
-               LORGQRMIN = MAX( 1, M-P )
-               LORGQROPT = INT( WORK(1) )
+               LORGQRMIN = MAX( LORGQRMIN, M-P )
+               LORGQROPT = MAX( LORGQROPT, INT( WORK(1) ) )
+            END IF
+            IF( WANTV1T .AND. Q .GT. 0 ) THEN
+               CALL ZUNGLQ( Q, Q, Q, V1T, LDV1T, CDUM, WORK(1), -1,
+     $                      CHILDINFO )
+               LORGLQMIN = MAX( LORGLQMIN, Q )
+               LORGLQOPT = MAX( LORGLQOPT, INT( WORK(1) ) )
             END IF
-            CALL ZUNGLQ( Q, Q, Q, V1T, LDV1T, 0, WORK(1), -1,
-     $                   CHILDINFO )
-            LORGLQMIN = MAX( 1, Q )
-            LORGLQOPT = INT( WORK(1) )
             CALL ZBBCSD( JOBU2, JOBU1, 'N', JOBV1T, 'N', M, M-P, M-Q,
-     $                   THETA, 0, U2, LDU2, U1, LDU1, 0, 1, V1T, LDV1T,
-     $                   0, 0, 0, 0, 0, 0, 0, 0, RWORK(1), -1,
-     $                   CHILDINFO )
+     $                   THETA, DUM, U2, LDU2, U1, LDU1, CDUM, 1, V1T,
+     $                   LDV1T, DUM, DUM, DUM, DUM, DUM, DUM, DUM, DUM,
+     $                   RWORK(1), -1, CHILDINFO )
             LBBCSD = INT( RWORK(1) )
          END IF
          LRWORKMIN = IBBCSD+LBBCSD-1
 *        Simultaneously diagonalize X11 and X21.
 *   
          CALL ZBBCSD( JOBU1, JOBU2, JOBV1T, 'N', 'N', M, P, Q, THETA,
-     $                RWORK(IPHI), U1, LDU1, U2, LDU2, V1T, LDV1T, 0, 1,
-     $                RWORK(IB11D), RWORK(IB11E), RWORK(IB12D),
+     $                RWORK(IPHI), U1, LDU1, U2, LDU2, V1T, LDV1T, CDUM,
+     $                1, RWORK(IB11D), RWORK(IB11E), RWORK(IB12D),
      $                RWORK(IB12E), RWORK(IB21D), RWORK(IB21E),
      $                RWORK(IB22D), RWORK(IB22E), RWORK(IBBCSD), LBBCSD,
      $                CHILDINFO )
 *        Simultaneously diagonalize X11 and X21.
 *   
          CALL ZBBCSD( JOBV1T, 'N', JOBU1, JOBU2, 'T', M, Q, P, THETA,
-     $                RWORK(IPHI), V1T, LDV1T, 0, 1, U1, LDU1, U2, LDU2,
-     $                RWORK(IB11D), RWORK(IB11E), RWORK(IB12D),
+     $                RWORK(IPHI), V1T, LDV1T, CDUM, 1, U1, LDU1, U2,
+     $                LDU2, RWORK(IB11D), RWORK(IB11E), RWORK(IB12D),
      $                RWORK(IB12E), RWORK(IB21D), RWORK(IB21E),
      $                RWORK(IB22D), RWORK(IB22E), RWORK(IBBCSD), LBBCSD,
      $                CHILDINFO )
 *        Simultaneously diagonalize X11 and X21.
 *   
          CALL ZBBCSD( 'N', JOBV1T, JOBU2, JOBU1, 'T', M, M-Q, M-P,
-     $                THETA, RWORK(IPHI), 0, 1, V1T, LDV1T, U2, LDU2,
+     $                THETA, RWORK(IPHI), CDUM, 1, V1T, LDV1T, U2, LDU2,
      $                U1, LDU1, RWORK(IB11D), RWORK(IB11E),
      $                RWORK(IB12D), RWORK(IB12E), RWORK(IB21D),
      $                RWORK(IB21E), RWORK(IB22D), RWORK(IB22E),
 *        Simultaneously diagonalize X11 and X21.
 *   
          CALL ZBBCSD( JOBU2, JOBU1, 'N', JOBV1T, 'N', M, M-P, M-Q,
-     $                THETA, RWORK(IPHI), U2, LDU2, U1, LDU1, 0, 1, V1T,
-     $                LDV1T, RWORK(IB11D), RWORK(IB11E), RWORK(IB12D),
-     $                RWORK(IB12E), RWORK(IB21D), RWORK(IB21E),
-     $                RWORK(IB22D), RWORK(IB22E), RWORK(IBBCSD), LBBCSD,
-     $                CHILDINFO )
+     $                THETA, RWORK(IPHI), U2, LDU2, U1, LDU1, CDUM, 1,
+     $                V1T, LDV1T, RWORK(IB11D), RWORK(IB11E),
+     $                RWORK(IB12D), RWORK(IB12E), RWORK(IB21D),
+     $                RWORK(IB21E), RWORK(IB22D), RWORK(IB22E),
+     $                RWORK(IBBCSD), LBBCSD, CHILDINFO )
 *   
 *        Permute rows and columns to place identity submatrices in
 *        preferred positions