| @@ -188,6 +188,7 @@ else() | |||
| CACHE STRING "Linker flags for shared libs" FORCE) | |||
| endif( NOT LATESTLAPACK_FOUND ) | |||
| message(STATUS "BUILD TESTING : ${BUILD_TESTING}" ) | |||
| if(BUILD_TESTING) | |||
| add_subdirectory(TESTING) | |||
| endif(BUILD_TESTING) | |||
| @@ -200,7 +201,7 @@ option(LAPACKE "Build LAPACKE" OFF) | |||
| # if LAPACKE_WITH_TMG is selected, we need to add those routines to LAPACKE | |||
| option(LAPACKE_WITH_TMG "Build LAPACKE with tmglib routines" OFF) | |||
| if (LAPACKE_WITH_TMG) | |||
| option(LAPACKE "Build LAPACKE" ON) | |||
| set(LAPACKE ON) | |||
| if(NOT BUILD_TESTING) | |||
| add_subdirectory(TESTING/MATGEN) | |||
| endif(NOT BUILD_TESTING) | |||
| @@ -647,7 +647,7 @@ INPUT_ENCODING = UTF-8 | |||
| # *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py | |||
| # *.f90 *.f *.for *.vhd *.vhdl | |||
| FILE_PATTERNS = *.f | |||
| FILE_PATTERNS = * | |||
| # The RECURSIVE tag can be used to turn specify whether or not subdirectories | |||
| # should be searched for input files as well. Possible values are YES and NO. | |||
| @@ -1,391 +0,0 @@ | |||
| % Psfig/TeX Release 1.2 | |||
| % dvi2ps-li version | |||
| % | |||
| % All software, documentation, and related files in this distribution of | |||
| % psfig/tex are Copyright 1987, 1988 Trevor J. Darrell | |||
| % | |||
| % Permission is granted for use and non-profit distribution of psfig/tex | |||
| % providing that this notice be clearly maintained, but the right to | |||
| % distribute any portion of psfig/tex for profit or as part of any commercial | |||
| % product is specifically reserved for the author. | |||
| % | |||
| % $Header$ | |||
| % $Source$ | |||
| % | |||
| % Thanks to Greg Hager (GDH) and Ned Batchelder for their contributions | |||
| % to this project. | |||
| % | |||
| \catcode`\@=11\relax | |||
| \newwrite\@unused | |||
| \def\typeout#1{{\let\protect\string\immediate\write\@unused{#1}}} | |||
| \typeout{psfig/tex 1.2-dvi2ps-li} | |||
| %% Here's how you define your figure path. Should be set up with null | |||
| %% default and a user useable definition. | |||
| \def\figurepath{./} | |||
| \def\psfigurepath#1{\edef\figurepath{#1}} | |||
| % | |||
| % @psdo control structure -- similar to Latex @for. | |||
| % I redefined these with different names so that psfig can | |||
| % be used with TeX as well as LaTeX, and so that it will not | |||
| % be vunerable to future changes in LaTeX's internal | |||
| % control structure, | |||
| % | |||
| \def\@nnil{\@nil} | |||
| \def\@empty{} | |||
| \def\@psdonoop#1\@@#2#3{} | |||
| \def\@psdo#1:=#2\do#3{\edef\@psdotmp{#2}\ifx\@psdotmp\@empty \else | |||
| \expandafter\@psdoloop#2,\@nil,\@nil\@@#1{#3}\fi} | |||
| \def\@psdoloop#1,#2,#3\@@#4#5{\def#4{#1}\ifx #4\@nnil \else | |||
| #5\def#4{#2}\ifx #4\@nnil \else#5\@ipsdoloop #3\@@#4{#5}\fi\fi} | |||
| \def\@ipsdoloop#1,#2\@@#3#4{\def#3{#1}\ifx #3\@nnil | |||
| \let\@nextwhile=\@psdonoop \else | |||
| #4\relax\let\@nextwhile=\@ipsdoloop\fi\@nextwhile#2\@@#3{#4}} | |||
| \def\@tpsdo#1:=#2\do#3{\xdef\@psdotmp{#2}\ifx\@psdotmp\@empty \else | |||
| \@tpsdoloop#2\@nil\@nil\@@#1{#3}\fi} | |||
| \def\@tpsdoloop#1#2\@@#3#4{\def#3{#1}\ifx #3\@nnil | |||
| \let\@nextwhile=\@psdonoop \else | |||
| #4\relax\let\@nextwhile=\@tpsdoloop\fi\@nextwhile#2\@@#3{#4}} | |||
| % | |||
| % | |||
| \def\psdraft{ | |||
| \def\@psdraft{0} | |||
| %\typeout{draft level now is \@psdraft \space . } | |||
| } | |||
| \def\psfull{ | |||
| \def\@psdraft{100} | |||
| %\typeout{draft level now is \@psdraft \space . } | |||
| } | |||
| \psfull | |||
| \newif\if@prologfile | |||
| \newif\if@postlogfile | |||
| \newif\if@noisy | |||
| \def\pssilent{ | |||
| \@noisyfalse | |||
| } | |||
| \def\psnoisy{ | |||
| \@noisytrue | |||
| } | |||
| \psnoisy | |||
| %%% These are for the option list. | |||
| %%% A specification of the form a = b maps to calling \@p@@sa{b} | |||
| \newif\if@bbllx | |||
| \newif\if@bblly | |||
| \newif\if@bburx | |||
| \newif\if@bbury | |||
| \newif\if@height | |||
| \newif\if@width | |||
| \newif\if@rheight | |||
| \newif\if@rwidth | |||
| \newif\if@clip | |||
| \newif\if@verbose | |||
| \def\@p@@sclip#1{\@cliptrue} | |||
| %%% GDH 7/26/87 -- changed so that it first looks in the local directory, | |||
| %%% then in a specified global directory for the ps file. | |||
| \def\@p@@sfile#1{\def\@p@sfile{null}% | |||
| \openin1=#1 | |||
| \ifeof1\closein1% | |||
| \openin1=\figurepath#1 | |||
| \ifeof1\typeout{Error, File #1 not found} | |||
| \else\closein1 | |||
| \edef\@p@sfile{\figurepath#1}% | |||
| \fi% | |||
| \else\closein1% | |||
| \def\@p@sfile{#1}% | |||
| \fi} | |||
| \def\@p@@sfigure#1{\def\@p@sfile{null}% | |||
| \openin1=#1 | |||
| \ifeof1\closein1% | |||
| \openin1=\figurepath#1 | |||
| \ifeof1\typeout{Error, File #1 not found} | |||
| \else\closein1 | |||
| \def\@p@sfile{\figurepath#1}% | |||
| \fi% | |||
| \else\closein1% | |||
| \def\@p@sfile{#1}% | |||
| \fi} | |||
| \def\@p@@sbbllx#1{ | |||
| %\typeout{bbllx is #1} | |||
| \@bbllxtrue | |||
| \dimen100=#1 | |||
| \edef\@p@sbbllx{\number\dimen100} | |||
| } | |||
| \def\@p@@sbblly#1{ | |||
| %\typeout{bblly is #1} | |||
| \@bbllytrue | |||
| \dimen100=#1 | |||
| \edef\@p@sbblly{\number\dimen100} | |||
| } | |||
| \def\@p@@sbburx#1{ | |||
| %\typeout{bburx is #1} | |||
| \@bburxtrue | |||
| \dimen100=#1 | |||
| \edef\@p@sbburx{\number\dimen100} | |||
| } | |||
| \def\@p@@sbbury#1{ | |||
| %\typeout{bbury is #1} | |||
| \@bburytrue | |||
| \dimen100=#1 | |||
| \edef\@p@sbbury{\number\dimen100} | |||
| } | |||
| \def\@p@@sheight#1{ | |||
| \@heighttrue | |||
| \dimen100=#1 | |||
| \edef\@p@sheight{\number\dimen100} | |||
| %\typeout{Height is \@p@sheight} | |||
| } | |||
| \def\@p@@swidth#1{ | |||
| %\typeout{Width is #1} | |||
| \@widthtrue | |||
| \dimen100=#1 | |||
| \edef\@p@swidth{\number\dimen100} | |||
| } | |||
| \def\@p@@srheight#1{ | |||
| %\typeout{Reserved height is #1} | |||
| \@rheighttrue | |||
| \dimen100=#1 | |||
| \edef\@p@srheight{\number\dimen100} | |||
| } | |||
| \def\@p@@srwidth#1{ | |||
| %\typeout{Reserved width is #1} | |||
| \@rwidthtrue | |||
| \dimen100=#1 | |||
| \edef\@p@srwidth{\number\dimen100} | |||
| } | |||
| \def\@p@@ssilent#1{ | |||
| \@verbosefalse | |||
| } | |||
| \def\@p@@sprolog#1{\@prologfiletrue\def\@prologfileval{#1}} | |||
| \def\@p@@spostlog#1{\@postlogfiletrue\def\@postlogfileval{#1}} | |||
| \def\@cs@name#1{\csname #1\endcsname} | |||
| \def\@setparms#1=#2,{\@cs@name{@p@@s#1}{#2}} | |||
| % | |||
| % initialize the defaults (size the size of the figure) | |||
| % | |||
| \def\ps@init@parms{ | |||
| \@bbllxfalse \@bbllyfalse | |||
| \@bburxfalse \@bburyfalse | |||
| \@heightfalse \@widthfalse | |||
| \@rheightfalse \@rwidthfalse | |||
| \def\@p@sbbllx{}\def\@p@sbblly{} | |||
| \def\@p@sbburx{}\def\@p@sbbury{} | |||
| \def\@p@sheight{}\def\@p@swidth{} | |||
| \def\@p@srheight{}\def\@p@srwidth{} | |||
| \def\@p@sfile{} | |||
| \def\@p@scost{10} | |||
| \def\@sc{} | |||
| \@prologfilefalse | |||
| \@postlogfilefalse | |||
| \@clipfalse | |||
| \if@noisy | |||
| \@verbosetrue | |||
| \else | |||
| \@verbosefalse | |||
| \fi | |||
| } | |||
| % | |||
| % Go through the options setting things up. | |||
| % | |||
| \def\parse@ps@parms#1{ | |||
| \@psdo\@psfiga:=#1\do | |||
| {\expandafter\@setparms\@psfiga,}} | |||
| % | |||
| % Compute bb height and width | |||
| % | |||
| \newif\ifno@bb | |||
| \newif\ifnot@eof | |||
| \newread\ps@stream | |||
| \def\bb@missing{ | |||
| \if@verbose{ | |||
| \typeout{psfig: searching \@p@sfile \space for bounding box} | |||
| }\fi | |||
| \openin\ps@stream=\@p@sfile | |||
| \no@bbtrue | |||
| \not@eoftrue | |||
| \catcode`\%=12 | |||
| \loop | |||
| \read\ps@stream to \line@in | |||
| \global\toks200=\expandafter{\line@in} | |||
| \ifeof\ps@stream \not@eoffalse \fi | |||
| %\typeout{ looking at :: \the\toks200 } | |||
| \@bbtest{\toks200} | |||
| \if@bbmatch\not@eoffalse\expandafter\bb@cull\the\toks200\fi | |||
| \ifnot@eof \repeat | |||
| \catcode`\%=14 | |||
| } | |||
| \catcode`\%=12 | |||
| \newif\if@bbmatch | |||
| \def\@bbtest#1{\expandafter\@a@\the#1%%BoundingBox:\@bbtest\@a@} | |||
| \long\def\@a@#1%%BoundingBox:#2#3\@a@{\ifx\@bbtest#2\@bbmatchfalse\else\@bbmatchtrue\fi} | |||
| \long\def\bb@cull#1 #2 #3 #4 #5 { | |||
| \dimen100=#2 bp\edef\@p@sbbllx{\number\dimen100} | |||
| \dimen100=#3 bp\edef\@p@sbblly{\number\dimen100} | |||
| \dimen100=#4 bp\edef\@p@sbburx{\number\dimen100} | |||
| \dimen100=#5 bp\edef\@p@sbbury{\number\dimen100} | |||
| \no@bbfalse | |||
| } | |||
| \catcode`\%=14 | |||
| % | |||
| \def\compute@bb{ | |||
| \no@bbfalse | |||
| \if@bbllx \else \no@bbtrue \fi | |||
| \if@bblly \else \no@bbtrue \fi | |||
| \if@bburx \else \no@bbtrue \fi | |||
| \if@bbury \else \no@bbtrue \fi | |||
| \ifno@bb \bb@missing \fi | |||
| \ifno@bb \typeout{FATAL ERROR: no bb supplied or found} | |||
| \no-bb-error | |||
| \fi | |||
| % | |||
| \count203=\@p@sbburx | |||
| \count204=\@p@sbbury | |||
| \advance\count203 by -\@p@sbbllx | |||
| \advance\count204 by -\@p@sbblly | |||
| \edef\@bbw{\number\count203} | |||
| \edef\@bbh{\number\count204} | |||
| %\typeout{ bbh = \@bbh, bbw = \@bbw } | |||
| } | |||
| % | |||
| % \in@hundreds performs #1 * (#2 / #3) correct to the hundreds, | |||
| % then leaves the result in @result | |||
| % | |||
| \def\in@hundreds#1#2#3{\count240=#2 \count241=#3 | |||
| \count100=\count240 % 100 is first digit #2/#3 | |||
| \divide\count100 by \count241 | |||
| \count101=\count100 | |||
| \multiply\count101 by \count241 | |||
| \advance\count240 by -\count101 | |||
| \multiply\count240 by 10 | |||
| \count101=\count240 %101 is second digit of #2/#3 | |||
| \divide\count101 by \count241 | |||
| \count102=\count101 | |||
| \multiply\count102 by \count241 | |||
| \advance\count240 by -\count102 | |||
| \multiply\count240 by 10 | |||
| \count102=\count240 % 102 is the third digit | |||
| \divide\count102 by \count241 | |||
| \count200=#1\count205=0 | |||
| \count201=\count200 | |||
| \multiply\count201 by \count100 | |||
| \advance\count205 by \count201 | |||
| \count201=\count200 | |||
| \divide\count201 by 10 | |||
| \multiply\count201 by \count101 | |||
| \advance\count205 by \count201 | |||
| % | |||
| \count201=\count200 | |||
| \divide\count201 by 100 | |||
| \multiply\count201 by \count102 | |||
| \advance\count205 by \count201 | |||
| % | |||
| \edef\@result{\number\count205} | |||
| } | |||
| \def\compute@wfromh{ | |||
| % computing : width = height * (bbw / bbh) | |||
| \in@hundreds{\@p@sheight}{\@bbw}{\@bbh} | |||
| %\typeout{ \@p@sheight * \@bbw / \@bbh, = \@result } | |||
| \edef\@p@swidth{\@result} | |||
| %\typeout{w from h: width is \@p@swidth} | |||
| } | |||
| \def\compute@hfromw{ | |||
| % computing : height = width * (bbh / bbw) | |||
| \in@hundreds{\@p@swidth}{\@bbh}{\@bbw} | |||
| %\typeout{ \@p@swidth * \@bbh / \@bbw = \@result } | |||
| \edef\@p@sheight{\@result} | |||
| %\typeout{h from w : height is \@p@sheight} | |||
| } | |||
| \def\compute@handw{ | |||
| \if@height | |||
| \if@width | |||
| \else | |||
| \compute@wfromh | |||
| \fi | |||
| \else | |||
| \if@width | |||
| \compute@hfromw | |||
| \else | |||
| \edef\@p@sheight{\@bbh} | |||
| \edef\@p@swidth{\@bbw} | |||
| \fi | |||
| \fi | |||
| } | |||
| \def\compute@resv{ | |||
| \if@rheight \else \edef\@p@srheight{\@p@sheight} \fi | |||
| \if@rwidth \else \edef\@p@srwidth{\@p@swidth} \fi | |||
| } | |||
| % | |||
| % Compute any missing values | |||
| \def\compute@sizes{ | |||
| \compute@bb | |||
| \compute@handw | |||
| \compute@resv | |||
| } | |||
| % | |||
| % \psfig | |||
| % usage : \psfig{file=, height=, width=, bbllx=, bblly=, bburx=, bbury=, | |||
| % rheight=, rwidth=, clip=} | |||
| % | |||
| % "clip=" is a switch and takes no value, but the `=' must be present. | |||
| \def\psfig#1{\vbox { | |||
| % do a zero width hard space so that a single | |||
| % \psfig in a centering enviornment will behave nicely | |||
| %{\setbox0=\hbox{\ }\ \hskip-\wd0} | |||
| % | |||
| \ps@init@parms | |||
| \parse@ps@parms{#1} | |||
| \compute@sizes | |||
| % | |||
| \ifnum\@p@scost<\@psdraft{ | |||
| \if@verbose{ | |||
| \typeout{psfig: including \@p@sfile \space } | |||
| }\fi | |||
| % | |||
| \special{ pstext="\@p@swidth \space | |||
| \@p@sheight \space | |||
| \@p@sbbllx \space \@p@sbblly \space | |||
| \@p@sbburx \space | |||
| \@p@sbbury \space startTexFig" \space} | |||
| \if@clip{ | |||
| \if@verbose{ | |||
| \typeout{(clip)} | |||
| }\fi | |||
| \special{ pstext="doclip \space"} | |||
| }\fi | |||
| \if@prologfile | |||
| \special{psfile=\@prologfileval \space } \fi | |||
| \special{psfile=\@p@sfile \space } | |||
| \if@postlogfile | |||
| \special{psfile=\@postlogfileval \space } \fi | |||
| \special{pstext=endTexFig \space } | |||
| % Create the vbox to reserve the space for the figure | |||
| \vbox to \@p@srheight true sp{ | |||
| \hbox to \@p@srwidth true sp{ | |||
| \hss | |||
| } | |||
| \vss | |||
| } | |||
| }\else{ | |||
| % draft figure, just reserve the space and print the | |||
| % path name. | |||
| \vbox to \@p@srheight true sp{ | |||
| \vss | |||
| \hbox to \@p@srwidth true sp{ | |||
| \hss | |||
| \if@verbose{ | |||
| \@p@sfile | |||
| }\fi | |||
| \hss | |||
| } | |||
| \vss | |||
| } | |||
| }\fi | |||
| }} | |||
| \def\psglobal{\typeout{psfig: PSGLOBAL is OBSOLETE; use psprint -m instead}} | |||
| \catcode`\@=12\relax | |||
| @@ -72,6 +72,10 @@ | |||
| CHARACTER CMACH | |||
| * .. | |||
| * | |||
| * .. Scalar Arguments .. | |||
| DOUBLE PRECISION A, B | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| @@ -41,14 +41,14 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date September 2012 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup auxOTHERauxiliary | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE ILAVER( VERS_MAJOR, VERS_MINOR, VERS_PATCH ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.2) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * September 2012 | |||
| @@ -58,8 +58,8 @@ | |||
| INTEGER VERS_MAJOR, VERS_MINOR, VERS_PATCH | |||
| * ===================================================================== | |||
| VERS_MAJOR = 3 | |||
| VERS_MINOR = 4 | |||
| VERS_PATCH = 2 | |||
| VERS_MINOR = 5 | |||
| VERS_PATCH = 0 | |||
| * ===================================================================== | |||
| * | |||
| RETURN | |||
| @@ -1,7 +1,7 @@ | |||
| #################################################################### | |||
| # LAPACK make include file. # | |||
| # LAPACK, Version 3.4.1 # | |||
| # April 2012 # | |||
| # LAPACK, Version 3.5.0 # | |||
| # November 2013 # | |||
| #################################################################### | |||
| # | |||
| SHELL = /bin/sh | |||
| @@ -1,7 +1,7 @@ | |||
| #################################################################### | |||
| # LAPACK make include file. # | |||
| # LAPACK, Version 3.4.1 # | |||
| # April 2012 # | |||
| # LAPACK, Version 3.5.0 # | |||
| # November 2013 # | |||
| #################################################################### | |||
| # | |||
| SHELL = /bin/sh | |||
| @@ -1,7 +1,7 @@ | |||
| #################################################################### | |||
| # LAPACK make include file. # | |||
| # LAPACK, Version 3.4.1 # | |||
| # April 2012 # | |||
| # LAPACK, Version 3.5.0 # | |||
| # November 2013 # | |||
| #################################################################### | |||
| # | |||
| SHELL = /sbin/sh | |||
| @@ -1,7 +1,7 @@ | |||
| #################################################################### | |||
| # LAPACK make include file. # | |||
| # LAPACK, Version 3.4.1 # | |||
| # April 2012 # | |||
| # LAPACK, Version 3.5.0 # | |||
| # November 2013 # | |||
| #################################################################### | |||
| # | |||
| SHELL = /sbin/sh | |||
| @@ -1,7 +1,7 @@ | |||
| #################################################################### | |||
| # LAPACK make include file. # | |||
| # LAPACK, Version 3.4.1 # | |||
| # April 2012 # | |||
| # LAPACK, Version 3.5.0 # | |||
| # November 2013 # | |||
| #################################################################### | |||
| # | |||
| SHELL = /sbin/sh | |||
| @@ -1,7 +1,7 @@ | |||
| #################################################################### | |||
| # LAPACK make include file. # | |||
| # LAPACK, Version 3.4.1 # | |||
| # April 2012 # | |||
| # LAPACK, Version 3.5.0 # | |||
| # November 2013 # | |||
| #################################################################### | |||
| # | |||
| SHELL = /bin/sh | |||
| @@ -1,7 +1,7 @@ | |||
| #################################################################### | |||
| # LAPACK make include file. # | |||
| # LAPACK, Version 3.4.1 # | |||
| # April 2012 # | |||
| # LAPACK, Version 3.5.0 # | |||
| # November 2013 # | |||
| #################################################################### | |||
| # | |||
| SHELL = /bin/sh | |||
| @@ -1,7 +1,7 @@ | |||
| #################################################################### | |||
| # LAPACK make include file. # | |||
| # LAPACK, Version 3.4.1 # | |||
| # April 2012 # | |||
| # LAPACK, Version 3.5.0 # | |||
| # November 2013 # | |||
| #################################################################### | |||
| # | |||
| SHELL = /bin/sh | |||
| @@ -1,7 +1,7 @@ | |||
| #################################################################### | |||
| # LAPACK make include file. # | |||
| # LAPACK, Version 3.4.1 # | |||
| # April 2012 # | |||
| # LAPACK, Version 3.5.0 # | |||
| # November 2013 # | |||
| #################################################################### | |||
| # | |||
| SHELL = /bin/sh | |||
| @@ -13,9 +13,9 @@ SHELL = /bin/sh | |||
| # desired load options for your machine. | |||
| # | |||
| FORTRAN = gfortran | |||
| OPTS = -O2 | |||
| OPTS = -O2 -frecursive | |||
| DRVOPTS = $(OPTS) | |||
| NOOPT = -O0 | |||
| NOOPT = -O0 -frecursive | |||
| LOADER = gfortran | |||
| LOADOPTS = | |||
| # | |||
| @@ -1,7 +1,7 @@ | |||
| #################################################################### | |||
| # LAPACK make include file. # | |||
| # LAPACK, Version 3.4.1 # | |||
| # April 2012 # | |||
| # LAPACK, Version 3.5.0 # | |||
| # November 2013 # | |||
| #################################################################### | |||
| # | |||
| SHELL = /bin/sh | |||
| @@ -12,10 +12,10 @@ SHELL = /bin/sh | |||
| # selected. Define LOADER and LOADOPTS to refer to the loader | |||
| # and desired load options for your machine. | |||
| # | |||
| FORTRAN = gfortran -fimplicit-none -g | |||
| FORTRAN = gfortran -fimplicit-none -g -frecursive | |||
| OPTS = | |||
| DRVOPTS = $(OPTS) | |||
| NOOPT = -g -O0 | |||
| NOOPT = -g -O0 -frecursive | |||
| LOADER = gfortran -g | |||
| LOADOPTS = | |||
| # | |||
| @@ -1,7 +1,7 @@ | |||
| #################################################################### | |||
| # LAPACK make include file. # | |||
| # LAPACK, Version 3.4.1 # | |||
| # April 2012 # | |||
| # LAPACK, Version 3.5.0 # | |||
| # November 2013 # | |||
| #################################################################### | |||
| # | |||
| SHELL = /bin/sh | |||
| @@ -1,7 +1,7 @@ | |||
| #################################################################### | |||
| # LAPACK make include file. # | |||
| # LAPACK, Version 3.4.1 # | |||
| # April 2012 # | |||
| # LAPACK, Version 3.5.0 # | |||
| # November 2013 # | |||
| #################################################################### | |||
| # | |||
| SHELL = /bin/sh | |||
| @@ -1,7 +1,7 @@ | |||
| #################################################################### | |||
| # LAPACK make include file. # | |||
| # LAPACK, Version 3.4.1 # | |||
| # April 2012 # | |||
| # LAPACK, Version 3.5.0 # | |||
| # November 2013 # | |||
| #################################################################### | |||
| # | |||
| SHELL = /bin/sh | |||
| @@ -20,6 +20,7 @@ VERSION 3.3.1 : April 2011 | |||
| VERSION 3.4.0 : November 2011 | |||
| VERSION 3.4.1 : April 2012 | |||
| VERSION 3.4.2 : September 2012 | |||
| VERSION 3.5.0 : November 2013 | |||
| LAPACK is a library of Fortran 90 with subroutines for solving | |||
| the most commonly occurring problems in numerical linear algebra. | |||
| @@ -40,8 +41,8 @@ very much on the efficiency of the BLAS. | |||
| ================= | |||
| LAPACK INSTALLATION: | |||
| - LAPACK can be installed with make. Configuration haev to be set in the | |||
| make.inc file. A make.inc.example for a Linux mahcine running GNU compilers | |||
| - LAPACK can be installed with make. Configuration have to be set in the | |||
| make.inc file. A make.inc.example for a Linux machine running GNU compilers | |||
| is given in the main directory. Some specific make.inc are also available in | |||
| the INSTALL directory | |||
| - LAPACK includes also the CMAKE build. You will need to have CMAKE installed | |||
| @@ -113,7 +113,7 @@ set(SLASRC | |||
| slaqtr.f slar1v.f slar2v.f ilaslr.f ilaslc.f | |||
| slarf.f slarfb.f slarfg.f slarfgp.f slarft.f slarfx.f slargv.f | |||
| slarrv.f slartv.f | |||
| slarz.f slarzb.f slarzt.f slaswp.f slasy2.f slasyf.f | |||
| slarz.f slarzb.f slarzt.f slaswp.f slasy2.f slasyf.f slasyf_rook.f | |||
| slatbs.f slatdf.f slatps.f slatrd.f slatrs.f slatrz.f slatzm.f | |||
| slauu2.f slauum.f sopgtr.f sopmtr.f sorg2l.f sorg2r.f | |||
| sorgbr.f sorghr.f sorgl2.f sorglq.f sorgql.f sorgqr.f sorgr2.f | |||
| @@ -134,6 +134,8 @@ set(SLASRC | |||
| ssygst.f ssygv.f ssygvd.f ssygvx.f ssyrfs.f ssysv.f ssysvx.f | |||
| ssytd2.f ssytf2.f ssytrd.f ssytrf.f ssytri.f ssytri2.f ssytri2x.f | |||
| ssyswapr.f ssytrs.f ssytrs2.f ssyconv.f | |||
| ssytf2_rook.f ssytrf_rook.f ssytrs_rook.f | |||
| ssytri_rook.f ssycon_rook.f ssysv_rook.f | |||
| stbcon.f | |||
| 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 | |||
| @@ -144,7 +146,8 @@ set(SLASRC | |||
| stfttr.f stpttf.f stpttr.f strttf.f strttp.f | |||
| sgejsv.f sgesvj.f sgsvj0.f sgsvj1.f | |||
| sgeequb.f ssyequb.f spoequb.f sgbequb.f | |||
| sbbcsd.f slapmr.f sorbdb.f sorcsd.f | |||
| sbbcsd.f slapmr.f sorbdb.f sorbdb1.f sorbdb2.f sorbdb3.f sorbdb4.f | |||
| sorbdb5.f sorbdb6.f sorcsd.f sorcsd2by1.f | |||
| sgeqrt.f sgeqrt2.f sgeqrt3.f sgemqrt.f | |||
| stpqrt.f stpqrt2.f stpmqrt.f stprfb.f | |||
| ) | |||
| @@ -176,15 +179,17 @@ set(CLASRC | |||
| checon.f cheev.f cheevd.f cheevr.f cheevx.f chegs2.f chegst.f | |||
| chegv.f chegvd.f chegvx.f cherfs.f chesv.f chesvx.f chetd2.f | |||
| chetf2.f chetrd.f | |||
| chetrf.f chetri.f chetri2.f chetri2x.f cheswapr.f | |||
| chetrs.f chetrs2.f chgeqz.f chpcon.f chpev.f chpevd.f | |||
| chetrf.f chetri.f chetri2.f chetri2x.f cheswapr.f | |||
| chetrs.f chetrs2.f | |||
| chetf2_rook.f chetrf_rook.f chetri_rook.f chetrs_rook.f checon_rook.f chesv_rook.f | |||
| chgeqz.f chpcon.f chpev.f chpevd.f | |||
| chpevx.f chpgst.f chpgv.f chpgvd.f chpgvx.f chprfs.f chpsv.f | |||
| chpsvx.f | |||
| chptrd.f chptrf.f chptri.f chptrs.f chsein.f chseqr.f clabrd.f | |||
| clacgv.f clacon.f clacn2.f clacp2.f clacpy.f clacrm.f clacrt.f cladiv.f | |||
| claed0.f claed7.f claed8.f | |||
| claein.f claesy.f claev2.f clags2.f clagtm.f | |||
| clahef.f clahqr.f | |||
| clahef.f clahef_rook.f clahqr.f | |||
| clahrd.f clahr2.f claic1.f clals0.f clalsa.f clalsd.f clangb.f clange.f clangt.f | |||
| clanhb.f clanhe.f | |||
| clanhp.f clanhs.f clanht.f clansb.f clansp.f clansy.f clantb.f | |||
| @@ -195,7 +200,7 @@ set(CLASRC | |||
| clarf.f clarfb.f clarfg.f clarfgp.f clarft.f | |||
| clarfx.f clargv.f clarnv.f clarrv.f clartg.f clartv.f | |||
| clarz.f clarzb.f clarzt.f clascl.f claset.f clasr.f classq.f | |||
| claswp.f clasyf.f clatbs.f clatdf.f clatps.f clatrd.f clatrs.f clatrz.f | |||
| claswp.f clasyf.f clasyf_rook.f clatbs.f clatdf.f clatps.f clatrd.f clatrs.f clatrz.f | |||
| clatzm.f clauu2.f clauum.f cpbcon.f cpbequ.f cpbrfs.f cpbstf.f cpbsv.f | |||
| cpbsvx.f cpbtf2.f cpbtrf.f cpbtrs.f cpocon.f cpoequ.f cporfs.f | |||
| cposv.f cposvx.f cpotf2.f cpotrf.f cpotri.f cpotrs.f cpstrf.f cpstf2.f | |||
| @@ -207,6 +212,8 @@ set(CLASRC | |||
| csyr.f csyrfs.f csysv.f csysvx.f csytf2.f csytrf.f csytri.f | |||
| csytri2.f csytri2x.f csyswapr.f | |||
| csytrs.f csytrs2.f csyconv.f | |||
| csytf2_rook.f csytrf_rook.f csytrs_rook.f | |||
| csytri_rook.f csycon_rook.f csysv_rook.f | |||
| 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 | |||
| @@ -219,7 +226,8 @@ set(CLASRC | |||
| chfrk.f ctfttp.f clanhf.f cpftrf.f cpftri.f cpftrs.f ctfsm.f ctftri.f | |||
| ctfttr.f ctpttf.f ctpttr.f ctrttf.f ctrttp.f | |||
| cgeequb.f cgbequb.f csyequb.f cpoequb.f cheequb.f | |||
| cbbcsd.f clapmr.f cunbdb.f cuncsd.f | |||
| cbbcsd.f clapmr.f cunbdb.f cunbdb1.f cunbdb2.f cunbdb3.f cunbdb4.f | |||
| cunbdb5.f cunbdb6.f cuncsd.f cuncsd2by1.f | |||
| cgeqrt.f cgeqrt2.f cgeqrt3.f cgemqrt.f | |||
| ctpqrt.f ctpqrt2.f ctpmqrt.f ctprfb.f) | |||
| @@ -261,7 +269,7 @@ set(DLASRC | |||
| dlaqtr.f dlar1v.f dlar2v.f iladlr.f iladlc.f | |||
| dlarf.f dlarfb.f dlarfg.f dlarfgp.f dlarft.f dlarfx.f dlargv.f | |||
| dlarrv.f dlartv.f | |||
| dlarz.f dlarzb.f dlarzt.f dlaswp.f dlasy2.f dlasyf.f | |||
| dlarz.f dlarzb.f dlarzt.f dlaswp.f dlasy2.f dlasyf.f dlasyf_rook.f | |||
| dlatbs.f dlatdf.f dlatps.f dlatrd.f dlatrs.f dlatrz.f dlatzm.f dlauu2.f | |||
| dlauum.f dopgtr.f dopmtr.f dorg2l.f dorg2r.f | |||
| dorgbr.f dorghr.f dorgl2.f dorglq.f dorgql.f dorgqr.f dorgr2.f | |||
| @@ -283,6 +291,8 @@ set(DLASRC | |||
| dsysv.f dsysvx.f | |||
| dsytd2.f dsytf2.f dsytrd.f dsytrf.f dsytri.f dsytrs.f dsytrs2.f | |||
| dsytri2.f dsytri2x.f dsyswapr.f dsyconv.f | |||
| dsytf2_rook.f dsytrf_rook.f dsytrs_rook.f | |||
| dsytri_rook.f dsycon_rook.f dsysv_rook.f | |||
| dtbcon.f | |||
| 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 | |||
| @@ -294,7 +304,8 @@ set(DLASRC | |||
| dtfttr.f dtpttf.f dtpttr.f dtrttf.f dtrttp.f | |||
| dgejsv.f dgesvj.f dgsvj0.f dgsvj1.f | |||
| dgeequb.f dsyequb.f dpoequb.f dgbequb.f | |||
| dbbcsd.f dlapmr.f dorbdb.f dorcsd.f | |||
| dbbcsd.f dlapmr.f dorbdb.f dorbdb1.f dorbdb2.f dorbdb3.f dorbdb4.f | |||
| dorbdb5.f dorbdb6.f dorcsd.f dorcsd2by1.f | |||
| dgeqrt.f dgeqrt2.f dgeqrt3.f dgemqrt.f | |||
| dtpqrt.f dtpqrt2.f dtpmqrt.f dtprfb.f ) | |||
| @@ -324,14 +335,16 @@ set(ZLASRC | |||
| zhegv.f zhegvd.f zhegvx.f zherfs.f zhesv.f zhesvx.f zhetd2.f | |||
| zhetf2.f zhetrd.f | |||
| zhetrf.f zhetri.f zhetri2.f zhetri2x.f zheswapr.f | |||
| zhetrs.f zhetrs2.f zhgeqz.f zhpcon.f zhpev.f zhpevd.f | |||
| zhetrs.f zhetrs2.f | |||
| zhetf2_rook.f zhetrf_rook.f zhetri_rook.f zhetrs_rook.f zhecon_rook.f zhesv_rook.f | |||
| zhgeqz.f zhpcon.f zhpev.f zhpevd.f | |||
| zhpevx.f zhpgst.f zhpgv.f zhpgvd.f zhpgvx.f zhprfs.f zhpsv.f | |||
| zhpsvx.f | |||
| zhptrd.f zhptrf.f zhptri.f zhptrs.f zhsein.f zhseqr.f zlabrd.f | |||
| zlacgv.f zlacon.f zlacn2.f zlacp2.f zlacpy.f zlacrm.f zlacrt.f zladiv.f | |||
| zlaed0.f zlaed7.f zlaed8.f | |||
| zlaein.f zlaesy.f zlaev2.f zlags2.f zlagtm.f | |||
| zlahef.f zlahqr.f | |||
| zlahef.f zlahef_rook.f zlahqr.f | |||
| zlahrd.f zlahr2.f zlaic1.f zlals0.f zlalsa.f zlalsd.f zlangb.f zlange.f | |||
| zlangt.f zlanhb.f | |||
| zlanhe.f | |||
| @@ -344,7 +357,7 @@ set(ZLASRC | |||
| zlarfg.f zlarfgp.f zlarft.f | |||
| zlarfx.f zlargv.f zlarnv.f zlarrv.f zlartg.f zlartv.f | |||
| zlarz.f zlarzb.f zlarzt.f zlascl.f zlaset.f zlasr.f | |||
| zlassq.f zlaswp.f zlasyf.f | |||
| zlassq.f zlaswp.f zlasyf.f zlasyf_rook.f | |||
| zlatbs.f zlatdf.f zlatps.f zlatrd.f zlatrs.f zlatrz.f zlatzm.f zlauu2.f | |||
| zlauum.f zpbcon.f zpbequ.f zpbrfs.f zpbstf.f zpbsv.f | |||
| zpbsvx.f zpbtf2.f zpbtrf.f zpbtrs.f zpocon.f zpoequ.f zporfs.f | |||
| @@ -357,6 +370,8 @@ set(ZLASRC | |||
| zsyr.f zsyrfs.f zsysv.f zsysvx.f zsytf2.f zsytrf.f zsytri.f | |||
| zsytri2.f zsytri2x.f zsyswapr.f | |||
| zsytrs.f zsytrs2.f zsyconv.f | |||
| zsytf2_rook.f zsytrf_rook.f zsytrs_rook.f | |||
| zsytri_rook.f zsycon_rook.f zsysv_rook.f | |||
| 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 | |||
| @@ -371,7 +386,8 @@ set(ZLASRC | |||
| zhfrk.f ztfttp.f zlanhf.f zpftrf.f zpftri.f zpftrs.f ztfsm.f ztftri.f | |||
| ztfttr.f ztpttf.f ztpttr.f ztrttf.f ztrttp.f | |||
| zgeequb.f zgbequb.f zsyequb.f zpoequb.f zheequb.f | |||
| zbbcsd.f zlapmr.f zunbdb.f zuncsd.f | |||
| zbbcsd.f zlapmr.f zunbdb.f zunbdb1.f zunbdb2.f zunbdb3.f zunbdb4.f | |||
| zunbdb5.f zunbdb6.f zuncsd.f zuncsd2by1.f | |||
| zgeqrt.f zgeqrt2.f zgeqrt3.f zgemqrt.f | |||
| ztpqrt.f ztpqrt2.f ztpmqrt.f ztprfb.f) | |||
| @@ -118,7 +118,7 @@ SLASRC = \ | |||
| slaqtr.o slar1v.o slar2v.o ilaslr.o ilaslc.o \ | |||
| slarf.o slarfb.o slarfg.o slarfgp.o slarft.o slarfx.o slargv.o \ | |||
| slarrv.o slartv.o \ | |||
| slarz.o slarzb.o slarzt.o slasy2.o slasyf.o \ | |||
| slarz.o slarzb.o slarzt.o slasy2.o slasyf.o slasyf_rook.o \ | |||
| slatbs.o slatdf.o slatps.o slatrd.o slatrs.o slatrz.o slatzm.o \ | |||
| sopgtr.o sopmtr.o sorg2l.o sorg2r.o \ | |||
| sorgbr.o sorghr.o sorgl2.o sorglq.o sorgql.o sorgqr.o sorgr2.o \ | |||
| @@ -140,6 +140,8 @@ SLASRC = \ | |||
| ssygst.o ssygv.o ssygvd.o ssygvx.o ssyrfs.o ssysv.o ssysvx.o \ | |||
| ssytd2.o ssytf2.o ssytrd.o ssytrf.o ssytri.o ssytri2.o ssytri2x.o \ | |||
| ssyswapr.o ssytrs.o ssytrs2.o ssyconv.o \ | |||
| ssytf2_rook.o ssytrf_rook.o ssytrs_rook.o \ | |||
| ssytri_rook.o ssycon_rook.o ssysv_rook.o \ | |||
| stbcon.o \ | |||
| 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 \ | |||
| @@ -150,7 +152,8 @@ SLASRC = \ | |||
| stfttr.o stpttf.o stpttr.o strttf.o strttp.o \ | |||
| sgejsv.o sgesvj.o sgsvj0.o sgsvj1.o \ | |||
| sgeequb.o ssyequb.o spoequb.o sgbequb.o \ | |||
| sbbcsd.o slapmr.o sorbdb.o sorcsd.o \ | |||
| sbbcsd.o slapmr.o sorbdb.o sorbdb1.o sorbdb2.o sorbdb3.o sorbdb4.o \ | |||
| sorbdb5.o sorbdb6.o sorcsd.o sorcsd2by1.o \ | |||
| sgeqrt.o sgeqrt2.o sgeqrt3.o sgemqrt.o \ | |||
| stpqrt.o stpqrt2.o stpmqrt.o stprfb.o | |||
| @@ -184,14 +187,16 @@ CLASRC = \ | |||
| chegv.o chegvd.o chegvx.o cherfs.o chesv.o chesvx.o chetd2.o \ | |||
| chetf2.o chetrd.o \ | |||
| chetrf.o chetri.o chetri2.o chetri2x.o cheswapr.o \ | |||
| chetrs.o chetrs2.o chgeqz.o chpcon.o chpev.o chpevd.o \ | |||
| chetrs.o chetrs2.o \ | |||
| chetf2_rook.o chetrf_rook.o chetri_rook.o chetrs_rook.o checon_rook.o chesv_rook.o \ | |||
| chgeqz.o chpcon.o chpev.o chpevd.o \ | |||
| chpevx.o chpgst.o chpgv.o chpgvd.o chpgvx.o chprfs.o chpsv.o \ | |||
| chpsvx.o \ | |||
| chptrd.o chptrf.o chptri.o chptrs.o chsein.o chseqr.o clabrd.o \ | |||
| clacgv.o clacon.o clacn2.o clacp2.o clacpy.o clacrm.o clacrt.o cladiv.o \ | |||
| claed0.o claed7.o claed8.o \ | |||
| claein.o claesy.o claev2.o clags2.o clagtm.o \ | |||
| clahef.o clahqr.o \ | |||
| clahef.o clahef_rook.o clahqr.o \ | |||
| clahrd.o clahr2.o claic1.o clals0.o clalsa.o clalsd.o clangb.o clange.o clangt.o \ | |||
| clanhb.o clanhe.o \ | |||
| clanhp.o clanhs.o clanht.o clansb.o clansp.o clansy.o clantb.o \ | |||
| @@ -202,7 +207,7 @@ CLASRC = \ | |||
| clarf.o clarfb.o clarfg.o clarft.o clarfgp.o \ | |||
| clarfx.o clargv.o clarnv.o clarrv.o clartg.o clartv.o \ | |||
| clarz.o clarzb.o clarzt.o clascl.o claset.o clasr.o classq.o \ | |||
| clasyf.o clatbs.o clatdf.o clatps.o clatrd.o clatrs.o clatrz.o \ | |||
| clasyf.o clasyf_rook.o clatbs.o clatdf.o clatps.o clatrd.o clatrs.o clatrz.o \ | |||
| clatzm.o cpbcon.o cpbequ.o cpbrfs.o cpbstf.o cpbsv.o \ | |||
| cpbsvx.o cpbtf2.o cpbtrf.o cpbtrs.o cpocon.o cpoequ.o cporfs.o \ | |||
| cposv.o cposvx.o cpotri.o cpstrf.o cpstf2.o \ | |||
| @@ -214,6 +219,8 @@ CLASRC = \ | |||
| csycon.o csymv.o \ | |||
| csyr.o csyrfs.o csysv.o csysvx.o csytf2.o csytrf.o csytri.o csytri2.o csytri2x.o \ | |||
| csyswapr.o csytrs.o csytrs2.o csyconv.o \ | |||
| csytf2_rook.o csytrf_rook.o csytrs_rook.o \ | |||
| csytri_rook.o csycon_rook.o csysv_rook.o \ | |||
| 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 \ | |||
| @@ -226,7 +233,8 @@ CLASRC = \ | |||
| chfrk.o ctfttp.o clanhf.o cpftrf.o cpftri.o cpftrs.o ctfsm.o ctftri.o \ | |||
| ctfttr.o ctpttf.o ctpttr.o ctrttf.o ctrttp.o \ | |||
| cgeequb.o cgbequb.o csyequb.o cpoequb.o cheequb.o \ | |||
| cbbcsd.o clapmr.o cunbdb.o cuncsd.o \ | |||
| cbbcsd.o clapmr.o cunbdb.o cunbdb1.o cunbdb2.o cunbdb3.o cunbdb4.o \ | |||
| cunbdb5.o cunbdb6.o cuncsd.o cuncsd2by1.o \ | |||
| cgeqrt.o cgeqrt2.o cgeqrt3.o cgemqrt.o \ | |||
| ctpqrt.o ctpqrt2.o ctpmqrt.o ctprfb.o | |||
| @@ -270,7 +278,7 @@ DLASRC = \ | |||
| dlaqtr.o dlar1v.o dlar2v.o iladlr.o iladlc.o \ | |||
| dlarf.o dlarfb.o dlarfg.o dlarfgp.o dlarft.o dlarfx.o \ | |||
| dlargv.o dlarrv.o dlartv.o \ | |||
| dlarz.o dlarzb.o dlarzt.o dlasy2.o dlasyf.o \ | |||
| dlarz.o dlarzb.o dlarzt.o dlasy2.o dlasyf.o dlasyf_rook.o \ | |||
| dlatbs.o dlatdf.o dlatps.o dlatrd.o dlatrs.o dlatrz.o dlatzm.o \ | |||
| dopgtr.o dopmtr.o dorg2l.o dorg2r.o \ | |||
| dorgbr.o dorghr.o dorgl2.o dorglq.o dorgql.o dorgqr.o dorgr2.o \ | |||
| @@ -293,6 +301,8 @@ DLASRC = \ | |||
| dsysv.o dsysvx.o \ | |||
| dsytd2.o dsytf2.o dsytrd.o dsytrf.o dsytri.o dsytri2.o dsytri2x.o \ | |||
| dsyswapr.o dsytrs.o dsytrs2.o dsyconv.o \ | |||
| dsytf2_rook.o dsytrf_rook.o dsytrs_rook.o \ | |||
| dsytri_rook.o dsycon_rook.o dsysv_rook.o \ | |||
| 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 \ | |||
| @@ -303,7 +313,8 @@ DLASRC = \ | |||
| dtfttr.o dtpttf.o dtpttr.o dtrttf.o dtrttp.o \ | |||
| dgejsv.o dgesvj.o dgsvj0.o dgsvj1.o \ | |||
| dgeequb.o dsyequb.o dpoequb.o dgbequb.o \ | |||
| dbbcsd.o dlapmr.o dorbdb.o dorcsd.o \ | |||
| dbbcsd.o dlapmr.o dorbdb.o dorbdb1.o dorbdb2.o dorbdb3.o dorbdb4.o \ | |||
| dorbdb5.o dorbdb6.o dorcsd.o dorcsd2by1.o \ | |||
| dgeqrt.o dgeqrt2.o dgeqrt3.o dgemqrt.o \ | |||
| dtpqrt.o dtpqrt2.o dtpmqrt.o dtprfb.o | |||
| @@ -335,14 +346,16 @@ ZLASRC = \ | |||
| zhegv.o zhegvd.o zhegvx.o zherfs.o zhesv.o zhesvx.o zhetd2.o \ | |||
| zhetf2.o zhetrd.o \ | |||
| zhetrf.o zhetri.o zhetri2.o zhetri2x.o zheswapr.o \ | |||
| zhetrs.o zhetrs2.o zhgeqz.o zhpcon.o zhpev.o zhpevd.o \ | |||
| zhetrs.o zhetrs2.o \ | |||
| zhetf2_rook.o zhetrf_rook.o zhetri_rook.o zhetrs_rook.o zhecon_rook.o zhesv_rook.o \ | |||
| zhgeqz.o zhpcon.o zhpev.o zhpevd.o \ | |||
| zhpevx.o zhpgst.o zhpgv.o zhpgvd.o zhpgvx.o zhprfs.o zhpsv.o \ | |||
| zhpsvx.o \ | |||
| zhptrd.o zhptrf.o zhptri.o zhptrs.o zhsein.o zhseqr.o zlabrd.o \ | |||
| zlacgv.o zlacon.o zlacn2.o zlacp2.o zlacpy.o zlacrm.o zlacrt.o zladiv.o \ | |||
| zlaed0.o zlaed7.o zlaed8.o \ | |||
| zlaein.o zlaesy.o zlaev2.o zlags2.o zlagtm.o \ | |||
| zlahef.o zlahqr.o \ | |||
| zlahef.o zlahef_rook.o zlahqr.o \ | |||
| zlahrd.o zlahr2.o zlaic1.o zlals0.o zlalsa.o zlalsd.o zlangb.o zlange.o \ | |||
| zlangt.o zlanhb.o \ | |||
| zlanhe.o \ | |||
| @@ -355,7 +368,7 @@ ZLASRC = \ | |||
| zlarfg.o zlarft.o zlarfgp.o \ | |||
| zlarfx.o zlargv.o zlarnv.o zlarrv.o zlartg.o zlartv.o \ | |||
| zlarz.o zlarzb.o zlarzt.o zlascl.o zlaset.o zlasr.o \ | |||
| zlassq.o zlasyf.o \ | |||
| zlassq.o zlasyf.o zlasyf_rook.o \ | |||
| zlatbs.o zlatdf.o zlatps.o zlatrd.o zlatrs.o zlatrz.o zlatzm.o zlauu2.o \ | |||
| zpbcon.o zpbequ.o zpbrfs.o zpbstf.o zpbsv.o \ | |||
| zpbsvx.o zpbtf2.o zpbtrf.o zpbtrs.o zpocon.o zpoequ.o zporfs.o \ | |||
| @@ -368,6 +381,8 @@ ZLASRC = \ | |||
| zsycon.o zsymv.o \ | |||
| zsyr.o zsyrfs.o zsysv.o zsysvx.o zsytf2.o zsytrf.o zsytri.o zsytri2.o zsytri2x.o \ | |||
| zsyswapr.o zsytrs.o zsytrs2.o zsyconv.o \ | |||
| zsytf2_rook.o zsytrf_rook.o zsytrs_rook.o \ | |||
| zsytri_rook.o zsycon_rook.o zsysv_rook.o \ | |||
| 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 \ | |||
| @@ -382,7 +397,8 @@ ZLASRC = \ | |||
| zhfrk.o ztfttp.o zlanhf.o zpftrf.o zpftri.o zpftrs.o ztfsm.o ztftri.o \ | |||
| ztfttr.o ztpttf.o ztpttr.o ztrttf.o ztrttp.o \ | |||
| zgeequb.o zgbequb.o zsyequb.o zpoequb.o zheequb.o \ | |||
| zbbcsd.o zlapmr.o zunbdb.o zuncsd.o \ | |||
| zbbcsd.o zlapmr.o zunbdb.o zunbdb1.o zunbdb2.o zunbdb3.o zunbdb4.o \ | |||
| zunbdb5.o zunbdb6.o zuncsd.o zuncsd2by1.o \ | |||
| zgeqrt.o zgeqrt2.o zgeqrt3.o zgemqrt.o \ | |||
| ztpqrt.o ztpqrt2.o ztpmqrt.o ztprfb.o | |||
| @@ -322,7 +322,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date November 2011 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup complexOTHERcomputational | |||
| * | |||
| @@ -332,10 +332,10 @@ | |||
| $ V2T, LDV2T, B11D, B11E, B12D, B12E, B21D, B21E, | |||
| $ B22D, B22E, RWORK, LRWORK, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.0) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * November 2011 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER JOBU1, JOBU2, JOBV1T, JOBV2T, TRANS | |||
| @@ -477,7 +477,10 @@ | |||
| * Initial deflation | |||
| * | |||
| IMAX = Q | |||
| DO WHILE( ( IMAX .GT. 1 ) .AND. ( PHI(IMAX-1) .EQ. ZERO ) ) | |||
| DO WHILE( IMAX .GT. 1 ) | |||
| IF( PHI(IMAX-1) .NE. ZERO ) THEN | |||
| EXIT | |||
| END IF | |||
| IMAX = IMAX - 1 | |||
| END DO | |||
| IMIN = IMAX - 1 | |||
| @@ -122,7 +122,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date November 2011 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup complexGEcomputational | |||
| * | |||
| @@ -161,10 +161,10 @@ | |||
| * ===================================================================== | |||
| SUBROUTINE CGEBAL( JOB, N, A, LDA, ILO, IHI, SCALE, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.0) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * November 2011 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER JOB | |||
| @@ -195,8 +195,8 @@ | |||
| * .. External Functions .. | |||
| LOGICAL SISNAN, LSAME | |||
| INTEGER ICAMAX | |||
| REAL SLAMCH | |||
| EXTERNAL SISNAN, LSAME, ICAMAX, SLAMCH | |||
| REAL SLAMCH, SCNRM2 | |||
| EXTERNAL SISNAN, LSAME, ICAMAX, SLAMCH, SCNRM2 | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL CSSCAL, CSWAP, XERBLA | |||
| @@ -325,15 +325,9 @@ | |||
| NOCONV = .FALSE. | |||
| * | |||
| DO 200 I = K, L | |||
| C = ZERO | |||
| R = ZERO | |||
| * | |||
| DO 150 J = K, L | |||
| IF( J.EQ.I ) | |||
| $ GO TO 150 | |||
| C = C + CABS1( A( J, I ) ) | |||
| R = R + CABS1( A( I, J ) ) | |||
| 150 CONTINUE | |||
| * | |||
| C = SCNRM2( L-K+1, A( K, I ), 1 ) | |||
| R = SCNRM2( L-K+1, A( I , K ), LDA ) | |||
| ICA = ICAMAX( L, A( 1, I ), 1 ) | |||
| CA = ABS( A( ICA, I ) ) | |||
| IRA = ICAMAX( N-K+1, A( I, K ), LDA ) | |||
| @@ -160,7 +160,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date November 2011 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup complexGEcomputational | |||
| * | |||
| @@ -168,10 +168,10 @@ | |||
| SUBROUTINE CGEMQRT( SIDE, TRANS, M, N, K, NB, V, LDV, T, LDT, | |||
| $ C, LDC, WORK, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.0) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * November 2011 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER SIDE, TRANS | |||
| @@ -225,7 +225,7 @@ | |||
| INFO = -4 | |||
| ELSE IF( K.LT.0 .OR. K.GT.Q ) THEN | |||
| INFO = -5 | |||
| ELSE IF( NB.LT.1 .OR. NB.GT.K ) THEN | |||
| ELSE IF( NB.LT.1 .OR. (NB.GT.K .AND. K.GT.0)) THEN | |||
| INFO = -6 | |||
| ELSE IF( LDV.LT.MAX( 1, Q ) ) THEN | |||
| INFO = -8 | |||
| @@ -108,7 +108,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date November 2011 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup complexGEcomputational | |||
| * | |||
| @@ -141,10 +141,10 @@ | |||
| * ===================================================================== | |||
| SUBROUTINE CGEQRT( M, N, NB, A, LDA, T, LDT, WORK, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.0) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * November 2011 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| INTEGER INFO, LDA, LDT, M, N, NB | |||
| @@ -173,7 +173,7 @@ | |||
| INFO = -1 | |||
| ELSE IF( N.LT.0 ) THEN | |||
| INFO = -2 | |||
| ELSE IF( NB.LT.1 .OR. NB.GT.MIN(M,N) ) THEN | |||
| ELSE IF( NB.LT.1 .OR. ( NB.GT.MIN(M,N) .AND. MIN(M,N).GT.0 ) )THEN | |||
| INFO = -3 | |||
| ELSE IF( LDA.LT.MAX( 1, M ) ) THEN | |||
| INFO = -5 | |||
| @@ -98,7 +98,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date September 2012 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup complexGEauxiliary | |||
| * | |||
| @@ -111,10 +111,10 @@ | |||
| * ===================================================================== | |||
| SUBROUTINE CGETC2( N, A, LDA, IPIV, JPIV, INFO ) | |||
| * | |||
| * -- LAPACK auxiliary routine (version 3.4.2) -- | |||
| * -- LAPACK auxiliary routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * September 2012 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| INTEGER INFO, LDA, N | |||
| @@ -203,6 +203,12 @@ | |||
| INFO = N | |||
| A( N, N ) = CMPLX( SMIN, ZERO ) | |||
| END IF | |||
| * | |||
| * Set last pivots to N | |||
| * | |||
| IPIV( N ) = N | |||
| JPIV( N ) = N | |||
| * | |||
| RETURN | |||
| * | |||
| * End of CGETC2 | |||
| @@ -0,0 +1,253 @@ | |||
| *> \brief \b CHECON_ROOK estimates the reciprocal of the condition number fort HE matrices using factorization obtained with one of the bounded diagonal pivoting methods (max 2 interchanges) | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download CHECON_ROOK + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/checon_rook.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/checon_rook.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/checon_rook.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE CHECON_ROOK( UPLO, N, A, LDA, IPIV, ANORM, RCOND, WORK, | |||
| * INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * CHARACTER UPLO | |||
| * INTEGER INFO, LDA, N | |||
| * REAL ANORM, RCOND | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * INTEGER IPIV( * ) | |||
| * COMPLEX A( LDA, * ), WORK( * ) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| * ============= | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> CHECON_ROOK estimates the reciprocal of the condition number of a complex | |||
| *> Hermitian matrix A using the factorization A = U*D*U**H or | |||
| *> A = L*D*L**H computed by CHETRF_ROOK. | |||
| *> | |||
| *> An estimate is obtained for norm(inv(A)), and the reciprocal of the | |||
| *> condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))). | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] UPLO | |||
| *> \verbatim | |||
| *> UPLO is CHARACTER*1 | |||
| *> Specifies whether the details of the factorization are stored | |||
| *> as an upper or lower triangular matrix. | |||
| *> = 'U': Upper triangular, form is A = U*D*U**H; | |||
| *> = 'L': Lower triangular, form is A = L*D*L**H. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] N | |||
| *> \verbatim | |||
| *> N is INTEGER | |||
| *> The order of the matrix A. N >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] A | |||
| *> \verbatim | |||
| *> A is COMPLEX array, dimension (LDA,N) | |||
| *> The block diagonal matrix D and the multipliers used to | |||
| *> obtain the factor U or L as computed by CHETRF_ROOK. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDA | |||
| *> \verbatim | |||
| *> LDA is INTEGER | |||
| *> The leading dimension of the array A. LDA >= max(1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] IPIV | |||
| *> \verbatim | |||
| *> IPIV is INTEGER array, dimension (N) | |||
| *> Details of the interchanges and the block structure of D | |||
| *> as determined by CHETRF_ROOK. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] ANORM | |||
| *> \verbatim | |||
| *> ANORM is REAL | |||
| *> The 1-norm of the original matrix A. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] RCOND | |||
| *> \verbatim | |||
| *> RCOND is REAL | |||
| *> The reciprocal of the condition number of the matrix A, | |||
| *> computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is an | |||
| *> estimate of the 1-norm of inv(A) computed in this routine. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] WORK | |||
| *> \verbatim | |||
| *> WORK is COMPLEX array, dimension (2*N) | |||
| *> \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 2013 | |||
| * | |||
| *> \ingroup complexHEcomputational | |||
| * | |||
| *> \par Contributors: | |||
| * ================== | |||
| *> \verbatim | |||
| *> | |||
| *> November 2013, Igor Kozachenko, | |||
| *> Computer Science Division, | |||
| *> University of California, Berkeley | |||
| *> | |||
| *> September 2007, Sven Hammarling, Nicholas J. Higham, Craig Lucas, | |||
| *> School of Mathematics, | |||
| *> University of Manchester | |||
| *> | |||
| *> \endverbatim | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE CHECON_ROOK( UPLO, N, A, LDA, IPIV, ANORM, RCOND, WORK, | |||
| $ INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER UPLO | |||
| INTEGER INFO, LDA, N | |||
| REAL ANORM, RCOND | |||
| * .. | |||
| * .. Array Arguments .. | |||
| INTEGER IPIV( * ) | |||
| COMPLEX A( LDA, * ), WORK( * ) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| REAL ONE, ZERO | |||
| PARAMETER ( ONE = 1.0E+0, ZERO = 0.0E+0 ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| LOGICAL UPPER | |||
| INTEGER I, KASE | |||
| REAL AINVNM | |||
| * .. | |||
| * .. Local Arrays .. | |||
| INTEGER ISAVE( 3 ) | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| EXTERNAL LSAME | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL CHETRS_ROOK, CLACN2, XERBLA | |||
| * .. | |||
| * .. Intrinsic Functions .. | |||
| INTRINSIC MAX | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Test the input parameters. | |||
| * | |||
| INFO = 0 | |||
| UPPER = LSAME( UPLO, 'U' ) | |||
| IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN | |||
| INFO = -1 | |||
| ELSE IF( N.LT.0 ) THEN | |||
| INFO = -2 | |||
| ELSE IF( LDA.LT.MAX( 1, N ) ) THEN | |||
| INFO = -4 | |||
| ELSE IF( ANORM.LT.ZERO ) THEN | |||
| INFO = -6 | |||
| END IF | |||
| IF( INFO.NE.0 ) THEN | |||
| CALL XERBLA( 'CHECON_ROOK', -INFO ) | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Quick return if possible | |||
| * | |||
| RCOND = ZERO | |||
| IF( N.EQ.0 ) THEN | |||
| RCOND = ONE | |||
| RETURN | |||
| ELSE IF( ANORM.LE.ZERO ) THEN | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Check that the diagonal matrix D is nonsingular. | |||
| * | |||
| IF( UPPER ) THEN | |||
| * | |||
| * Upper triangular storage: examine D from bottom to top | |||
| * | |||
| DO 10 I = N, 1, -1 | |||
| IF( IPIV( I ).GT.0 .AND. A( I, I ).EQ.ZERO ) | |||
| $ RETURN | |||
| 10 CONTINUE | |||
| ELSE | |||
| * | |||
| * Lower triangular storage: examine D from top to bottom. | |||
| * | |||
| DO 20 I = 1, N | |||
| IF( IPIV( I ).GT.0 .AND. A( I, I ).EQ.ZERO ) | |||
| $ RETURN | |||
| 20 CONTINUE | |||
| END IF | |||
| * | |||
| * Estimate the 1-norm of the inverse. | |||
| * | |||
| KASE = 0 | |||
| 30 CONTINUE | |||
| CALL CLACN2( N, WORK( N+1 ), WORK, AINVNM, KASE, ISAVE ) | |||
| IF( KASE.NE.0 ) THEN | |||
| * | |||
| * Multiply by inv(L*D*L**H) or inv(U*D*U**H). | |||
| * | |||
| CALL CHETRS_ROOK( UPLO, N, 1, A, LDA, IPIV, WORK, N, INFO ) | |||
| GO TO 30 | |||
| END IF | |||
| * | |||
| * Compute the estimate of the reciprocal condition number. | |||
| * | |||
| IF( AINVNM.NE.ZERO ) | |||
| $ RCOND = ( ONE / AINVNM ) / ANORM | |||
| * | |||
| RETURN | |||
| * | |||
| * End of CHECON_ROOK | |||
| * | |||
| END | |||
| @@ -0,0 +1,295 @@ | |||
| *> \brief \b CHESV_ROOK computes the solution to a system of linear equations A * X = B for HE matrices using the bounded Bunch-Kaufman ("rook") diagonal pivoting method | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download CHESV_ROOK + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/chesv_rook.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/chesv_rook.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/chesv_rook.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE CHESV_ROOK( UPLO, N, NRHS, A, LDA, IPIV, B, LDB, WORK, | |||
| * LWORK, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * CHARACTER UPLO | |||
| * INTEGER INFO, LDA, LDB, LWORK, N, NRHS | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * INTEGER IPIV( * ) | |||
| * COMPLEX A( LDA, * ), B( LDB, * ), WORK( * ) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| * ============= | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> CHESV_ROOK computes the solution to a complex system of linear equations | |||
| *> A * X = B, | |||
| *> where A is an N-by-N Hermitian matrix and X and B are N-by-NRHS | |||
| *> matrices. | |||
| *> | |||
| *> The bounded Bunch-Kaufman ("rook") diagonal pivoting method is used | |||
| *> to factor A as | |||
| *> A = U * D * U**T, if UPLO = 'U', or | |||
| *> A = L * D * L**T, if UPLO = 'L', | |||
| *> where U (or L) is a product of permutation and unit upper (lower) | |||
| *> triangular matrices, and D is Hermitian and block diagonal with | |||
| *> 1-by-1 and 2-by-2 diagonal blocks. | |||
| *> | |||
| *> CHETRF_ROOK is called to compute the factorization of a complex | |||
| *> Hermition matrix A using the bounded Bunch-Kaufman ("rook") diagonal | |||
| *> pivoting method. | |||
| *> | |||
| *> The factored form of A is then used to solve the system | |||
| *> of equations A * X = B by calling CHETRS_ROOK (uses BLAS 2). | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] UPLO | |||
| *> \verbatim | |||
| *> UPLO is CHARACTER*1 | |||
| *> = 'U': Upper triangle of A is stored; | |||
| *> = 'L': Lower triangle of A is stored. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] N | |||
| *> \verbatim | |||
| *> N is INTEGER | |||
| *> The number of linear equations, i.e., the order of the | |||
| *> matrix A. N >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] NRHS | |||
| *> \verbatim | |||
| *> NRHS is INTEGER | |||
| *> The number of right hand sides, i.e., the number of columns | |||
| *> of the matrix B. NRHS >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] A | |||
| *> \verbatim | |||
| *> A is COMPLEX array, dimension (LDA,N) | |||
| *> On entry, the Hermitian 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 | |||
| *> triangular part of A is not referenced. If UPLO = 'L', the | |||
| *> leading N-by-N lower triangular part of A contains the lower | |||
| *> triangular part of the matrix A, and the strictly upper | |||
| *> triangular part of A is not referenced. | |||
| *> | |||
| *> On exit, if INFO = 0, the block diagonal matrix D and the | |||
| *> multipliers used to obtain the factor U or L from the | |||
| *> factorization A = U*D*U**H or A = L*D*L**H as computed by | |||
| *> CHETRF_ROOK. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDA | |||
| *> \verbatim | |||
| *> LDA is INTEGER | |||
| *> The leading dimension of the array A. LDA >= max(1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] IPIV | |||
| *> \verbatim | |||
| *> IPIV is INTEGER array, dimension (N) | |||
| *> Details of the interchanges and the block structure of D. | |||
| *> | |||
| *> If UPLO = 'U': | |||
| *> Only the last KB elements of IPIV are set. | |||
| *> | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) were | |||
| *> interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) < 0 and IPIV(k-1) < 0, then rows and | |||
| *> columns k and -IPIV(k) were interchanged and rows and | |||
| *> columns k-1 and -IPIV(k-1) were inerchaged, | |||
| *> D(k-1:k,k-1:k) is a 2-by-2 diagonal block. | |||
| *> | |||
| *> If UPLO = 'L': | |||
| *> Only the first KB elements of IPIV are set. | |||
| *> | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) | |||
| *> were interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) < 0 and IPIV(k+1) < 0, then rows and | |||
| *> columns k and -IPIV(k) were interchanged and rows and | |||
| *> columns k+1 and -IPIV(k+1) were inerchaged, | |||
| *> D(k:k+1,k:k+1) is a 2-by-2 diagonal block. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] B | |||
| *> \verbatim | |||
| *> B is COMPLEX array, dimension (LDB,NRHS) | |||
| *> On entry, the N-by-NRHS right hand side matrix B. | |||
| *> On exit, if INFO = 0, the N-by-NRHS solution matrix X. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDB | |||
| *> \verbatim | |||
| *> LDB is INTEGER | |||
| *> The leading dimension of the array B. LDB >= max(1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] WORK | |||
| *> \verbatim | |||
| *> WORK is COMPLEX array, dimension (MAX(1,LWORK)) | |||
| *> On exit, if INFO = 0, WORK(1) returns the optimal LWORK. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LWORK | |||
| *> \verbatim | |||
| *> LWORK is INTEGER | |||
| *> The length of WORK. LWORK >= 1, and for best performance | |||
| *> LWORK >= max(1,N*NB), where NB is the optimal blocksize for | |||
| *> CHETRF_ROOK. | |||
| *> for LWORK < N, TRS will be done with Level BLAS 2 | |||
| *> for LWORK >= N, TRS will be done with Level BLAS 3 | |||
| *> | |||
| *> 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 | |||
| *> > 0: if INFO = i, D(i,i) is exactly zero. The factorization | |||
| *> has been completed, but the block diagonal matrix D is | |||
| *> exactly singular, so the solution could not be computed. | |||
| *> \endverbatim | |||
| * | |||
| * Authors: | |||
| * ======== | |||
| * | |||
| *> \author Univ. of Tennessee | |||
| *> \author Univ. of California Berkeley | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup complexHEsolve | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> November 2013, Igor Kozachenko, | |||
| *> Computer Science Division, | |||
| *> University of California, Berkeley | |||
| *> | |||
| *> September 2007, Sven Hammarling, Nicholas J. Higham, Craig Lucas, | |||
| *> School of Mathematics, | |||
| *> University of Manchester | |||
| *> | |||
| *> \endverbatim | |||
| * | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE CHESV_ROOK( UPLO, N, NRHS, A, LDA, IPIV, B, LDB, WORK, | |||
| $ LWORK, INFO ) | |||
| * | |||
| * -- LAPACK driver routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER UPLO | |||
| INTEGER INFO, LDA, LDB, LWORK, N, NRHS | |||
| * .. | |||
| * .. Array Arguments .. | |||
| INTEGER IPIV( * ) | |||
| COMPLEX A( LDA, * ), B( LDB, * ), WORK( * ) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Local Scalars .. | |||
| LOGICAL LQUERY | |||
| INTEGER LWKOPT, NB | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| INTEGER ILAENV | |||
| EXTERNAL LSAME, ILAENV | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL XERBLA, CHETRF_ROOK, CHETRS_ROOK | |||
| * .. | |||
| * .. Intrinsic Functions .. | |||
| INTRINSIC MAX | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Test the input parameters. | |||
| * | |||
| INFO = 0 | |||
| LQUERY = ( LWORK.EQ.-1 ) | |||
| IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN | |||
| INFO = -1 | |||
| ELSE IF( N.LT.0 ) THEN | |||
| INFO = -2 | |||
| ELSE IF( NRHS.LT.0 ) THEN | |||
| INFO = -3 | |||
| ELSE IF( LDA.LT.MAX( 1, N ) ) THEN | |||
| INFO = -5 | |||
| ELSE IF( LDB.LT.MAX( 1, N ) ) THEN | |||
| INFO = -8 | |||
| ELSE IF( LWORK.LT.1 .AND. .NOT.LQUERY ) THEN | |||
| INFO = -10 | |||
| END IF | |||
| * | |||
| IF( INFO.EQ.0 ) THEN | |||
| IF( N.EQ.0 ) THEN | |||
| LWKOPT = 1 | |||
| ELSE | |||
| NB = ILAENV( 1, 'CHETRF_ROOK', UPLO, N, -1, -1, -1 ) | |||
| LWKOPT = N*NB | |||
| END IF | |||
| WORK( 1 ) = LWKOPT | |||
| END IF | |||
| * | |||
| IF( INFO.NE.0 ) THEN | |||
| CALL XERBLA( 'CHESV_ROOK ', -INFO ) | |||
| RETURN | |||
| ELSE IF( LQUERY ) THEN | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Compute the factorization A = U*D*U**H or A = L*D*L**H. | |||
| * | |||
| CALL CHETRF_ROOK( UPLO, N, A, LDA, IPIV, WORK, LWORK, INFO ) | |||
| IF( INFO.EQ.0 ) THEN | |||
| * | |||
| * Solve the system A*X = B, overwriting B with X. | |||
| * | |||
| * Solve with TRS ( Use Level BLAS 2) | |||
| * | |||
| CALL CHETRS_ROOK( UPLO, N, NRHS, A, LDA, IPIV, B, LDB, INFO ) | |||
| * | |||
| END IF | |||
| * | |||
| WORK( 1 ) = LWKOPT | |||
| * | |||
| RETURN | |||
| * | |||
| * End of CHESV_ROOK | |||
| * | |||
| END | |||
| @@ -1,4 +1,4 @@ | |||
| *> \brief \b CHETF2 computes the factorization of a complex Hermitian matrix, using the diagonal pivoting method (unblocked algorithm). | |||
| *> \brief \b CHETF2 computes the factorization of a complex Hermitian matrix, using the diagonal pivoting method (unblocked algorithm calling Level 2 BLAS). | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| @@ -90,13 +90,22 @@ | |||
| *> \verbatim | |||
| *> IPIV is INTEGER array, dimension (N) | |||
| *> Details of the interchanges and the block structure of D. | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) were | |||
| *> interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> If UPLO = 'U' and IPIV(k) = IPIV(k-1) < 0, then rows and | |||
| *> columns k-1 and -IPIV(k) were interchanged and D(k-1:k,k-1:k) | |||
| *> is a 2-by-2 diagonal block. If UPLO = 'L' and IPIV(k) = | |||
| *> IPIV(k+1) < 0, then rows and columns k+1 and -IPIV(k) were | |||
| *> interchanged and D(k:k+1,k:k+1) is a 2-by-2 diagonal block. | |||
| *> | |||
| *> If UPLO = 'U': | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) were | |||
| *> interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) = IPIV(k-1) < 0, then rows and columns | |||
| *> k-1 and -IPIV(k) were interchanged and D(k-1:k,k-1:k) | |||
| *> is a 2-by-2 diagonal block. | |||
| *> | |||
| *> If UPLO = 'L': | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) were | |||
| *> interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) = IPIV(k+1) < 0, then rows and columns | |||
| *> k+1 and -IPIV(k) were interchanged and D(k:k+1,k:k+1) | |||
| *> is a 2-by-2 diagonal block. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] INFO | |||
| @@ -118,7 +127,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date September 2012 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup complexHEcomputational | |||
| * | |||
| @@ -177,10 +186,10 @@ | |||
| * ===================================================================== | |||
| SUBROUTINE CHETF2( UPLO, N, A, LDA, IPIV, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.2) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * September 2012 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER UPLO | |||
| @@ -268,7 +277,8 @@ | |||
| ABSAKK = ABS( REAL( A( K, K ) ) ) | |||
| * | |||
| * IMAX is the row-index of the largest off-diagonal element in | |||
| * column K, and COLMAX is its absolute value | |||
| * column K, and COLMAX is its absolute value. | |||
| * Determine both COLMAX and IMAX. | |||
| * | |||
| IF( K.GT.1 ) THEN | |||
| IMAX = ICAMAX( K-1, A( 1, K ), 1 ) | |||
| @@ -279,7 +289,8 @@ | |||
| * | |||
| IF( (MAX( ABSAKK, COLMAX ).EQ.ZERO) .OR. SISNAN(ABSAKK) ) THEN | |||
| * | |||
| * Column K is zero or contains a NaN: set INFO and continue | |||
| * Column K is or underflow, or contains a NaN: | |||
| * set INFO and continue | |||
| * | |||
| IF( INFO.EQ.0 ) | |||
| $ INFO = K | |||
| @@ -450,7 +461,8 @@ | |||
| ABSAKK = ABS( REAL( A( K, K ) ) ) | |||
| * | |||
| * IMAX is the row-index of the largest off-diagonal element in | |||
| * column K, and COLMAX is its absolute value | |||
| * column K, and COLMAX is its absolute value. | |||
| * Determine both COLMAX and IMAX. | |||
| * | |||
| IF( K.LT.N ) THEN | |||
| IMAX = K + ICAMAX( N-K, A( K+1, K ), 1 ) | |||
| @@ -461,7 +473,8 @@ | |||
| * | |||
| IF( (MAX( ABSAKK, COLMAX ).EQ.ZERO) .OR. SISNAN(ABSAKK) ) THEN | |||
| * | |||
| * Column K is zero or contains a NaN: set INFO and continue | |||
| * Column K is zero or underflow, contains a NaN: | |||
| * set INFO and continue | |||
| * | |||
| IF( INFO.EQ.0 ) | |||
| $ INFO = K | |||
| @@ -0,0 +1,910 @@ | |||
| *> \brief \b CHETF2_ROOK computes the factorization of a complex Hermitian indefinite matrix using the bounded Bunch-Kaufman ("rook") diagonal pivoting method (unblocked algorithm). | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download CHETF2_ROOK + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/chetf2_rook.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/chetf2_rook.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/chetf2_rook.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE CHETF2_ROOK( UPLO, N, A, LDA, IPIV, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * CHARACTER UPLO | |||
| * INTEGER INFO, LDA, N | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * INTEGER IPIV( * ) | |||
| * COMPLEX A( LDA, * ) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| * ============= | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> CHETF2_ROOK computes the factorization of a complex Hermitian matrix A | |||
| *> using the bounded Bunch-Kaufman ("rook") diagonal pivoting method: | |||
| *> | |||
| *> A = U*D*U**H or A = L*D*L**H | |||
| *> | |||
| *> where U (or L) is a product of permutation and unit upper (lower) | |||
| *> triangular matrices, U**H is the conjugate transpose of U, and D is | |||
| *> Hermitian and block diagonal with 1-by-1 and 2-by-2 diagonal blocks. | |||
| *> | |||
| *> This is the unblocked version of the algorithm, calling Level 2 BLAS. | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] UPLO | |||
| *> \verbatim | |||
| *> UPLO is CHARACTER*1 | |||
| *> Specifies whether the upper or lower triangular part of the | |||
| *> Hermitian matrix A is stored: | |||
| *> = 'U': Upper triangular | |||
| *> = 'L': Lower triangular | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] N | |||
| *> \verbatim | |||
| *> N is INTEGER | |||
| *> The order of the matrix A. N >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] A | |||
| *> \verbatim | |||
| *> A is COMPLEX array, dimension (LDA,N) | |||
| *> On entry, the Hermitian 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 | |||
| *> triangular part of A is not referenced. If UPLO = 'L', the | |||
| *> leading n-by-n lower triangular part of A contains the lower | |||
| *> triangular part of the matrix A, and the strictly upper | |||
| *> triangular part of A is not referenced. | |||
| *> | |||
| *> On exit, the block diagonal matrix D and the multipliers used | |||
| *> to obtain the factor U or L (see below for further details). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDA | |||
| *> \verbatim | |||
| *> LDA is INTEGER | |||
| *> The leading dimension of the array A. LDA >= max(1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] IPIV | |||
| *> \verbatim | |||
| *> IPIV is INTEGER array, dimension (N) | |||
| *> Details of the interchanges and the block structure of D. | |||
| *> | |||
| *> If UPLO = 'U': | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) were | |||
| *> interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) < 0 and IPIV(k-1) < 0, then rows and | |||
| *> columns k and -IPIV(k) were interchanged and rows and | |||
| *> columns k-1 and -IPIV(k-1) were inerchaged, | |||
| *> D(k-1:k,k-1:k) is a 2-by-2 diagonal block. | |||
| *> | |||
| *> If UPLO = 'L': | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) | |||
| *> were interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) < 0 and IPIV(k+1) < 0, then rows and | |||
| *> columns k and -IPIV(k) were interchanged and rows and | |||
| *> columns k+1 and -IPIV(k+1) were inerchaged, | |||
| *> D(k:k+1,k:k+1) is a 2-by-2 diagonal block. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] INFO | |||
| *> \verbatim | |||
| *> INFO is INTEGER | |||
| *> = 0: successful exit | |||
| *> < 0: if INFO = -k, the k-th argument had an illegal value | |||
| *> > 0: if INFO = k, D(k,k) is exactly zero. The factorization | |||
| *> has been completed, but the block diagonal matrix D is | |||
| *> exactly singular, and division by zero will occur if it | |||
| *> is used to solve a system of equations. | |||
| *> \endverbatim | |||
| * | |||
| * Authors: | |||
| * ======== | |||
| * | |||
| *> \author Univ. of Tennessee | |||
| *> \author Univ. of California Berkeley | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup complexHEcomputational | |||
| * | |||
| *> \par Further Details: | |||
| * ===================== | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> If UPLO = 'U', then A = U*D*U**H, where | |||
| *> U = P(n)*U(n)* ... *P(k)U(k)* ..., | |||
| *> i.e., U is a product of terms P(k)*U(k), where k decreases from n to | |||
| *> 1 in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1 | |||
| *> and 2-by-2 diagonal blocks D(k). P(k) is a permutation matrix as | |||
| *> defined by IPIV(k), and U(k) is a unit upper triangular matrix, such | |||
| *> that if the diagonal block D(k) is of order s (s = 1 or 2), then | |||
| *> | |||
| *> ( I v 0 ) k-s | |||
| *> U(k) = ( 0 I 0 ) s | |||
| *> ( 0 0 I ) n-k | |||
| *> k-s s n-k | |||
| *> | |||
| *> If s = 1, D(k) overwrites A(k,k), and v overwrites A(1:k-1,k). | |||
| *> If s = 2, the upper triangle of D(k) overwrites A(k-1,k-1), A(k-1,k), | |||
| *> and A(k,k), and v overwrites A(1:k-2,k-1:k). | |||
| *> | |||
| *> If UPLO = 'L', then A = L*D*L**H, where | |||
| *> L = P(1)*L(1)* ... *P(k)*L(k)* ..., | |||
| *> i.e., L is a product of terms P(k)*L(k), where k increases from 1 to | |||
| *> n in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1 | |||
| *> and 2-by-2 diagonal blocks D(k). P(k) is a permutation matrix as | |||
| *> defined by IPIV(k), and L(k) is a unit lower triangular matrix, such | |||
| *> that if the diagonal block D(k) is of order s (s = 1 or 2), then | |||
| *> | |||
| *> ( I 0 0 ) k-1 | |||
| *> L(k) = ( 0 I 0 ) s | |||
| *> ( 0 v I ) n-k-s+1 | |||
| *> k-1 s n-k-s+1 | |||
| *> | |||
| *> If s = 1, D(k) overwrites A(k,k), and v overwrites A(k+1:n,k). | |||
| *> If s = 2, the lower triangle of D(k) overwrites A(k,k), A(k+1,k), | |||
| *> and A(k+1,k+1), and v overwrites A(k+2:n,k:k+1). | |||
| *> \endverbatim | |||
| * | |||
| *> \par Contributors: | |||
| * ================== | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> November 2013, Igor Kozachenko, | |||
| *> Computer Science Division, | |||
| *> University of California, Berkeley | |||
| *> | |||
| *> September 2007, Sven Hammarling, Nicholas J. Higham, Craig Lucas, | |||
| *> School of Mathematics, | |||
| *> University of Manchester | |||
| *> | |||
| *> 01-01-96 - Based on modifications by | |||
| *> J. Lewis, Boeing Computer Services Company | |||
| *> A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA | |||
| *> \endverbatim | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE CHETF2_ROOK( UPLO, N, A, LDA, IPIV, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER UPLO | |||
| INTEGER INFO, LDA, N | |||
| * .. | |||
| * .. Array Arguments .. | |||
| INTEGER IPIV( * ) | |||
| COMPLEX A( LDA, * ) | |||
| * .. | |||
| * | |||
| * ====================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| REAL ZERO, ONE | |||
| PARAMETER ( ZERO = 0.0E+0, ONE = 1.0E+0 ) | |||
| REAL EIGHT, SEVTEN | |||
| PARAMETER ( EIGHT = 8.0E+0, SEVTEN = 17.0E+0 ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| LOGICAL DONE, UPPER | |||
| INTEGER I, II, IMAX, ITEMP, J, JMAX, K, KK, KP, KSTEP, | |||
| $ P | |||
| REAL ABSAKK, ALPHA, COLMAX, D, D11, D22, R1, STEMP, | |||
| $ ROWMAX, TT, SFMIN | |||
| COMPLEX D12, D21, T, WK, WKM1, WKP1, Z | |||
| * .. | |||
| * .. External Functions .. | |||
| * | |||
| LOGICAL LSAME | |||
| INTEGER ICAMAX | |||
| REAL SLAMCH, SLAPY2 | |||
| EXTERNAL LSAME, ICAMAX, SLAMCH, SLAPY2 | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL XERBLA, CSSCAL, CHER, CSWAP | |||
| * .. | |||
| * .. Intrinsic Functions .. | |||
| INTRINSIC ABS, AIMAG, CMPLX, CONJG, MAX, REAL, SQRT | |||
| * .. | |||
| * .. Statement Functions .. | |||
| REAL CABS1 | |||
| * .. | |||
| * .. Statement Function definitions .. | |||
| CABS1( Z ) = ABS( REAL( Z ) ) + ABS( AIMAG( Z ) ) | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Test the input parameters. | |||
| * | |||
| INFO = 0 | |||
| UPPER = LSAME( UPLO, 'U' ) | |||
| IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN | |||
| INFO = -1 | |||
| ELSE IF( N.LT.0 ) THEN | |||
| INFO = -2 | |||
| ELSE IF( LDA.LT.MAX( 1, N ) ) THEN | |||
| INFO = -4 | |||
| END IF | |||
| IF( INFO.NE.0 ) THEN | |||
| CALL XERBLA( 'CHETF2_ROOK', -INFO ) | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Initialize ALPHA for use in choosing pivot block size. | |||
| * | |||
| ALPHA = ( ONE+SQRT( SEVTEN ) ) / EIGHT | |||
| * | |||
| * Compute machine safe minimum | |||
| * | |||
| SFMIN = SLAMCH( 'S' ) | |||
| * | |||
| IF( UPPER ) THEN | |||
| * | |||
| * Factorize A as U*D*U**H using the upper triangle of A | |||
| * | |||
| * K is the main loop index, decreasing from N to 1 in steps of | |||
| * 1 or 2 | |||
| * | |||
| K = N | |||
| 10 CONTINUE | |||
| * | |||
| * If K < 1, exit from loop | |||
| * | |||
| IF( K.LT.1 ) | |||
| $ GO TO 70 | |||
| KSTEP = 1 | |||
| P = K | |||
| * | |||
| * Determine rows and columns to be interchanged and whether | |||
| * a 1-by-1 or 2-by-2 pivot block will be used | |||
| * | |||
| ABSAKK = ABS( REAL( A( K, K ) ) ) | |||
| * | |||
| * IMAX is the row-index of the largest off-diagonal element in | |||
| * column K, and COLMAX is its absolute value. | |||
| * Determine both COLMAX and IMAX. | |||
| * | |||
| IF( K.GT.1 ) THEN | |||
| IMAX = ICAMAX( K-1, A( 1, K ), 1 ) | |||
| COLMAX = CABS1( A( IMAX, K ) ) | |||
| ELSE | |||
| COLMAX = ZERO | |||
| END IF | |||
| * | |||
| IF( ( MAX( ABSAKK, COLMAX ).EQ.ZERO ) ) THEN | |||
| * | |||
| * Column K is zero or underflow: set INFO and continue | |||
| * | |||
| IF( INFO.EQ.0 ) | |||
| $ INFO = K | |||
| KP = K | |||
| A( K, K ) = REAL( A( K, K ) ) | |||
| ELSE | |||
| * | |||
| * ============================================================ | |||
| * | |||
| * BEGIN pivot search | |||
| * | |||
| * Case(1) | |||
| * Equivalent to testing for ABSAKK.GE.ALPHA*COLMAX | |||
| * (used to handle NaN and Inf) | |||
| * | |||
| IF( .NOT.( ABSAKK.LT.ALPHA*COLMAX ) ) THEN | |||
| * | |||
| * no interchange, use 1-by-1 pivot block | |||
| * | |||
| KP = K | |||
| * | |||
| ELSE | |||
| * | |||
| DONE = .FALSE. | |||
| * | |||
| * Loop until pivot found | |||
| * | |||
| 12 CONTINUE | |||
| * | |||
| * BEGIN pivot search loop body | |||
| * | |||
| * | |||
| * JMAX is the column-index of the largest off-diagonal | |||
| * element in row IMAX, and ROWMAX is its absolute value. | |||
| * Determine both ROWMAX and JMAX. | |||
| * | |||
| IF( IMAX.NE.K ) THEN | |||
| JMAX = IMAX + ICAMAX( K-IMAX, A( IMAX, IMAX+1 ), | |||
| $ LDA ) | |||
| ROWMAX = CABS1( A( IMAX, JMAX ) ) | |||
| ELSE | |||
| ROWMAX = ZERO | |||
| END IF | |||
| * | |||
| IF( IMAX.GT.1 ) THEN | |||
| ITEMP = ICAMAX( IMAX-1, A( 1, IMAX ), 1 ) | |||
| STEMP = CABS1( A( ITEMP, IMAX ) ) | |||
| IF( STEMP.GT.ROWMAX ) THEN | |||
| ROWMAX = STEMP | |||
| JMAX = ITEMP | |||
| END IF | |||
| END IF | |||
| * | |||
| * Case(2) | |||
| * Equivalent to testing for | |||
| * ABS( REAL( W( IMAX,KW-1 ) ) ).GE.ALPHA*ROWMAX | |||
| * (used to handle NaN and Inf) | |||
| * | |||
| IF( .NOT.( ABS( REAL( A( IMAX, IMAX ) ) ) | |||
| $ .LT.ALPHA*ROWMAX ) ) THEN | |||
| * | |||
| * interchange rows and columns K and IMAX, | |||
| * use 1-by-1 pivot block | |||
| * | |||
| KP = IMAX | |||
| DONE = .TRUE. | |||
| * | |||
| * Case(3) | |||
| * Equivalent to testing for ROWMAX.EQ.COLMAX, | |||
| * (used to handle NaN and Inf) | |||
| * | |||
| ELSE IF( ( P.EQ.JMAX ) .OR. ( ROWMAX.LE.COLMAX ) ) | |||
| $ THEN | |||
| * | |||
| * interchange rows and columns K-1 and IMAX, | |||
| * use 2-by-2 pivot block | |||
| * | |||
| KP = IMAX | |||
| KSTEP = 2 | |||
| DONE = .TRUE. | |||
| * | |||
| * Case(4) | |||
| ELSE | |||
| * | |||
| * Pivot not found: set params and repeat | |||
| * | |||
| P = IMAX | |||
| COLMAX = ROWMAX | |||
| IMAX = JMAX | |||
| END IF | |||
| * | |||
| * END pivot search loop body | |||
| * | |||
| IF( .NOT.DONE ) GOTO 12 | |||
| * | |||
| END IF | |||
| * | |||
| * END pivot search | |||
| * | |||
| * ============================================================ | |||
| * | |||
| * KK is the column of A where pivoting step stopped | |||
| * | |||
| KK = K - KSTEP + 1 | |||
| * | |||
| * For only a 2x2 pivot, interchange rows and columns K and P | |||
| * in the leading submatrix A(1:k,1:k) | |||
| * | |||
| IF( ( KSTEP.EQ.2 ) .AND. ( P.NE.K ) ) THEN | |||
| * (1) Swap columnar parts | |||
| IF( P.GT.1 ) | |||
| $ CALL CSWAP( P-1, A( 1, K ), 1, A( 1, P ), 1 ) | |||
| * (2) Swap and conjugate middle parts | |||
| DO 14 J = P + 1, K - 1 | |||
| T = CONJG( A( J, K ) ) | |||
| A( J, K ) = CONJG( A( P, J ) ) | |||
| A( P, J ) = T | |||
| 14 CONTINUE | |||
| * (3) Swap and conjugate corner elements at row-col interserction | |||
| A( P, K ) = CONJG( A( P, K ) ) | |||
| * (4) Swap diagonal elements at row-col intersection | |||
| R1 = REAL( A( K, K ) ) | |||
| A( K, K ) = REAL( A( P, P ) ) | |||
| A( P, P ) = R1 | |||
| END IF | |||
| * | |||
| * For both 1x1 and 2x2 pivots, interchange rows and | |||
| * columns KK and KP in the leading submatrix A(1:k,1:k) | |||
| * | |||
| IF( KP.NE.KK ) THEN | |||
| * (1) Swap columnar parts | |||
| IF( KP.GT.1 ) | |||
| $ CALL CSWAP( KP-1, A( 1, KK ), 1, A( 1, KP ), 1 ) | |||
| * (2) Swap and conjugate middle parts | |||
| DO 15 J = KP + 1, KK - 1 | |||
| T = CONJG( A( J, KK ) ) | |||
| A( J, KK ) = CONJG( A( KP, J ) ) | |||
| A( KP, J ) = T | |||
| 15 CONTINUE | |||
| * (3) Swap and conjugate corner elements at row-col interserction | |||
| A( KP, KK ) = CONJG( A( KP, KK ) ) | |||
| * (4) Swap diagonal elements at row-col intersection | |||
| R1 = REAL( A( KK, KK ) ) | |||
| A( KK, KK ) = REAL( A( KP, KP ) ) | |||
| A( KP, KP ) = R1 | |||
| * | |||
| IF( KSTEP.EQ.2 ) THEN | |||
| * (*) Make sure that diagonal element of pivot is real | |||
| A( K, K ) = REAL( A( K, K ) ) | |||
| * (5) Swap row elements | |||
| T = A( K-1, K ) | |||
| A( K-1, K ) = A( KP, K ) | |||
| A( KP, K ) = T | |||
| END IF | |||
| ELSE | |||
| * (*) Make sure that diagonal element of pivot is real | |||
| A( K, K ) = REAL( A( K, K ) ) | |||
| IF( KSTEP.EQ.2 ) | |||
| $ A( K-1, K-1 ) = REAL( A( K-1, K-1 ) ) | |||
| END IF | |||
| * | |||
| * Update the leading submatrix | |||
| * | |||
| IF( KSTEP.EQ.1 ) THEN | |||
| * | |||
| * 1-by-1 pivot block D(k): column k now holds | |||
| * | |||
| * W(k) = U(k)*D(k) | |||
| * | |||
| * where U(k) is the k-th column of U | |||
| * | |||
| IF( K.GT.1 ) THEN | |||
| * | |||
| * Perform a rank-1 update of A(1:k-1,1:k-1) and | |||
| * store U(k) in column k | |||
| * | |||
| IF( ABS( REAL( A( K, K ) ) ).GE.SFMIN ) THEN | |||
| * | |||
| * Perform a rank-1 update of A(1:k-1,1:k-1) as | |||
| * A := A - U(k)*D(k)*U(k)**T | |||
| * = A - W(k)*1/D(k)*W(k)**T | |||
| * | |||
| D11 = ONE / REAL( A( K, K ) ) | |||
| CALL CHER( UPLO, K-1, -D11, A( 1, K ), 1, A, LDA ) | |||
| * | |||
| * Store U(k) in column k | |||
| * | |||
| CALL CSSCAL( K-1, D11, A( 1, K ), 1 ) | |||
| ELSE | |||
| * | |||
| * Store L(k) in column K | |||
| * | |||
| D11 = REAL( A( K, K ) ) | |||
| DO 16 II = 1, K - 1 | |||
| A( II, K ) = A( II, K ) / D11 | |||
| 16 CONTINUE | |||
| * | |||
| * Perform a rank-1 update of A(k+1:n,k+1:n) as | |||
| * A := A - U(k)*D(k)*U(k)**T | |||
| * = A - W(k)*(1/D(k))*W(k)**T | |||
| * = A - (W(k)/D(k))*(D(k))*(W(k)/D(K))**T | |||
| * | |||
| CALL CHER( UPLO, K-1, -D11, A( 1, K ), 1, A, LDA ) | |||
| END IF | |||
| END IF | |||
| * | |||
| ELSE | |||
| * | |||
| * 2-by-2 pivot block D(k): columns k and k-1 now hold | |||
| * | |||
| * ( W(k-1) W(k) ) = ( U(k-1) U(k) )*D(k) | |||
| * | |||
| * where U(k) and U(k-1) are the k-th and (k-1)-th columns | |||
| * of U | |||
| * | |||
| * Perform a rank-2 update of A(1:k-2,1:k-2) as | |||
| * | |||
| * A := A - ( U(k-1) U(k) )*D(k)*( U(k-1) U(k) )**T | |||
| * = A - ( ( A(k-1)A(k) )*inv(D(k)) ) * ( A(k-1)A(k) )**T | |||
| * | |||
| * and store L(k) and L(k+1) in columns k and k+1 | |||
| * | |||
| IF( K.GT.2 ) THEN | |||
| * D = |A12| | |||
| D = SLAPY2( REAL( A( K-1, K ) ), | |||
| $ AIMAG( A( K-1, K ) ) ) | |||
| D11 = A( K, K ) / D | |||
| D22 = A( K-1, K-1 ) / D | |||
| D12 = A( K-1, K ) / D | |||
| TT = ONE / ( D11*D22-ONE ) | |||
| * | |||
| DO 30 J = K - 2, 1, -1 | |||
| * | |||
| * Compute D21 * ( W(k)W(k+1) ) * inv(D(k)) for row J | |||
| * | |||
| WKM1 = TT*( D11*A( J, K-1 )-CONJG( D12 )* | |||
| $ A( J, K ) ) | |||
| WK = TT*( D22*A( J, K )-D12*A( J, K-1 ) ) | |||
| * | |||
| * Perform a rank-2 update of A(1:k-2,1:k-2) | |||
| * | |||
| DO 20 I = J, 1, -1 | |||
| A( I, J ) = A( I, J ) - | |||
| $ ( A( I, K ) / D )*CONJG( WK ) - | |||
| $ ( A( I, K-1 ) / D )*CONJG( WKM1 ) | |||
| 20 CONTINUE | |||
| * | |||
| * Store U(k) and U(k-1) in cols k and k-1 for row J | |||
| * | |||
| A( J, K ) = WK / D | |||
| A( J, K-1 ) = WKM1 / D | |||
| * (*) Make sure that diagonal element of pivot is real | |||
| A( J, J ) = CMPLX( REAL( A( J, J ) ), ZERO ) | |||
| * | |||
| 30 CONTINUE | |||
| * | |||
| END IF | |||
| * | |||
| END IF | |||
| * | |||
| END IF | |||
| * | |||
| * Store details of the interchanges in IPIV | |||
| * | |||
| IF( KSTEP.EQ.1 ) THEN | |||
| IPIV( K ) = KP | |||
| ELSE | |||
| IPIV( K ) = -P | |||
| IPIV( K-1 ) = -KP | |||
| END IF | |||
| * | |||
| * Decrease K and return to the start of the main loop | |||
| * | |||
| K = K - KSTEP | |||
| GO TO 10 | |||
| * | |||
| ELSE | |||
| * | |||
| * Factorize A as L*D*L**H using the lower triangle of A | |||
| * | |||
| * K is the main loop index, increasing from 1 to N in steps of | |||
| * 1 or 2 | |||
| * | |||
| K = 1 | |||
| 40 CONTINUE | |||
| * | |||
| * If K > N, exit from loop | |||
| * | |||
| IF( K.GT.N ) | |||
| $ GO TO 70 | |||
| KSTEP = 1 | |||
| P = K | |||
| * | |||
| * Determine rows and columns to be interchanged and whether | |||
| * a 1-by-1 or 2-by-2 pivot block will be used | |||
| * | |||
| ABSAKK = ABS( REAL( A( K, K ) ) ) | |||
| * | |||
| * IMAX is the row-index of the largest off-diagonal element in | |||
| * column K, and COLMAX is its absolute value. | |||
| * Determine both COLMAX and IMAX. | |||
| * | |||
| IF( K.LT.N ) THEN | |||
| IMAX = K + ICAMAX( N-K, A( K+1, K ), 1 ) | |||
| COLMAX = CABS1( A( IMAX, K ) ) | |||
| ELSE | |||
| COLMAX = ZERO | |||
| END IF | |||
| * | |||
| IF( MAX( ABSAKK, COLMAX ).EQ.ZERO ) THEN | |||
| * | |||
| * Column K is zero or underflow: set INFO and continue | |||
| * | |||
| IF( INFO.EQ.0 ) | |||
| $ INFO = K | |||
| KP = K | |||
| A( K, K ) = REAL( A( K, K ) ) | |||
| ELSE | |||
| * | |||
| * ============================================================ | |||
| * | |||
| * BEGIN pivot search | |||
| * | |||
| * Case(1) | |||
| * Equivalent to testing for ABSAKK.GE.ALPHA*COLMAX | |||
| * (used to handle NaN and Inf) | |||
| * | |||
| IF( .NOT.( ABSAKK.LT.ALPHA*COLMAX ) ) THEN | |||
| * | |||
| * no interchange, use 1-by-1 pivot block | |||
| * | |||
| KP = K | |||
| * | |||
| ELSE | |||
| * | |||
| DONE = .FALSE. | |||
| * | |||
| * Loop until pivot found | |||
| * | |||
| 42 CONTINUE | |||
| * | |||
| * BEGIN pivot search loop body | |||
| * | |||
| * | |||
| * JMAX is the column-index of the largest off-diagonal | |||
| * element in row IMAX, and ROWMAX is its absolute value. | |||
| * Determine both ROWMAX and JMAX. | |||
| * | |||
| IF( IMAX.NE.K ) THEN | |||
| JMAX = K - 1 + ICAMAX( IMAX-K, A( IMAX, K ), LDA ) | |||
| ROWMAX = CABS1( A( IMAX, JMAX ) ) | |||
| ELSE | |||
| ROWMAX = ZERO | |||
| END IF | |||
| * | |||
| IF( IMAX.LT.N ) THEN | |||
| ITEMP = IMAX + ICAMAX( N-IMAX, A( IMAX+1, IMAX ), | |||
| $ 1 ) | |||
| STEMP = CABS1( A( ITEMP, IMAX ) ) | |||
| IF( STEMP.GT.ROWMAX ) THEN | |||
| ROWMAX = STEMP | |||
| JMAX = ITEMP | |||
| END IF | |||
| END IF | |||
| * | |||
| * Case(2) | |||
| * Equivalent to testing for | |||
| * ABS( REAL( W( IMAX,KW-1 ) ) ).GE.ALPHA*ROWMAX | |||
| * (used to handle NaN and Inf) | |||
| * | |||
| IF( .NOT.( ABS( REAL( A( IMAX, IMAX ) ) ) | |||
| $ .LT.ALPHA*ROWMAX ) ) THEN | |||
| * | |||
| * interchange rows and columns K and IMAX, | |||
| * use 1-by-1 pivot block | |||
| * | |||
| KP = IMAX | |||
| DONE = .TRUE. | |||
| * | |||
| * Case(3) | |||
| * Equivalent to testing for ROWMAX.EQ.COLMAX, | |||
| * (used to handle NaN and Inf) | |||
| * | |||
| ELSE IF( ( P.EQ.JMAX ) .OR. ( ROWMAX.LE.COLMAX ) ) | |||
| $ THEN | |||
| * | |||
| * interchange rows and columns K+1 and IMAX, | |||
| * use 2-by-2 pivot block | |||
| * | |||
| KP = IMAX | |||
| KSTEP = 2 | |||
| DONE = .TRUE. | |||
| * | |||
| * Case(4) | |||
| ELSE | |||
| * | |||
| * Pivot not found: set params and repeat | |||
| * | |||
| P = IMAX | |||
| COLMAX = ROWMAX | |||
| IMAX = JMAX | |||
| END IF | |||
| * | |||
| * | |||
| * END pivot search loop body | |||
| * | |||
| IF( .NOT.DONE ) GOTO 42 | |||
| * | |||
| END IF | |||
| * | |||
| * END pivot search | |||
| * | |||
| * ============================================================ | |||
| * | |||
| * KK is the column of A where pivoting step stopped | |||
| * | |||
| KK = K + KSTEP - 1 | |||
| * | |||
| * For only a 2x2 pivot, interchange rows and columns K and P | |||
| * in the trailing submatrix A(k:n,k:n) | |||
| * | |||
| IF( ( KSTEP.EQ.2 ) .AND. ( P.NE.K ) ) THEN | |||
| * (1) Swap columnar parts | |||
| IF( P.LT.N ) | |||
| $ CALL CSWAP( N-P, A( P+1, K ), 1, A( P+1, P ), 1 ) | |||
| * (2) Swap and conjugate middle parts | |||
| DO 44 J = K + 1, P - 1 | |||
| T = CONJG( A( J, K ) ) | |||
| A( J, K ) = CONJG( A( P, J ) ) | |||
| A( P, J ) = T | |||
| 44 CONTINUE | |||
| * (3) Swap and conjugate corner elements at row-col interserction | |||
| A( P, K ) = CONJG( A( P, K ) ) | |||
| * (4) Swap diagonal elements at row-col intersection | |||
| R1 = REAL( A( K, K ) ) | |||
| A( K, K ) = REAL( A( P, P ) ) | |||
| A( P, P ) = R1 | |||
| END IF | |||
| * | |||
| * For both 1x1 and 2x2 pivots, interchange rows and | |||
| * columns KK and KP in the trailing submatrix A(k:n,k:n) | |||
| * | |||
| IF( KP.NE.KK ) THEN | |||
| * (1) Swap columnar parts | |||
| IF( KP.LT.N ) | |||
| $ CALL CSWAP( N-KP, A( KP+1, KK ), 1, A( KP+1, KP ), 1 ) | |||
| * (2) Swap and conjugate middle parts | |||
| DO 45 J = KK + 1, KP - 1 | |||
| T = CONJG( A( J, KK ) ) | |||
| A( J, KK ) = CONJG( A( KP, J ) ) | |||
| A( KP, J ) = T | |||
| 45 CONTINUE | |||
| * (3) Swap and conjugate corner elements at row-col interserction | |||
| A( KP, KK ) = CONJG( A( KP, KK ) ) | |||
| * (4) Swap diagonal elements at row-col intersection | |||
| R1 = REAL( A( KK, KK ) ) | |||
| A( KK, KK ) = REAL( A( KP, KP ) ) | |||
| A( KP, KP ) = R1 | |||
| * | |||
| IF( KSTEP.EQ.2 ) THEN | |||
| * (*) Make sure that diagonal element of pivot is real | |||
| A( K, K ) = REAL( A( K, K ) ) | |||
| * (5) Swap row elements | |||
| T = A( K+1, K ) | |||
| A( K+1, K ) = A( KP, K ) | |||
| A( KP, K ) = T | |||
| END IF | |||
| ELSE | |||
| * (*) Make sure that diagonal element of pivot is real | |||
| A( K, K ) = REAL( A( K, K ) ) | |||
| IF( KSTEP.EQ.2 ) | |||
| $ A( K+1, K+1 ) = REAL( A( K+1, K+1 ) ) | |||
| END IF | |||
| * | |||
| * Update the trailing submatrix | |||
| * | |||
| IF( KSTEP.EQ.1 ) THEN | |||
| * | |||
| * 1-by-1 pivot block D(k): column k of A now holds | |||
| * | |||
| * W(k) = L(k)*D(k), | |||
| * | |||
| * where L(k) is the k-th column of L | |||
| * | |||
| IF( K.LT.N ) THEN | |||
| * | |||
| * Perform a rank-1 update of A(k+1:n,k+1:n) and | |||
| * store L(k) in column k | |||
| * | |||
| * Handle division by a small number | |||
| * | |||
| IF( ABS( REAL( A( K, K ) ) ).GE.SFMIN ) THEN | |||
| * | |||
| * Perform a rank-1 update of A(k+1:n,k+1:n) as | |||
| * A := A - L(k)*D(k)*L(k)**T | |||
| * = A - W(k)*(1/D(k))*W(k)**T | |||
| * | |||
| D11 = ONE / REAL( A( K, K ) ) | |||
| CALL CHER( UPLO, N-K, -D11, A( K+1, K ), 1, | |||
| $ A( K+1, K+1 ), LDA ) | |||
| * | |||
| * Store L(k) in column k | |||
| * | |||
| CALL CSSCAL( N-K, D11, A( K+1, K ), 1 ) | |||
| ELSE | |||
| * | |||
| * Store L(k) in column k | |||
| * | |||
| D11 = REAL( A( K, K ) ) | |||
| DO 46 II = K + 1, N | |||
| A( II, K ) = A( II, K ) / D11 | |||
| 46 CONTINUE | |||
| * | |||
| * Perform a rank-1 update of A(k+1:n,k+1:n) as | |||
| * A := A - L(k)*D(k)*L(k)**T | |||
| * = A - W(k)*(1/D(k))*W(k)**T | |||
| * = A - (W(k)/D(k))*(D(k))*(W(k)/D(K))**T | |||
| * | |||
| CALL CHER( UPLO, N-K, -D11, A( K+1, K ), 1, | |||
| $ A( K+1, K+1 ), LDA ) | |||
| END IF | |||
| END IF | |||
| * | |||
| ELSE | |||
| * | |||
| * 2-by-2 pivot block D(k): columns k and k+1 now hold | |||
| * | |||
| * ( W(k) W(k+1) ) = ( L(k) L(k+1) )*D(k) | |||
| * | |||
| * where L(k) and L(k+1) are the k-th and (k+1)-th columns | |||
| * of L | |||
| * | |||
| * | |||
| * Perform a rank-2 update of A(k+2:n,k+2:n) as | |||
| * | |||
| * A := A - ( L(k) L(k+1) ) * D(k) * ( L(k) L(k+1) )**T | |||
| * = A - ( ( A(k)A(k+1) )*inv(D(k) ) * ( A(k)A(k+1) )**T | |||
| * | |||
| * and store L(k) and L(k+1) in columns k and k+1 | |||
| * | |||
| IF( K.LT.N-1 ) THEN | |||
| * D = |A21| | |||
| D = SLAPY2( REAL( A( K+1, K ) ), | |||
| $ AIMAG( A( K+1, K ) ) ) | |||
| D11 = REAL( A( K+1, K+1 ) ) / D | |||
| D22 = REAL( A( K, K ) ) / D | |||
| D21 = A( K+1, K ) / D | |||
| TT = ONE / ( D11*D22-ONE ) | |||
| * | |||
| DO 60 J = K + 2, N | |||
| * | |||
| * Compute D21 * ( W(k)W(k+1) ) * inv(D(k)) for row J | |||
| * | |||
| WK = TT*( D11*A( J, K )-D21*A( J, K+1 ) ) | |||
| WKP1 = TT*( D22*A( J, K+1 )-CONJG( D21 )* | |||
| $ A( J, K ) ) | |||
| * | |||
| * Perform a rank-2 update of A(k+2:n,k+2:n) | |||
| * | |||
| DO 50 I = J, N | |||
| A( I, J ) = A( I, J ) - | |||
| $ ( A( I, K ) / D )*CONJG( WK ) - | |||
| $ ( A( I, K+1 ) / D )*CONJG( WKP1 ) | |||
| 50 CONTINUE | |||
| * | |||
| * Store L(k) and L(k+1) in cols k and k+1 for row J | |||
| * | |||
| A( J, K ) = WK / D | |||
| A( J, K+1 ) = WKP1 / D | |||
| * (*) Make sure that diagonal element of pivot is real | |||
| A( J, J ) = CMPLX( REAL( A( J, J ) ), ZERO ) | |||
| * | |||
| 60 CONTINUE | |||
| * | |||
| END IF | |||
| * | |||
| END IF | |||
| * | |||
| END IF | |||
| * | |||
| * Store details of the interchanges in IPIV | |||
| * | |||
| IF( KSTEP.EQ.1 ) THEN | |||
| IPIV( K ) = KP | |||
| ELSE | |||
| IPIV( K ) = -P | |||
| IPIV( K+1 ) = -KP | |||
| END IF | |||
| * | |||
| * Increase K and return to the start of the main loop | |||
| * | |||
| K = K + KSTEP | |||
| GO TO 40 | |||
| * | |||
| END IF | |||
| * | |||
| 70 CONTINUE | |||
| * | |||
| RETURN | |||
| * | |||
| * End of CHETF2_ROOK | |||
| * | |||
| END | |||
| @@ -0,0 +1,397 @@ | |||
| *> \brief \b CHETRF_ROOK computes the factorization of a complex Hermitian indefinite matrix using the bounded Bunch-Kaufman ("rook") diagonal pivoting method (blocked algorithm, calling Level 3 BLAS). | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download CHETRF_ROOK + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/chetrf_rook.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/chetrf_rook.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/chetrf_rook.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE CHETRF_ROOK( UPLO, N, A, LDA, IPIV, WORK, LWORK, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * CHARACTER UPLO | |||
| * INTEGER INFO, LDA, LWORK, N | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * INTEGER IPIV( * ) | |||
| * COMPLEX A( LDA, * ), WORK( * ) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| * ============= | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> CHETRF_ROOK computes the factorization of a comlex Hermitian matrix A | |||
| *> using the bounded Bunch-Kaufman ("rook") diagonal pivoting method. | |||
| *> The form of the factorization is | |||
| *> | |||
| *> A = U*D*U**T or A = L*D*L**T | |||
| *> | |||
| *> where U (or L) is a product of permutation and unit upper (lower) | |||
| *> triangular matrices, and D is Hermitian and block diagonal with | |||
| *> 1-by-1 and 2-by-2 diagonal blocks. | |||
| *> | |||
| *> This is the blocked version of the algorithm, calling Level 3 BLAS. | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] UPLO | |||
| *> \verbatim | |||
| *> UPLO is CHARACTER*1 | |||
| *> = 'U': Upper triangle of A is stored; | |||
| *> = 'L': Lower triangle of A is stored. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] N | |||
| *> \verbatim | |||
| *> N is INTEGER | |||
| *> The order of the matrix A. N >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] A | |||
| *> \verbatim | |||
| *> A is COMPLEX array, dimension (LDA,N) | |||
| *> On entry, the Hermitian 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 | |||
| *> triangular part of A is not referenced. If UPLO = 'L', the | |||
| *> leading N-by-N lower triangular part of A contains the lower | |||
| *> triangular part of the matrix A, and the strictly upper | |||
| *> triangular part of A is not referenced. | |||
| *> | |||
| *> On exit, the block diagonal matrix D and the multipliers used | |||
| *> to obtain the factor U or L (see below for further details). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDA | |||
| *> \verbatim | |||
| *> LDA is INTEGER | |||
| *> The leading dimension of the array A. LDA >= max(1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] IPIV | |||
| *> \verbatim | |||
| *> IPIV is INTEGER array, dimension (N) | |||
| *> Details of the interchanges and the block structure of D. | |||
| *> | |||
| *> If UPLO = 'U': | |||
| *> Only the last KB elements of IPIV are set. | |||
| *> | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) were | |||
| *> interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) < 0 and IPIV(k-1) < 0, then rows and | |||
| *> columns k and -IPIV(k) were interchanged and rows and | |||
| *> columns k-1 and -IPIV(k-1) were inerchaged, | |||
| *> D(k-1:k,k-1:k) is a 2-by-2 diagonal block. | |||
| *> | |||
| *> If UPLO = 'L': | |||
| *> Only the first KB elements of IPIV are set. | |||
| *> | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) | |||
| *> were interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) < 0 and IPIV(k+1) < 0, then rows and | |||
| *> columns k and -IPIV(k) were interchanged and rows and | |||
| *> columns k+1 and -IPIV(k+1) were inerchaged, | |||
| *> D(k:k+1,k:k+1) is a 2-by-2 diagonal block. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] WORK | |||
| *> \verbatim | |||
| *> WORK is COMPLEX array, dimension (MAX(1,LWORK)). | |||
| *> On exit, if INFO = 0, WORK(1) returns the optimal LWORK. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LWORK | |||
| *> \verbatim | |||
| *> LWORK is INTEGER | |||
| *> The length of WORK. LWORK >=1. For best performance | |||
| *> LWORK >= N*NB, where NB is the block size returned by ILAENV. | |||
| *> | |||
| *> 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 | |||
| *> > 0: if INFO = i, D(i,i) is exactly zero. The factorization | |||
| *> has been completed, but the block diagonal matrix D is | |||
| *> exactly singular, and division by zero will occur if it | |||
| *> is used to solve a system of equations. | |||
| *> \endverbatim | |||
| * | |||
| * Authors: | |||
| * ======== | |||
| * | |||
| *> \author Univ. of Tennessee | |||
| *> \author Univ. of California Berkeley | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup complexHEcomputational | |||
| * | |||
| *> \par Further Details: | |||
| * ===================== | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> If UPLO = 'U', then A = U*D*U**T, where | |||
| *> U = P(n)*U(n)* ... *P(k)U(k)* ..., | |||
| *> i.e., U is a product of terms P(k)*U(k), where k decreases from n to | |||
| *> 1 in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1 | |||
| *> and 2-by-2 diagonal blocks D(k). P(k) is a permutation matrix as | |||
| *> defined by IPIV(k), and U(k) is a unit upper triangular matrix, such | |||
| *> that if the diagonal block D(k) is of order s (s = 1 or 2), then | |||
| *> | |||
| *> ( I v 0 ) k-s | |||
| *> U(k) = ( 0 I 0 ) s | |||
| *> ( 0 0 I ) n-k | |||
| *> k-s s n-k | |||
| *> | |||
| *> If s = 1, D(k) overwrites A(k,k), and v overwrites A(1:k-1,k). | |||
| *> If s = 2, the upper triangle of D(k) overwrites A(k-1,k-1), A(k-1,k), | |||
| *> and A(k,k), and v overwrites A(1:k-2,k-1:k). | |||
| *> | |||
| *> If UPLO = 'L', then A = L*D*L**T, where | |||
| *> L = P(1)*L(1)* ... *P(k)*L(k)* ..., | |||
| *> i.e., L is a product of terms P(k)*L(k), where k increases from 1 to | |||
| *> n in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1 | |||
| *> and 2-by-2 diagonal blocks D(k). P(k) is a permutation matrix as | |||
| *> defined by IPIV(k), and L(k) is a unit lower triangular matrix, such | |||
| *> that if the diagonal block D(k) is of order s (s = 1 or 2), then | |||
| *> | |||
| *> ( I 0 0 ) k-1 | |||
| *> L(k) = ( 0 I 0 ) s | |||
| *> ( 0 v I ) n-k-s+1 | |||
| *> k-1 s n-k-s+1 | |||
| *> | |||
| *> If s = 1, D(k) overwrites A(k,k), and v overwrites A(k+1:n,k). | |||
| *> If s = 2, the lower triangle of D(k) overwrites A(k,k), A(k+1,k), | |||
| *> and A(k+1,k+1), and v overwrites A(k+2:n,k:k+1). | |||
| *> \endverbatim | |||
| * | |||
| *> \par Contributors: | |||
| * ================== | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> November 2013, Igor Kozachenko, | |||
| *> Computer Science Division, | |||
| *> University of California, Berkeley | |||
| *> | |||
| *> September 2007, Sven Hammarling, Nicholas J. Higham, Craig Lucas, | |||
| *> School of Mathematics, | |||
| *> University of Manchester | |||
| *> | |||
| *> \endverbatim | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE CHETRF_ROOK( UPLO, N, A, LDA, IPIV, WORK, LWORK, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER UPLO | |||
| INTEGER INFO, LDA, LWORK, N | |||
| * .. | |||
| * .. Array Arguments .. | |||
| INTEGER IPIV( * ) | |||
| COMPLEX A( LDA, * ), WORK( * ) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Local Scalars .. | |||
| LOGICAL LQUERY, UPPER | |||
| INTEGER IINFO, IWS, J, K, KB, LDWORK, LWKOPT, NB, NBMIN | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| INTEGER ILAENV | |||
| EXTERNAL LSAME, ILAENV | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL CLAHEF_ROOK, CHETF2_ROOK, XERBLA | |||
| * .. | |||
| * .. Intrinsic Functions .. | |||
| INTRINSIC MAX | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Test the input parameters. | |||
| * | |||
| INFO = 0 | |||
| UPPER = LSAME( UPLO, 'U' ) | |||
| LQUERY = ( LWORK.EQ.-1 ) | |||
| IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN | |||
| INFO = -1 | |||
| ELSE IF( N.LT.0 ) THEN | |||
| INFO = -2 | |||
| ELSE IF( LDA.LT.MAX( 1, N ) ) THEN | |||
| INFO = -4 | |||
| ELSE IF( LWORK.LT.1 .AND. .NOT.LQUERY ) THEN | |||
| INFO = -7 | |||
| END IF | |||
| * | |||
| IF( INFO.EQ.0 ) THEN | |||
| * | |||
| * Determine the block size | |||
| * | |||
| NB = ILAENV( 1, 'CHETRF_ROOK', UPLO, N, -1, -1, -1 ) | |||
| LWKOPT = N*NB | |||
| WORK( 1 ) = LWKOPT | |||
| END IF | |||
| * | |||
| IF( INFO.NE.0 ) THEN | |||
| CALL XERBLA( 'CHETRF_ROOK', -INFO ) | |||
| RETURN | |||
| ELSE IF( LQUERY ) THEN | |||
| RETURN | |||
| END IF | |||
| * | |||
| NBMIN = 2 | |||
| LDWORK = N | |||
| IF( NB.GT.1 .AND. NB.LT.N ) THEN | |||
| IWS = LDWORK*NB | |||
| IF( LWORK.LT.IWS ) THEN | |||
| NB = MAX( LWORK / LDWORK, 1 ) | |||
| NBMIN = MAX( 2, ILAENV( 2, 'CHETRF_ROOK', | |||
| $ UPLO, N, -1, -1, -1 ) ) | |||
| END IF | |||
| ELSE | |||
| IWS = 1 | |||
| END IF | |||
| IF( NB.LT.NBMIN ) | |||
| $ NB = N | |||
| * | |||
| IF( UPPER ) THEN | |||
| * | |||
| * Factorize A as U*D*U**T using the upper triangle of A | |||
| * | |||
| * K is the main loop index, decreasing from N to 1 in steps of | |||
| * KB, where KB is the number of columns factorized by CLAHEF_ROOK; | |||
| * KB is either NB or NB-1, or K for the last block | |||
| * | |||
| K = N | |||
| 10 CONTINUE | |||
| * | |||
| * If K < 1, exit from loop | |||
| * | |||
| IF( K.LT.1 ) | |||
| $ GO TO 40 | |||
| * | |||
| IF( K.GT.NB ) THEN | |||
| * | |||
| * Factorize columns k-kb+1:k of A and use blocked code to | |||
| * update columns 1:k-kb | |||
| * | |||
| CALL CLAHEF_ROOK( UPLO, K, NB, KB, A, LDA, | |||
| $ IPIV, WORK, LDWORK, IINFO ) | |||
| ELSE | |||
| * | |||
| * Use unblocked code to factorize columns 1:k of A | |||
| * | |||
| CALL CHETF2_ROOK( UPLO, K, A, LDA, IPIV, IINFO ) | |||
| KB = K | |||
| END IF | |||
| * | |||
| * Set INFO on the first occurrence of a zero pivot | |||
| * | |||
| IF( INFO.EQ.0 .AND. IINFO.GT.0 ) | |||
| $ INFO = IINFO | |||
| * | |||
| * No need to adjust IPIV | |||
| * | |||
| * Decrease K and return to the start of the main loop | |||
| * | |||
| K = K - KB | |||
| GO TO 10 | |||
| * | |||
| ELSE | |||
| * | |||
| * Factorize A as L*D*L**T using the lower triangle of A | |||
| * | |||
| * K is the main loop index, increasing from 1 to N in steps of | |||
| * KB, where KB is the number of columns factorized by CLAHEF_ROOK; | |||
| * KB is either NB or NB-1, or N-K+1 for the last block | |||
| * | |||
| K = 1 | |||
| 20 CONTINUE | |||
| * | |||
| * If K > N, exit from loop | |||
| * | |||
| IF( K.GT.N ) | |||
| $ GO TO 40 | |||
| * | |||
| IF( K.LE.N-NB ) THEN | |||
| * | |||
| * Factorize columns k:k+kb-1 of A and use blocked code to | |||
| * update columns k+kb:n | |||
| * | |||
| CALL CLAHEF_ROOK( UPLO, N-K+1, NB, KB, A( K, K ), LDA, | |||
| $ IPIV( K ), WORK, LDWORK, IINFO ) | |||
| ELSE | |||
| * | |||
| * Use unblocked code to factorize columns k:n of A | |||
| * | |||
| CALL CHETF2_ROOK( UPLO, N-K+1, A( K, K ), LDA, IPIV( K ), | |||
| $ IINFO ) | |||
| KB = N - K + 1 | |||
| END IF | |||
| * | |||
| * Set INFO on the first occurrence of a zero pivot | |||
| * | |||
| IF( INFO.EQ.0 .AND. IINFO.GT.0 ) | |||
| $ INFO = IINFO + K - 1 | |||
| * | |||
| * Adjust IPIV | |||
| * | |||
| DO 30 J = K, K + KB - 1 | |||
| IF( IPIV( J ).GT.0 ) THEN | |||
| IPIV( J ) = IPIV( J ) + K - 1 | |||
| ELSE | |||
| IPIV( J ) = IPIV( J ) - K + 1 | |||
| END IF | |||
| 30 CONTINUE | |||
| * | |||
| * Increase K and return to the start of the main loop | |||
| * | |||
| K = K + KB | |||
| GO TO 20 | |||
| * | |||
| END IF | |||
| * | |||
| 40 CONTINUE | |||
| WORK( 1 ) = LWKOPT | |||
| RETURN | |||
| * | |||
| * End of CHETRF_ROOK | |||
| * | |||
| END | |||
| @@ -0,0 +1,516 @@ | |||
| *> \brief \b CHETRI_ROOK computes the inverse of HE matrix using the factorization obtained with the bounded Bunch-Kaufman ("rook") diagonal pivoting method. | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download CHETRI_ROOK + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/chetri_rook.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/chetri_rook.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/chetri_rook.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE CHETRI_ROOK( UPLO, N, A, LDA, IPIV, WORK, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * CHARACTER UPLO | |||
| * INTEGER INFO, LDA, N | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * INTEGER IPIV( * ) | |||
| * COMPLEX A( LDA, * ), WORK( * ) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| * ============= | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> CHETRI_ROOK computes the inverse of a complex Hermitian indefinite matrix | |||
| *> A using the factorization A = U*D*U**H or A = L*D*L**H computed by | |||
| *> CHETRF_ROOK. | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] UPLO | |||
| *> \verbatim | |||
| *> UPLO is CHARACTER*1 | |||
| *> Specifies whether the details of the factorization are stored | |||
| *> as an upper or lower triangular matrix. | |||
| *> = 'U': Upper triangular, form is A = U*D*U**H; | |||
| *> = 'L': Lower triangular, form is A = L*D*L**H. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] N | |||
| *> \verbatim | |||
| *> N is INTEGER | |||
| *> The order of the matrix A. N >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] A | |||
| *> \verbatim | |||
| *> A is COMPLEX array, dimension (LDA,N) | |||
| *> On entry, the block diagonal matrix D and the multipliers | |||
| *> used to obtain the factor U or L as computed by CHETRF_ROOK. | |||
| *> | |||
| *> On exit, if INFO = 0, the (Hermitian) inverse of the original | |||
| *> matrix. If UPLO = 'U', the upper triangular part of the | |||
| *> inverse is formed and the part of A below the diagonal is not | |||
| *> referenced; if UPLO = 'L' the lower triangular part of the | |||
| *> inverse is formed and the part of A above the diagonal is | |||
| *> not referenced. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDA | |||
| *> \verbatim | |||
| *> LDA is INTEGER | |||
| *> The leading dimension of the array A. LDA >= max(1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] IPIV | |||
| *> \verbatim | |||
| *> IPIV is INTEGER array, dimension (N) | |||
| *> Details of the interchanges and the block structure of D | |||
| *> as determined by CHETRF_ROOK. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] WORK | |||
| *> \verbatim | |||
| *> WORK is COMPLEX array, dimension (N) | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] INFO | |||
| *> \verbatim | |||
| *> INFO is INTEGER | |||
| *> = 0: successful exit | |||
| *> < 0: if INFO = -i, the i-th argument had an illegal value | |||
| *> > 0: if INFO = i, D(i,i) = 0; the matrix is singular and its | |||
| *> inverse could not be computed. | |||
| *> \endverbatim | |||
| * | |||
| * Authors: | |||
| * ======== | |||
| * | |||
| *> \author Univ. of Tennessee | |||
| *> \author Univ. of California Berkeley | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup complexHEcomputational | |||
| * | |||
| *> \par Contributors: | |||
| * ================== | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> November 2013, Igor Kozachenko, | |||
| *> Computer Science Division, | |||
| *> University of California, Berkeley | |||
| *> | |||
| *> September 2007, Sven Hammarling, Nicholas J. Higham, Craig Lucas, | |||
| *> School of Mathematics, | |||
| *> University of Manchester | |||
| *> \endverbatim | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE CHETRI_ROOK( UPLO, N, A, LDA, IPIV, WORK, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER UPLO | |||
| INTEGER INFO, LDA, N | |||
| * .. | |||
| * .. Array Arguments .. | |||
| INTEGER IPIV( * ) | |||
| COMPLEX A( LDA, * ), WORK( * ) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| REAL ONE | |||
| COMPLEX CONE, CZERO | |||
| PARAMETER ( ONE = 1.0E+0, CONE = ( 1.0E+0, 0.0E+0 ), | |||
| $ CZERO = ( 0.0E+0, 0.0E+0 ) ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| LOGICAL UPPER | |||
| INTEGER J, K, KP, KSTEP | |||
| REAL AK, AKP1, D, T | |||
| COMPLEX AKKP1, TEMP | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| COMPLEX CDOTC | |||
| EXTERNAL LSAME, CDOTC | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL CCOPY, CHEMV, CSWAP, XERBLA | |||
| * .. | |||
| * .. Intrinsic Functions .. | |||
| INTRINSIC ABS, CONJG, MAX, REAL | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Test the input parameters. | |||
| * | |||
| INFO = 0 | |||
| UPPER = LSAME( UPLO, 'U' ) | |||
| IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN | |||
| INFO = -1 | |||
| ELSE IF( N.LT.0 ) THEN | |||
| INFO = -2 | |||
| ELSE IF( LDA.LT.MAX( 1, N ) ) THEN | |||
| INFO = -4 | |||
| END IF | |||
| IF( INFO.NE.0 ) THEN | |||
| CALL XERBLA( 'CHETRI_ROOK', -INFO ) | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Quick return if possible | |||
| * | |||
| IF( N.EQ.0 ) | |||
| $ RETURN | |||
| * | |||
| * Check that the diagonal matrix D is nonsingular. | |||
| * | |||
| IF( UPPER ) THEN | |||
| * | |||
| * Upper triangular storage: examine D from bottom to top | |||
| * | |||
| DO 10 INFO = N, 1, -1 | |||
| IF( IPIV( INFO ).GT.0 .AND. A( INFO, INFO ).EQ.CZERO ) | |||
| $ RETURN | |||
| 10 CONTINUE | |||
| ELSE | |||
| * | |||
| * Lower triangular storage: examine D from top to bottom. | |||
| * | |||
| DO 20 INFO = 1, N | |||
| IF( IPIV( INFO ).GT.0 .AND. A( INFO, INFO ).EQ.CZERO ) | |||
| $ RETURN | |||
| 20 CONTINUE | |||
| END IF | |||
| INFO = 0 | |||
| * | |||
| IF( UPPER ) THEN | |||
| * | |||
| * Compute inv(A) from the factorization A = U*D*U**H. | |||
| * | |||
| * K is the main loop index, increasing from 1 to N in steps of | |||
| * 1 or 2, depending on the size of the diagonal blocks. | |||
| * | |||
| K = 1 | |||
| 30 CONTINUE | |||
| * | |||
| * If K > N, exit from loop. | |||
| * | |||
| IF( K.GT.N ) | |||
| $ GO TO 70 | |||
| * | |||
| IF( IPIV( K ).GT.0 ) THEN | |||
| * | |||
| * 1 x 1 diagonal block | |||
| * | |||
| * Invert the diagonal block. | |||
| * | |||
| A( K, K ) = ONE / REAL( A( K, K ) ) | |||
| * | |||
| * Compute column K of the inverse. | |||
| * | |||
| IF( K.GT.1 ) THEN | |||
| CALL CCOPY( K-1, A( 1, K ), 1, WORK, 1 ) | |||
| CALL CHEMV( UPLO, K-1, -CONE, A, LDA, WORK, 1, CZERO, | |||
| $ A( 1, K ), 1 ) | |||
| A( K, K ) = A( K, K ) - REAL( CDOTC( K-1, WORK, 1, A( 1, | |||
| $ K ), 1 ) ) | |||
| END IF | |||
| KSTEP = 1 | |||
| ELSE | |||
| * | |||
| * 2 x 2 diagonal block | |||
| * | |||
| * Invert the diagonal block. | |||
| * | |||
| T = ABS( A( K, K+1 ) ) | |||
| AK = REAL( A( K, K ) ) / T | |||
| AKP1 = REAL( A( K+1, K+1 ) ) / T | |||
| AKKP1 = A( K, K+1 ) / T | |||
| D = T*( AK*AKP1-ONE ) | |||
| A( K, K ) = AKP1 / D | |||
| A( K+1, K+1 ) = AK / D | |||
| A( K, K+1 ) = -AKKP1 / D | |||
| * | |||
| * Compute columns K and K+1 of the inverse. | |||
| * | |||
| IF( K.GT.1 ) THEN | |||
| CALL CCOPY( K-1, A( 1, K ), 1, WORK, 1 ) | |||
| CALL CHEMV( UPLO, K-1, -CONE, A, LDA, WORK, 1, CZERO, | |||
| $ A( 1, K ), 1 ) | |||
| A( K, K ) = A( K, K ) - REAL( CDOTC( K-1, WORK, 1, A( 1, | |||
| $ K ), 1 ) ) | |||
| A( K, K+1 ) = A( K, K+1 ) - | |||
| $ CDOTC( K-1, A( 1, K ), 1, A( 1, K+1 ), 1 ) | |||
| CALL CCOPY( K-1, A( 1, K+1 ), 1, WORK, 1 ) | |||
| CALL CHEMV( UPLO, K-1, -CONE, A, LDA, WORK, 1, CZERO, | |||
| $ A( 1, K+1 ), 1 ) | |||
| A( K+1, K+1 ) = A( K+1, K+1 ) - | |||
| $ REAL( CDOTC( K-1, WORK, 1, A( 1, K+1 ), | |||
| $ 1 ) ) | |||
| END IF | |||
| KSTEP = 2 | |||
| END IF | |||
| * | |||
| IF( KSTEP.EQ.1 ) THEN | |||
| * | |||
| * Interchange rows and columns K and IPIV(K) in the leading | |||
| * submatrix A(1:k,1:k) | |||
| * | |||
| KP = IPIV( K ) | |||
| IF( KP.NE.K ) THEN | |||
| * | |||
| IF( KP.GT.1 ) | |||
| $ CALL CSWAP( KP-1, A( 1, K ), 1, A( 1, KP ), 1 ) | |||
| * | |||
| DO 40 J = KP + 1, K - 1 | |||
| TEMP = CONJG( A( J, K ) ) | |||
| A( J, K ) = CONJG( A( KP, J ) ) | |||
| A( KP, J ) = TEMP | |||
| 40 CONTINUE | |||
| * | |||
| A( KP, K ) = CONJG( A( KP, K ) ) | |||
| * | |||
| TEMP = A( K, K ) | |||
| A( K, K ) = A( KP, KP ) | |||
| A( KP, KP ) = TEMP | |||
| END IF | |||
| ELSE | |||
| * | |||
| * Interchange rows and columns K and K+1 with -IPIV(K) and | |||
| * -IPIV(K+1) in the leading submatrix A(k+1:n,k+1:n) | |||
| * | |||
| * (1) Interchange rows and columns K and -IPIV(K) | |||
| * | |||
| KP = -IPIV( K ) | |||
| IF( KP.NE.K ) THEN | |||
| * | |||
| IF( KP.GT.1 ) | |||
| $ CALL CSWAP( KP-1, A( 1, K ), 1, A( 1, KP ), 1 ) | |||
| * | |||
| DO 50 J = KP + 1, K - 1 | |||
| TEMP = CONJG( A( J, K ) ) | |||
| A( J, K ) = CONJG( A( KP, J ) ) | |||
| A( KP, J ) = TEMP | |||
| 50 CONTINUE | |||
| * | |||
| A( KP, K ) = CONJG( A( KP, K ) ) | |||
| * | |||
| TEMP = A( K, K ) | |||
| A( K, K ) = A( KP, KP ) | |||
| A( KP, KP ) = TEMP | |||
| * | |||
| TEMP = A( K, K+1 ) | |||
| A( K, K+1 ) = A( KP, K+1 ) | |||
| A( KP, K+1 ) = TEMP | |||
| END IF | |||
| * | |||
| * (2) Interchange rows and columns K+1 and -IPIV(K+1) | |||
| * | |||
| K = K + 1 | |||
| KP = -IPIV( K ) | |||
| IF( KP.NE.K ) THEN | |||
| * | |||
| IF( KP.GT.1 ) | |||
| $ CALL CSWAP( KP-1, A( 1, K ), 1, A( 1, KP ), 1 ) | |||
| * | |||
| DO 60 J = KP + 1, K - 1 | |||
| TEMP = CONJG( A( J, K ) ) | |||
| A( J, K ) = CONJG( A( KP, J ) ) | |||
| A( KP, J ) = TEMP | |||
| 60 CONTINUE | |||
| * | |||
| A( KP, K ) = CONJG( A( KP, K ) ) | |||
| * | |||
| TEMP = A( K, K ) | |||
| A( K, K ) = A( KP, KP ) | |||
| A( KP, KP ) = TEMP | |||
| END IF | |||
| END IF | |||
| * | |||
| K = K + 1 | |||
| GO TO 30 | |||
| 70 CONTINUE | |||
| * | |||
| ELSE | |||
| * | |||
| * Compute inv(A) from the factorization A = L*D*L**H. | |||
| * | |||
| * K is the main loop index, decreasing from N to 1 in steps of | |||
| * 1 or 2, depending on the size of the diagonal blocks. | |||
| * | |||
| K = N | |||
| 80 CONTINUE | |||
| * | |||
| * If K < 1, exit from loop. | |||
| * | |||
| IF( K.LT.1 ) | |||
| $ GO TO 120 | |||
| * | |||
| IF( IPIV( K ).GT.0 ) THEN | |||
| * | |||
| * 1 x 1 diagonal block | |||
| * | |||
| * Invert the diagonal block. | |||
| * | |||
| A( K, K ) = ONE / REAL( A( K, K ) ) | |||
| * | |||
| * Compute column K of the inverse. | |||
| * | |||
| IF( K.LT.N ) THEN | |||
| CALL CCOPY( N-K, A( K+1, K ), 1, WORK, 1 ) | |||
| CALL CHEMV( UPLO, N-K, -CONE, A( K+1, K+1 ), LDA, WORK, | |||
| $ 1, CZERO, A( K+1, K ), 1 ) | |||
| A( K, K ) = A( K, K ) - REAL( CDOTC( N-K, WORK, 1, | |||
| $ A( K+1, K ), 1 ) ) | |||
| END IF | |||
| KSTEP = 1 | |||
| ELSE | |||
| * | |||
| * 2 x 2 diagonal block | |||
| * | |||
| * Invert the diagonal block. | |||
| * | |||
| T = ABS( A( K, K-1 ) ) | |||
| AK = REAL( A( K-1, K-1 ) ) / T | |||
| AKP1 = REAL( A( K, K ) ) / T | |||
| AKKP1 = A( K, K-1 ) / T | |||
| D = T*( AK*AKP1-ONE ) | |||
| A( K-1, K-1 ) = AKP1 / D | |||
| A( K, K ) = AK / D | |||
| A( K, K-1 ) = -AKKP1 / D | |||
| * | |||
| * Compute columns K-1 and K of the inverse. | |||
| * | |||
| IF( K.LT.N ) THEN | |||
| CALL CCOPY( N-K, A( K+1, K ), 1, WORK, 1 ) | |||
| CALL CHEMV( UPLO, N-K, -CONE, A( K+1, K+1 ), LDA, WORK, | |||
| $ 1, CZERO, A( K+1, K ), 1 ) | |||
| A( K, K ) = A( K, K ) - REAL( CDOTC( N-K, WORK, 1, | |||
| $ A( K+1, K ), 1 ) ) | |||
| A( K, K-1 ) = A( K, K-1 ) - | |||
| $ CDOTC( N-K, A( K+1, K ), 1, A( K+1, K-1 ), | |||
| $ 1 ) | |||
| CALL CCOPY( N-K, A( K+1, K-1 ), 1, WORK, 1 ) | |||
| CALL CHEMV( UPLO, N-K, -CONE, A( K+1, K+1 ), LDA, WORK, | |||
| $ 1, CZERO, A( K+1, K-1 ), 1 ) | |||
| A( K-1, K-1 ) = A( K-1, K-1 ) - | |||
| $ REAL( CDOTC( N-K, WORK, 1, A( K+1, K-1 ), | |||
| $ 1 ) ) | |||
| END IF | |||
| KSTEP = 2 | |||
| END IF | |||
| * | |||
| IF( KSTEP.EQ.1 ) THEN | |||
| * | |||
| * Interchange rows and columns K and IPIV(K) in the trailing | |||
| * submatrix A(k:n,k:n) | |||
| * | |||
| KP = IPIV( K ) | |||
| IF( KP.NE.K ) THEN | |||
| * | |||
| IF( KP.LT.N ) | |||
| $ CALL CSWAP( N-KP, A( KP+1, K ), 1, A( KP+1, KP ), 1 ) | |||
| * | |||
| DO 90 J = K + 1, KP - 1 | |||
| TEMP = CONJG( A( J, K ) ) | |||
| A( J, K ) = CONJG( A( KP, J ) ) | |||
| A( KP, J ) = TEMP | |||
| 90 CONTINUE | |||
| * | |||
| A( KP, K ) = CONJG( A( KP, K ) ) | |||
| * | |||
| TEMP = A( K, K ) | |||
| A( K, K ) = A( KP, KP ) | |||
| A( KP, KP ) = TEMP | |||
| END IF | |||
| ELSE | |||
| * | |||
| * Interchange rows and columns K and K-1 with -IPIV(K) and | |||
| * -IPIV(K-1) in the trailing submatrix A(k-1:n,k-1:n) | |||
| * | |||
| * (1) Interchange rows and columns K and -IPIV(K) | |||
| * | |||
| KP = -IPIV( K ) | |||
| IF( KP.NE.K ) THEN | |||
| * | |||
| IF( KP.LT.N ) | |||
| $ CALL CSWAP( N-KP, A( KP+1, K ), 1, A( KP+1, KP ), 1 ) | |||
| * | |||
| DO 100 J = K + 1, KP - 1 | |||
| TEMP = CONJG( A( J, K ) ) | |||
| A( J, K ) = CONJG( A( KP, J ) ) | |||
| A( KP, J ) = TEMP | |||
| 100 CONTINUE | |||
| * | |||
| A( KP, K ) = CONJG( A( KP, K ) ) | |||
| * | |||
| TEMP = A( K, K ) | |||
| A( K, K ) = A( KP, KP ) | |||
| A( KP, KP ) = TEMP | |||
| * | |||
| TEMP = A( K, K-1 ) | |||
| A( K, K-1 ) = A( KP, K-1 ) | |||
| A( KP, K-1 ) = TEMP | |||
| END IF | |||
| * | |||
| * (2) Interchange rows and columns K-1 and -IPIV(K-1) | |||
| * | |||
| K = K - 1 | |||
| KP = -IPIV( K ) | |||
| IF( KP.NE.K ) THEN | |||
| * | |||
| IF( KP.LT.N ) | |||
| $ CALL CSWAP( N-KP, A( KP+1, K ), 1, A( KP+1, KP ), 1 ) | |||
| * | |||
| DO 110 J = K + 1, KP - 1 | |||
| TEMP = CONJG( A( J, K ) ) | |||
| A( J, K ) = CONJG( A( KP, J ) ) | |||
| A( KP, J ) = TEMP | |||
| 110 CONTINUE | |||
| * | |||
| A( KP, K ) = CONJG( A( KP, K ) ) | |||
| * | |||
| TEMP = A( K, K ) | |||
| A( K, K ) = A( KP, KP ) | |||
| A( KP, KP ) = TEMP | |||
| END IF | |||
| END IF | |||
| * | |||
| K = K - 1 | |||
| GO TO 80 | |||
| 120 CONTINUE | |||
| END IF | |||
| * | |||
| RETURN | |||
| * | |||
| * End of CHETRI_ROOK | |||
| * | |||
| END | |||
| @@ -0,0 +1,503 @@ | |||
| *> \brief \b CHETRS_ROOK computes the solution to a system of linear equations A * X = B for HE matrices using factorization obtained with one of the bounded diagonal pivoting methods (max 2 interchanges) | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download CHETRS_ROOK + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/chetrs_rook.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/chetrs_rook.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/chetrs_rook.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE CHETRS_ROOK( UPLO, N, NRHS, A, LDA, IPIV, B, LDB, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * CHARACTER UPLO | |||
| * INTEGER INFO, LDA, LDB, N, NRHS | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * INTEGER IPIV( * ) | |||
| * COMPLEX A( LDA, * ), B( LDB, * ) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| * ============= | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> CHETRS_ROOK solves a system of linear equations A*X = B with a complex | |||
| *> Hermitian matrix A using the factorization A = U*D*U**H or | |||
| *> A = L*D*L**H computed by CHETRF_ROOK. | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] UPLO | |||
| *> \verbatim | |||
| *> UPLO is CHARACTER*1 | |||
| *> Specifies whether the details of the factorization are stored | |||
| *> as an upper or lower triangular matrix. | |||
| *> = 'U': Upper triangular, form is A = U*D*U**H; | |||
| *> = 'L': Lower triangular, form is A = L*D*L**H. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] N | |||
| *> \verbatim | |||
| *> N is INTEGER | |||
| *> The order of the matrix A. N >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] NRHS | |||
| *> \verbatim | |||
| *> NRHS is INTEGER | |||
| *> The number of right hand sides, i.e., the number of columns | |||
| *> of the matrix B. NRHS >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] A | |||
| *> \verbatim | |||
| *> A is COMPLEX array, dimension (LDA,N) | |||
| *> The block diagonal matrix D and the multipliers used to | |||
| *> obtain the factor U or L as computed by CHETRF_ROOK. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDA | |||
| *> \verbatim | |||
| *> LDA is INTEGER | |||
| *> The leading dimension of the array A. LDA >= max(1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] IPIV | |||
| *> \verbatim | |||
| *> IPIV is INTEGER array, dimension (N) | |||
| *> Details of the interchanges and the block structure of D | |||
| *> as determined by CHETRF_ROOK. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] B | |||
| *> \verbatim | |||
| *> B is COMPLEX array, dimension (LDB,NRHS) | |||
| *> On entry, the right hand side matrix B. | |||
| *> On exit, the solution matrix X. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDB | |||
| *> \verbatim | |||
| *> LDB is INTEGER | |||
| *> The leading dimension of the array B. LDB >= max(1,N). | |||
| *> \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 2013 | |||
| * | |||
| *> \ingroup complexHEcomputational | |||
| * | |||
| *> \par Contributors: | |||
| * ================== | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> November 2013, Igor Kozachenko, | |||
| *> Computer Science Division, | |||
| *> University of California, Berkeley | |||
| *> | |||
| *> September 2007, Sven Hammarling, Nicholas J. Higham, Craig Lucas, | |||
| *> School of Mathematics, | |||
| *> University of Manchester | |||
| *> | |||
| *> \endverbatim | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE CHETRS_ROOK( UPLO, N, NRHS, A, LDA, IPIV, B, LDB, | |||
| $ INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER UPLO | |||
| INTEGER INFO, LDA, LDB, N, NRHS | |||
| * .. | |||
| * .. Array Arguments .. | |||
| INTEGER IPIV( * ) | |||
| COMPLEX A( LDA, * ), B( LDB, * ) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| COMPLEX ONE | |||
| PARAMETER ( ONE = ( 1.0E+0, 0.0E+0 ) ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| LOGICAL UPPER | |||
| INTEGER J, K, KP | |||
| REAL S | |||
| COMPLEX AK, AKM1, AKM1K, BK, BKM1, DENOM | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| EXTERNAL LSAME | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL CGEMV, CGERU, CLACGV, CSSCAL, CSWAP, XERBLA | |||
| * .. | |||
| * .. Intrinsic Functions .. | |||
| INTRINSIC CONJG, MAX, REAL | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| INFO = 0 | |||
| UPPER = LSAME( UPLO, 'U' ) | |||
| IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN | |||
| INFO = -1 | |||
| ELSE IF( N.LT.0 ) THEN | |||
| INFO = -2 | |||
| ELSE IF( NRHS.LT.0 ) THEN | |||
| INFO = -3 | |||
| ELSE IF( LDA.LT.MAX( 1, N ) ) THEN | |||
| INFO = -5 | |||
| ELSE IF( LDB.LT.MAX( 1, N ) ) THEN | |||
| INFO = -8 | |||
| END IF | |||
| IF( INFO.NE.0 ) THEN | |||
| CALL XERBLA( 'CHETRS_ROOK', -INFO ) | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Quick return if possible | |||
| * | |||
| IF( N.EQ.0 .OR. NRHS.EQ.0 ) | |||
| $ RETURN | |||
| * | |||
| IF( UPPER ) THEN | |||
| * | |||
| * Solve A*X = B, where A = U*D*U**H. | |||
| * | |||
| * First solve U*D*X = B, overwriting B with X. | |||
| * | |||
| * K is the main loop index, decreasing from N to 1 in steps of | |||
| * 1 or 2, depending on the size of the diagonal blocks. | |||
| * | |||
| K = N | |||
| 10 CONTINUE | |||
| * | |||
| * If K < 1, exit from loop. | |||
| * | |||
| IF( K.LT.1 ) | |||
| $ GO TO 30 | |||
| * | |||
| IF( IPIV( K ).GT.0 ) THEN | |||
| * | |||
| * 1 x 1 diagonal block | |||
| * | |||
| * Interchange rows K and IPIV(K). | |||
| * | |||
| KP = IPIV( K ) | |||
| IF( KP.NE.K ) | |||
| $ CALL CSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| * | |||
| * Multiply by inv(U(K)), where U(K) is the transformation | |||
| * stored in column K of A. | |||
| * | |||
| CALL CGERU( K-1, NRHS, -ONE, A( 1, K ), 1, B( K, 1 ), LDB, | |||
| $ B( 1, 1 ), LDB ) | |||
| * | |||
| * Multiply by the inverse of the diagonal block. | |||
| * | |||
| S = REAL( ONE ) / REAL( A( K, K ) ) | |||
| CALL CSSCAL( NRHS, S, B( K, 1 ), LDB ) | |||
| K = K - 1 | |||
| ELSE | |||
| * | |||
| * 2 x 2 diagonal block | |||
| * | |||
| * Interchange rows K and -IPIV(K), then K-1 and -IPIV(K-1) | |||
| * | |||
| KP = -IPIV( K ) | |||
| IF( KP.NE.K ) | |||
| $ CALL CSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| * | |||
| KP = -IPIV( K-1) | |||
| IF( KP.NE.K-1 ) | |||
| $ CALL CSWAP( NRHS, B( K-1, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| * | |||
| * Multiply by inv(U(K)), where U(K) is the transformation | |||
| * stored in columns K-1 and K of A. | |||
| * | |||
| CALL CGERU( K-2, NRHS, -ONE, A( 1, K ), 1, B( K, 1 ), LDB, | |||
| $ B( 1, 1 ), LDB ) | |||
| CALL CGERU( K-2, NRHS, -ONE, A( 1, K-1 ), 1, B( K-1, 1 ), | |||
| $ LDB, B( 1, 1 ), LDB ) | |||
| * | |||
| * Multiply by the inverse of the diagonal block. | |||
| * | |||
| AKM1K = A( K-1, K ) | |||
| AKM1 = A( K-1, K-1 ) / AKM1K | |||
| AK = A( K, K ) / CONJG( AKM1K ) | |||
| DENOM = AKM1*AK - ONE | |||
| DO 20 J = 1, NRHS | |||
| BKM1 = B( K-1, J ) / AKM1K | |||
| BK = B( K, J ) / CONJG( AKM1K ) | |||
| B( K-1, J ) = ( AK*BKM1-BK ) / DENOM | |||
| B( K, J ) = ( AKM1*BK-BKM1 ) / DENOM | |||
| 20 CONTINUE | |||
| K = K - 2 | |||
| END IF | |||
| * | |||
| GO TO 10 | |||
| 30 CONTINUE | |||
| * | |||
| * Next solve U**H *X = B, overwriting B with X. | |||
| * | |||
| * K is the main loop index, increasing from 1 to N in steps of | |||
| * 1 or 2, depending on the size of the diagonal blocks. | |||
| * | |||
| K = 1 | |||
| 40 CONTINUE | |||
| * | |||
| * If K > N, exit from loop. | |||
| * | |||
| IF( K.GT.N ) | |||
| $ GO TO 50 | |||
| * | |||
| IF( IPIV( K ).GT.0 ) THEN | |||
| * | |||
| * 1 x 1 diagonal block | |||
| * | |||
| * Multiply by inv(U**H(K)), where U(K) is the transformation | |||
| * stored in column K of A. | |||
| * | |||
| IF( K.GT.1 ) THEN | |||
| CALL CLACGV( NRHS, B( K, 1 ), LDB ) | |||
| CALL CGEMV( 'Conjugate transpose', K-1, NRHS, -ONE, B, | |||
| $ LDB, A( 1, K ), 1, ONE, B( K, 1 ), LDB ) | |||
| CALL CLACGV( NRHS, B( K, 1 ), LDB ) | |||
| END IF | |||
| * | |||
| * Interchange rows K and IPIV(K). | |||
| * | |||
| KP = IPIV( K ) | |||
| IF( KP.NE.K ) | |||
| $ CALL CSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| K = K + 1 | |||
| ELSE | |||
| * | |||
| * 2 x 2 diagonal block | |||
| * | |||
| * Multiply by inv(U**H(K+1)), where U(K+1) is the transformation | |||
| * stored in columns K and K+1 of A. | |||
| * | |||
| IF( K.GT.1 ) THEN | |||
| CALL CLACGV( NRHS, B( K, 1 ), LDB ) | |||
| CALL CGEMV( 'Conjugate transpose', K-1, NRHS, -ONE, B, | |||
| $ LDB, A( 1, K ), 1, ONE, B( K, 1 ), LDB ) | |||
| CALL CLACGV( NRHS, B( K, 1 ), LDB ) | |||
| * | |||
| CALL CLACGV( NRHS, B( K+1, 1 ), LDB ) | |||
| CALL CGEMV( 'Conjugate transpose', K-1, NRHS, -ONE, B, | |||
| $ LDB, A( 1, K+1 ), 1, ONE, B( K+1, 1 ), LDB ) | |||
| CALL CLACGV( NRHS, B( K+1, 1 ), LDB ) | |||
| END IF | |||
| * | |||
| * Interchange rows K and -IPIV(K), then K+1 and -IPIV(K+1) | |||
| * | |||
| KP = -IPIV( K ) | |||
| IF( KP.NE.K ) | |||
| $ CALL CSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| * | |||
| KP = -IPIV( K+1 ) | |||
| IF( KP.NE.K+1 ) | |||
| $ CALL CSWAP( NRHS, B( K+1, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| * | |||
| K = K + 2 | |||
| END IF | |||
| * | |||
| GO TO 40 | |||
| 50 CONTINUE | |||
| * | |||
| ELSE | |||
| * | |||
| * Solve A*X = B, where A = L*D*L**H. | |||
| * | |||
| * First solve L*D*X = B, overwriting B with X. | |||
| * | |||
| * K is the main loop index, increasing from 1 to N in steps of | |||
| * 1 or 2, depending on the size of the diagonal blocks. | |||
| * | |||
| K = 1 | |||
| 60 CONTINUE | |||
| * | |||
| * If K > N, exit from loop. | |||
| * | |||
| IF( K.GT.N ) | |||
| $ GO TO 80 | |||
| * | |||
| IF( IPIV( K ).GT.0 ) THEN | |||
| * | |||
| * 1 x 1 diagonal block | |||
| * | |||
| * Interchange rows K and IPIV(K). | |||
| * | |||
| KP = IPIV( K ) | |||
| IF( KP.NE.K ) | |||
| $ CALL CSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| * | |||
| * Multiply by inv(L(K)), where L(K) is the transformation | |||
| * stored in column K of A. | |||
| * | |||
| IF( K.LT.N ) | |||
| $ CALL CGERU( N-K, NRHS, -ONE, A( K+1, K ), 1, B( K, 1 ), | |||
| $ LDB, B( K+1, 1 ), LDB ) | |||
| * | |||
| * Multiply by the inverse of the diagonal block. | |||
| * | |||
| S = REAL( ONE ) / REAL( A( K, K ) ) | |||
| CALL CSSCAL( NRHS, S, B( K, 1 ), LDB ) | |||
| K = K + 1 | |||
| ELSE | |||
| * | |||
| * 2 x 2 diagonal block | |||
| * | |||
| * Interchange rows K and -IPIV(K), then K+1 and -IPIV(K+1) | |||
| * | |||
| KP = -IPIV( K ) | |||
| IF( KP.NE.K ) | |||
| $ CALL CSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| * | |||
| KP = -IPIV( K+1 ) | |||
| IF( KP.NE.K+1 ) | |||
| $ CALL CSWAP( NRHS, B( K+1, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| * | |||
| * Multiply by inv(L(K)), where L(K) is the transformation | |||
| * stored in columns K and K+1 of A. | |||
| * | |||
| IF( K.LT.N-1 ) THEN | |||
| CALL CGERU( N-K-1, NRHS, -ONE, A( K+2, K ), 1, B( K, 1 ), | |||
| $ LDB, B( K+2, 1 ), LDB ) | |||
| CALL CGERU( N-K-1, NRHS, -ONE, A( K+2, K+1 ), 1, | |||
| $ B( K+1, 1 ), LDB, B( K+2, 1 ), LDB ) | |||
| END IF | |||
| * | |||
| * Multiply by the inverse of the diagonal block. | |||
| * | |||
| AKM1K = A( K+1, K ) | |||
| AKM1 = A( K, K ) / CONJG( AKM1K ) | |||
| AK = A( K+1, K+1 ) / AKM1K | |||
| DENOM = AKM1*AK - ONE | |||
| DO 70 J = 1, NRHS | |||
| BKM1 = B( K, J ) / CONJG( AKM1K ) | |||
| BK = B( K+1, J ) / AKM1K | |||
| B( K, J ) = ( AK*BKM1-BK ) / DENOM | |||
| B( K+1, J ) = ( AKM1*BK-BKM1 ) / DENOM | |||
| 70 CONTINUE | |||
| K = K + 2 | |||
| END IF | |||
| * | |||
| GO TO 60 | |||
| 80 CONTINUE | |||
| * | |||
| * Next solve L**H *X = B, overwriting B with X. | |||
| * | |||
| * K is the main loop index, decreasing from N to 1 in steps of | |||
| * 1 or 2, depending on the size of the diagonal blocks. | |||
| * | |||
| K = N | |||
| 90 CONTINUE | |||
| * | |||
| * If K < 1, exit from loop. | |||
| * | |||
| IF( K.LT.1 ) | |||
| $ GO TO 100 | |||
| * | |||
| IF( IPIV( K ).GT.0 ) THEN | |||
| * | |||
| * 1 x 1 diagonal block | |||
| * | |||
| * Multiply by inv(L**H(K)), where L(K) is the transformation | |||
| * stored in column K of A. | |||
| * | |||
| IF( K.LT.N ) THEN | |||
| CALL CLACGV( NRHS, B( K, 1 ), LDB ) | |||
| CALL CGEMV( 'Conjugate transpose', N-K, NRHS, -ONE, | |||
| $ B( K+1, 1 ), LDB, A( K+1, K ), 1, ONE, | |||
| $ B( K, 1 ), LDB ) | |||
| CALL CLACGV( NRHS, B( K, 1 ), LDB ) | |||
| END IF | |||
| * | |||
| * Interchange rows K and IPIV(K). | |||
| * | |||
| KP = IPIV( K ) | |||
| IF( KP.NE.K ) | |||
| $ CALL CSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| K = K - 1 | |||
| ELSE | |||
| * | |||
| * 2 x 2 diagonal block | |||
| * | |||
| * Multiply by inv(L**H(K-1)), where L(K-1) is the transformation | |||
| * stored in columns K-1 and K of A. | |||
| * | |||
| IF( K.LT.N ) THEN | |||
| CALL CLACGV( NRHS, B( K, 1 ), LDB ) | |||
| CALL CGEMV( 'Conjugate transpose', N-K, NRHS, -ONE, | |||
| $ B( K+1, 1 ), LDB, A( K+1, K ), 1, ONE, | |||
| $ B( K, 1 ), LDB ) | |||
| CALL CLACGV( NRHS, B( K, 1 ), LDB ) | |||
| * | |||
| CALL CLACGV( NRHS, B( K-1, 1 ), LDB ) | |||
| CALL CGEMV( 'Conjugate transpose', N-K, NRHS, -ONE, | |||
| $ B( K+1, 1 ), LDB, A( K+1, K-1 ), 1, ONE, | |||
| $ B( K-1, 1 ), LDB ) | |||
| CALL CLACGV( NRHS, B( K-1, 1 ), LDB ) | |||
| END IF | |||
| * | |||
| * Interchange rows K and -IPIV(K), then K-1 and -IPIV(K-1) | |||
| * | |||
| KP = -IPIV( K ) | |||
| IF( KP.NE.K ) | |||
| $ CALL CSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| * | |||
| KP = -IPIV( K-1 ) | |||
| IF( KP.NE.K-1 ) | |||
| $ CALL CSWAP( NRHS, B( K-1, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| * | |||
| K = K - 2 | |||
| END IF | |||
| * | |||
| GO TO 90 | |||
| 100 CONTINUE | |||
| END IF | |||
| * | |||
| RETURN | |||
| * | |||
| * End of CHETRS_ROOK | |||
| * | |||
| END | |||
| @@ -104,6 +104,7 @@ | |||
| *> \verbatim | |||
| *> H is COMPLEX array, dimension (LDH,N) | |||
| *> The upper Hessenberg matrix H. | |||
| *> If a NaN is detected in H, the routine will return with INFO=-6. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDH | |||
| @@ -225,7 +226,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date November 2011 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup complexOTHERcomputational | |||
| * | |||
| @@ -244,10 +245,10 @@ | |||
| $ LDVL, VR, LDVR, MM, M, WORK, RWORK, IFAILL, | |||
| $ IFAILR, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.0) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * November 2011 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER EIGSRC, INITV, SIDE | |||
| @@ -276,9 +277,9 @@ | |||
| COMPLEX CDUM, WK | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| LOGICAL LSAME, SISNAN | |||
| REAL CLANHS, SLAMCH | |||
| EXTERNAL LSAME, CLANHS, SLAMCH | |||
| EXTERNAL LSAME, CLANHS, SLAMCH, SISNAN | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL CLAEIN, XERBLA | |||
| @@ -399,7 +400,10 @@ | |||
| * has not ben computed before. | |||
| * | |||
| HNORM = CLANHS( 'I', KR-KL+1, H( KL, KL ), LDH, RWORK ) | |||
| IF( HNORM.GT.RZERO ) THEN | |||
| IF( SISNAN( HNORM ) ) THEN | |||
| INFO = -6 | |||
| RETURN | |||
| ELSE IF( (HNORM.GT.RZERO) ) THEN | |||
| EPS3 = HNORM*ULP | |||
| ELSE | |||
| EPS3 = SMLNUM | |||
| @@ -43,7 +43,7 @@ | |||
| *> Optionally Z may be postmultiplied into an input unitary | |||
| *> matrix Q so that this routine can give the Schur factorization | |||
| *> of a matrix A which has been reduced to the Hessenberg form H | |||
| *> by the unitary matrix Q: A = Q*H*Q**H = (QZ)*H*(QZ)**H. | |||
| *> by the unitary matrix Q: A = Q*H*Q**H = (QZ)*T*(QZ)**H. | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| @@ -216,7 +216,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date November 2011 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup complexOTHERcomputational | |||
| * | |||
| @@ -299,10 +299,10 @@ | |||
| SUBROUTINE CHSEQR( JOB, COMPZ, N, ILO, IHI, H, LDH, W, Z, LDZ, | |||
| $ WORK, LWORK, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.0) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * November 2011 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| INTEGER IHI, ILO, INFO, LDH, LDZ, LWORK, N | |||
| @@ -67,14 +67,14 @@ | |||
| *> | |||
| *> \param[in] RES | |||
| *> \verbatim | |||
| *> RES is DOUBLE PRECISION array, dimension (N,NRHS) | |||
| *> RES is REAL array, dimension (N,NRHS) | |||
| *> The residual matrix, i.e., the matrix R in the relative backward | |||
| *> error formula above. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] AYB | |||
| *> \verbatim | |||
| *> AYB is DOUBLE PRECISION array, dimension (N, NRHS) | |||
| *> AYB is REAL array, dimension (N, NRHS) | |||
| *> The denominator in the relative backward error formula above, i.e., | |||
| *> the matrix abs(op(A_s))*abs(Y) + abs(B_s). The matrices A, Y, and B | |||
| *> are from iterative refinement (see cla_gerfsx_extended.f). | |||
| @@ -94,17 +94,17 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date September 2012 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup complexOTHERcomputational | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE CLA_LIN_BERR ( N, NZ, NRHS, RES, AYB, BERR ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.2) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * September 2012 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| INTEGER N, NZ, NRHS | |||
| @@ -1,25 +1,25 @@ | |||
| *> \brief \b CLAHEF computes a partial factorization of a complex Hermitian indefinite matrix, using the diagonal pivoting method. | |||
| *> \brief \b CLAHEF computes a partial factorization of a complex Hermitian indefinite matrix using the Bunch-Kaufman diagonal pivoting method (blocked algorithm, calling Level 3 BLAS). | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download CLAHEF + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/clahef.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/clahef.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/clahef.f"> | |||
| *> Download CLAHEF + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/clahef.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/clahef.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/clahef.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE CLAHEF( UPLO, N, NB, KB, A, LDA, IPIV, W, LDW, INFO ) | |||
| * | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * CHARACTER UPLO | |||
| * INTEGER INFO, KB, LDA, LDW, N, NB | |||
| @@ -28,7 +28,7 @@ | |||
| * INTEGER IPIV( * ) | |||
| * COMPLEX A( LDA, * ), W( LDW, * ) | |||
| * .. | |||
| * | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| * ============= | |||
| @@ -110,16 +110,26 @@ | |||
| *> \verbatim | |||
| *> IPIV is INTEGER array, dimension (N) | |||
| *> Details of the interchanges and the block structure of D. | |||
| *> If UPLO = 'U', only the last KB elements of IPIV are set; | |||
| *> if UPLO = 'L', only the first KB elements are set. | |||
| *> | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) were | |||
| *> interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> If UPLO = 'U' and IPIV(k) = IPIV(k-1) < 0, then rows and | |||
| *> columns k-1 and -IPIV(k) were interchanged and D(k-1:k,k-1:k) | |||
| *> is a 2-by-2 diagonal block. If UPLO = 'L' and IPIV(k) = | |||
| *> IPIV(k+1) < 0, then rows and columns k+1 and -IPIV(k) were | |||
| *> interchanged and D(k:k+1,k:k+1) is a 2-by-2 diagonal block. | |||
| *> If UPLO = 'U': | |||
| *> Only the last KB elements of IPIV are set. | |||
| *> | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) were | |||
| *> interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) = IPIV(k-1) < 0, then rows and columns | |||
| *> k-1 and -IPIV(k) were interchanged and D(k-1:k,k-1:k) | |||
| *> is a 2-by-2 diagonal block. | |||
| *> | |||
| *> If UPLO = 'L': | |||
| *> Only the first KB elements of IPIV are set. | |||
| *> | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) were | |||
| *> interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) = IPIV(k+1) < 0, then rows and columns | |||
| *> k+1 and -IPIV(k) were interchanged and D(k:k+1,k:k+1) | |||
| *> is a 2-by-2 diagonal block. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] W | |||
| @@ -145,22 +155,32 @@ | |||
| * Authors: | |||
| * ======== | |||
| * | |||
| *> \author Univ. of Tennessee | |||
| *> \author Univ. of California Berkeley | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| *> \author Univ. of Tennessee | |||
| *> \author Univ. of California Berkeley | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date September 2012 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup complexHEcomputational | |||
| * | |||
| *> \par Contributors: | |||
| * ================== | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> November 2013, Igor Kozachenko, | |||
| *> Computer Science Division, | |||
| *> University of California, Berkeley | |||
| *> \endverbatim | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE CLAHEF( UPLO, N, NB, KB, A, LDA, IPIV, W, LDW, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.2) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * September 2012 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER UPLO | |||
| @@ -219,17 +239,20 @@ | |||
| * for use in updating A11 (note that conjg(W) is actually stored) | |||
| * | |||
| * K is the main loop index, decreasing from N in steps of 1 or 2 | |||
| * | |||
| * KW is the column of W which corresponds to column K of A | |||
| * | |||
| K = N | |||
| 10 CONTINUE | |||
| * | |||
| * KW is the column of W which corresponds to column K of A | |||
| * | |||
| KW = NB + K - N | |||
| * | |||
| * Exit from loop | |||
| * | |||
| IF( ( K.LE.N-NB+1 .AND. NB.LT.N ) .OR. K.LT.1 ) | |||
| $ GO TO 30 | |||
| * | |||
| KSTEP = 1 | |||
| * | |||
| * Copy column K of A to column KW of W and update it | |||
| * | |||
| @@ -240,8 +263,6 @@ | |||
| $ W( K, KW+1 ), LDW, CONE, W( 1, KW ), 1 ) | |||
| W( K, KW ) = REAL( W( K, KW ) ) | |||
| END IF | |||
| * | |||
| KSTEP = 1 | |||
| * | |||
| * Determine rows and columns to be interchanged and whether | |||
| * a 1-by-1 or 2-by-2 pivot block will be used | |||
| @@ -249,7 +270,8 @@ | |||
| ABSAKK = ABS( REAL( W( K, KW ) ) ) | |||
| * | |||
| * IMAX is the row-index of the largest off-diagonal element in | |||
| * column K, and COLMAX is its absolute value | |||
| * column K, and COLMAX is its absolute value. | |||
| * Determine both COLMAX and IMAX. | |||
| * | |||
| IF( K.GT.1 ) THEN | |||
| IMAX = ICAMAX( K-1, W( 1, KW ), 1 ) | |||
| @@ -260,13 +282,19 @@ | |||
| * | |||
| IF( MAX( ABSAKK, COLMAX ).EQ.ZERO ) THEN | |||
| * | |||
| * Column K is zero: set INFO and continue | |||
| * Column K is zero or underflow: set INFO and continue | |||
| * | |||
| IF( INFO.EQ.0 ) | |||
| $ INFO = K | |||
| KP = K | |||
| A( K, K ) = REAL( A( K, K ) ) | |||
| ELSE | |||
| * | |||
| * ============================================================ | |||
| * | |||
| * BEGIN pivot search | |||
| * | |||
| * Case(1) | |||
| IF( ABSAKK.GE.ALPHA*COLMAX ) THEN | |||
| * | |||
| * no interchange, use 1-by-1 pivot block | |||
| @@ -274,6 +302,9 @@ | |||
| KP = K | |||
| ELSE | |||
| * | |||
| * BEGIN pivot search along IMAX row | |||
| * | |||
| * | |||
| * Copy column IMAX to column KW-1 of W and update it | |||
| * | |||
| CALL CCOPY( IMAX-1, A( 1, IMAX ), 1, W( 1, KW-1 ), 1 ) | |||
| @@ -289,7 +320,8 @@ | |||
| END IF | |||
| * | |||
| * JMAX is the column-index of the largest off-diagonal | |||
| * element in row IMAX, and ROWMAX is its absolute value | |||
| * element in row IMAX, and ROWMAX is its absolute value. | |||
| * Determine only ROWMAX. | |||
| * | |||
| JMAX = IMAX + ICAMAX( K-IMAX, W( IMAX+1, KW-1 ), 1 ) | |||
| ROWMAX = CABS1( W( JMAX, KW-1 ) ) | |||
| @@ -298,11 +330,14 @@ | |||
| ROWMAX = MAX( ROWMAX, CABS1( W( JMAX, KW-1 ) ) ) | |||
| END IF | |||
| * | |||
| * Case(2) | |||
| IF( ABSAKK.GE.ALPHA*COLMAX*( COLMAX / ROWMAX ) ) THEN | |||
| * | |||
| * no interchange, use 1-by-1 pivot block | |||
| * | |||
| KP = K | |||
| * | |||
| * Case(3) | |||
| ELSE IF( ABS( REAL( W( IMAX, KW-1 ) ) ).GE.ALPHA*ROWMAX ) | |||
| $ THEN | |||
| * | |||
| @@ -311,9 +346,11 @@ | |||
| * | |||
| KP = IMAX | |||
| * | |||
| * copy column KW-1 of W to column KW | |||
| * copy column KW-1 of W to column KW of W | |||
| * | |||
| CALL CCOPY( K, W( 1, KW-1 ), 1, W( 1, KW ), 1 ) | |||
| * | |||
| * Case(4) | |||
| ELSE | |||
| * | |||
| * interchange rows and columns K-1 and IMAX, use 2-by-2 | |||
| @@ -322,27 +359,48 @@ | |||
| KP = IMAX | |||
| KSTEP = 2 | |||
| END IF | |||
| * | |||
| * | |||
| * END pivot search along IMAX row | |||
| * | |||
| END IF | |||
| * | |||
| * END pivot search | |||
| * | |||
| * ============================================================ | |||
| * | |||
| * KK is the column of A where pivoting step stopped | |||
| * | |||
| KK = K - KSTEP + 1 | |||
| * | |||
| * KKW is the column of W which corresponds to column KK of A | |||
| * | |||
| KKW = NB + KK - N | |||
| * | |||
| * Updated column KP is already stored in column KKW of W | |||
| * Interchange rows and columns KP and KK. | |||
| * Updated column KP is already stored in column KKW of W. | |||
| * | |||
| IF( KP.NE.KK ) THEN | |||
| * | |||
| * Copy non-updated column KK to column KP | |||
| * Copy non-updated column KK to column KP of submatrix A | |||
| * at step K. No need to copy element into column K | |||
| * (or K and K-1 for 2-by-2 pivot) of A, since these columns | |||
| * will be later overwritten. | |||
| * | |||
| A( KP, KP ) = REAL( A( KK, KK ) ) | |||
| CALL CCOPY( KK-1-KP, A( KP+1, KK ), 1, A( KP, KP+1 ), | |||
| $ LDA ) | |||
| CALL CLACGV( KK-1-KP, A( KP, KP+1 ), LDA ) | |||
| CALL CCOPY( KP-1, A( 1, KK ), 1, A( 1, KP ), 1 ) | |||
| IF( KP.GT.1 ) | |||
| $ CALL CCOPY( KP-1, A( 1, KK ), 1, A( 1, KP ), 1 ) | |||
| * | |||
| * Interchange rows KK and KP in last KK columns of A and W | |||
| * Interchange rows KK and KP in last K+1 to N columns of A | |||
| * (columns K (or K and K-1 for 2-by-2 pivot) of A will be | |||
| * later overwritten). Interchange rows KK and KP | |||
| * in last KKW to NB columns of W. | |||
| * | |||
| IF( KK.LT.N ) | |||
| $ CALL CSWAP( N-KK, A( KK, KK+1 ), LDA, A( KP, KK+1 ), | |||
| IF( K.LT.N ) | |||
| $ CALL CSWAP( N-K, A( KK, K+1 ), LDA, A( KP, K+1 ), | |||
| $ LDA ) | |||
| CALL CSWAP( N-KK+1, W( KK, KKW ), LDW, W( KP, KKW ), | |||
| $ LDW ) | |||
| @@ -350,40 +408,108 @@ | |||
| * | |||
| IF( KSTEP.EQ.1 ) THEN | |||
| * | |||
| * 1-by-1 pivot block D(k): column KW of W now holds | |||
| * 1-by-1 pivot block D(k): column kw of W now holds | |||
| * | |||
| * W(k) = U(k)*D(k) | |||
| * W(kw) = U(k)*D(k), | |||
| * | |||
| * where U(k) is the k-th column of U | |||
| * | |||
| * Store U(k) in column k of A | |||
| * (1) Store subdiag. elements of column U(k) | |||
| * and 1-by-1 block D(k) in column k of A. | |||
| * (NOTE: Diagonal element U(k,k) is a UNIT element | |||
| * and not stored) | |||
| * A(k,k) := D(k,k) = W(k,kw) | |||
| * A(1:k-1,k) := U(1:k-1,k) = W(1:k-1,kw)/D(k,k) | |||
| * | |||
| * (NOTE: No need to use for Hermitian matrix | |||
| * A( K, K ) = DBLE( W( K, K) ) to separately copy diagonal | |||
| * element D(k,k) from W (potentially saves only one load)) | |||
| CALL CCOPY( K, W( 1, KW ), 1, A( 1, K ), 1 ) | |||
| R1 = ONE / REAL( A( K, K ) ) | |||
| CALL CSSCAL( K-1, R1, A( 1, K ), 1 ) | |||
| IF( K.GT.1 ) THEN | |||
| * | |||
| * Conjugate W(k) | |||
| * (NOTE: No need to check if A(k,k) is NOT ZERO, | |||
| * since that was ensured earlier in pivot search: | |||
| * case A(k,k) = 0 falls into 2x2 pivot case(4)) | |||
| * | |||
| R1 = ONE / REAL( A( K, K ) ) | |||
| CALL CSSCAL( K-1, R1, A( 1, K ), 1 ) | |||
| * | |||
| * (2) Conjugate column W(kw) | |||
| * | |||
| CALL CLACGV( K-1, W( 1, KW ), 1 ) | |||
| END IF | |||
| * | |||
| CALL CLACGV( K-1, W( 1, KW ), 1 ) | |||
| ELSE | |||
| * | |||
| * 2-by-2 pivot block D(k): columns KW and KW-1 of W now | |||
| * hold | |||
| * 2-by-2 pivot block D(k): columns kw and kw-1 of W now hold | |||
| * | |||
| * ( W(k-1) W(k) ) = ( U(k-1) U(k) )*D(k) | |||
| * ( W(kw-1) W(kw) ) = ( U(k-1) U(k) )*D(k) | |||
| * | |||
| * where U(k) and U(k-1) are the k-th and (k-1)-th columns | |||
| * of U | |||
| * | |||
| * (1) Store U(1:k-2,k-1) and U(1:k-2,k) and 2-by-2 | |||
| * block D(k-1:k,k-1:k) in columns k-1 and k of A. | |||
| * (NOTE: 2-by-2 diagonal block U(k-1:k,k-1:k) is a UNIT | |||
| * block and not stored) | |||
| * A(k-1:k,k-1:k) := D(k-1:k,k-1:k) = W(k-1:k,kw-1:kw) | |||
| * A(1:k-2,k-1:k) := U(1:k-2,k:k-1:k) = | |||
| * = W(1:k-2,kw-1:kw) * ( D(k-1:k,k-1:k)**(-1) ) | |||
| * | |||
| IF( K.GT.2 ) THEN | |||
| * | |||
| * Store U(k) and U(k-1) in columns k and k-1 of A | |||
| * Factor out the columns of the inverse of 2-by-2 pivot | |||
| * block D, so that each column contains 1, to reduce the | |||
| * number of FLOPS when we multiply panel | |||
| * ( W(kw-1) W(kw) ) by this inverse, i.e. by D**(-1). | |||
| * | |||
| * D**(-1) = ( d11 cj(d21) )**(-1) = | |||
| * ( d21 d22 ) | |||
| * | |||
| * = 1/(d11*d22-|d21|**2) * ( ( d22) (-cj(d21) ) ) = | |||
| * ( (-d21) ( d11 ) ) | |||
| * | |||
| * = 1/(|d21|**2) * 1/((d11/cj(d21))*(d22/d21)-1) * | |||
| * | |||
| * * ( d21*( d22/d21 ) conj(d21)*( - 1 ) ) = | |||
| * ( ( -1 ) ( d11/conj(d21) ) ) | |||
| * | |||
| * = 1/(|d21|**2) * 1/(D22*D11-1) * | |||
| * | |||
| * * ( d21*( D11 ) conj(d21)*( -1 ) ) = | |||
| * ( ( -1 ) ( D22 ) ) | |||
| * | |||
| * = (1/|d21|**2) * T * ( d21*( D11 ) conj(d21)*( -1 ) ) = | |||
| * ( ( -1 ) ( D22 ) ) | |||
| * | |||
| * = ( (T/conj(d21))*( D11 ) (T/d21)*( -1 ) ) = | |||
| * ( ( -1 ) ( D22 ) ) | |||
| * | |||
| * = ( conj(D21)*( D11 ) D21*( -1 ) ) | |||
| * ( ( -1 ) ( D22 ) ), | |||
| * | |||
| * where D11 = d22/d21, | |||
| * D22 = d11/conj(d21), | |||
| * D21 = T/d21, | |||
| * T = 1/(D22*D11-1). | |||
| * | |||
| * (NOTE: No need to check for division by ZERO, | |||
| * since that was ensured earlier in pivot search: | |||
| * (a) d21 != 0, since in 2x2 pivot case(4) | |||
| * |d21| should be larger than |d11| and |d22|; | |||
| * (b) (D22*D11 - 1) != 0, since from (a), | |||
| * both |D11| < 1, |D22| < 1, hence |D22*D11| << 1.) | |||
| * | |||
| D21 = W( K-1, KW ) | |||
| D11 = W( K, KW ) / CONJG( D21 ) | |||
| D22 = W( K-1, KW-1 ) / D21 | |||
| T = ONE / ( REAL( D11*D22 )-ONE ) | |||
| D21 = T / D21 | |||
| * | |||
| * Update elements in columns A(k-1) and A(k) as | |||
| * dot products of rows of ( W(kw-1) W(kw) ) and columns | |||
| * of D**(-1) | |||
| * | |||
| DO 20 J = 1, K - 2 | |||
| A( J, K-1 ) = D21*( D11*W( J, KW-1 )-W( J, KW ) ) | |||
| A( J, K ) = CONJG( D21 )* | |||
| @@ -397,11 +523,13 @@ | |||
| A( K-1, K ) = W( K-1, KW ) | |||
| A( K, K ) = W( K, KW ) | |||
| * | |||
| * Conjugate W(k) and W(k-1) | |||
| * (2) Conjugate columns W(kw) and W(kw-1) | |||
| * | |||
| CALL CLACGV( K-1, W( 1, KW ), 1 ) | |||
| CALL CLACGV( K-2, W( 1, KW-1 ), 1 ) | |||
| * | |||
| END IF | |||
| * | |||
| END IF | |||
| * | |||
| * Store details of the interchanges in IPIV | |||
| @@ -448,19 +576,27 @@ | |||
| 50 CONTINUE | |||
| * | |||
| * Put U12 in standard form by partially undoing the interchanges | |||
| * in columns k+1:n | |||
| * in of rows in columns k+1:n looping backwards from k+1 to n | |||
| * | |||
| J = K + 1 | |||
| 60 CONTINUE | |||
| JJ = J | |||
| JP = IPIV( J ) | |||
| IF( JP.LT.0 ) THEN | |||
| JP = -JP | |||
| * | |||
| * Undo the interchanges (if any) of rows J and JP | |||
| * at each step J | |||
| * | |||
| * (Here, J is a diagonal index) | |||
| JJ = J | |||
| JP = IPIV( J ) | |||
| IF( JP.LT.0 ) THEN | |||
| JP = -JP | |||
| * (Here, J is a diagonal index) | |||
| J = J + 1 | |||
| END IF | |||
| * (NOTE: Here, J is used to determine row length. Length N-J+1 | |||
| * of the rows to swap back doesn't include diagonal element) | |||
| J = J + 1 | |||
| END IF | |||
| J = J + 1 | |||
| IF( JP.NE.JJ .AND. J.LE.N ) | |||
| $ CALL CSWAP( N-J+1, A( JP, J ), LDA, A( JJ, J ), LDA ) | |||
| IF( JP.NE.JJ .AND. J.LE.N ) | |||
| $ CALL CSWAP( N-J+1, A( JP, J ), LDA, A( JJ, J ), LDA ) | |||
| IF( J.LE.N ) | |||
| $ GO TO 60 | |||
| * | |||
| @@ -483,6 +619,8 @@ | |||
| * | |||
| IF( ( K.GE.NB .AND. NB.LT.N ) .OR. K.GT.N ) | |||
| $ GO TO 90 | |||
| * | |||
| KSTEP = 1 | |||
| * | |||
| * Copy column K of A to column K of W and update it | |||
| * | |||
| @@ -492,8 +630,6 @@ | |||
| CALL CGEMV( 'No transpose', N-K+1, K-1, -CONE, A( K, 1 ), LDA, | |||
| $ W( K, 1 ), LDW, CONE, W( K, K ), 1 ) | |||
| W( K, K ) = REAL( W( K, K ) ) | |||
| * | |||
| KSTEP = 1 | |||
| * | |||
| * Determine rows and columns to be interchanged and whether | |||
| * a 1-by-1 or 2-by-2 pivot block will be used | |||
| @@ -501,7 +637,8 @@ | |||
| ABSAKK = ABS( REAL( W( K, K ) ) ) | |||
| * | |||
| * IMAX is the row-index of the largest off-diagonal element in | |||
| * column K, and COLMAX is its absolute value | |||
| * column K, and COLMAX is its absolute value. | |||
| * Determine both COLMAX and IMAX. | |||
| * | |||
| IF( K.LT.N ) THEN | |||
| IMAX = K + ICAMAX( N-K, W( K+1, K ), 1 ) | |||
| @@ -512,13 +649,19 @@ | |||
| * | |||
| IF( MAX( ABSAKK, COLMAX ).EQ.ZERO ) THEN | |||
| * | |||
| * Column K is zero: set INFO and continue | |||
| * Column K is zero or underflow: set INFO and continue | |||
| * | |||
| IF( INFO.EQ.0 ) | |||
| $ INFO = K | |||
| KP = K | |||
| A( K, K ) = REAL( A( K, K ) ) | |||
| ELSE | |||
| * | |||
| * ============================================================ | |||
| * | |||
| * BEGIN pivot search | |||
| * | |||
| * Case(1) | |||
| IF( ABSAKK.GE.ALPHA*COLMAX ) THEN | |||
| * | |||
| * no interchange, use 1-by-1 pivot block | |||
| @@ -526,6 +669,9 @@ | |||
| KP = K | |||
| ELSE | |||
| * | |||
| * BEGIN pivot search along IMAX row | |||
| * | |||
| * | |||
| * Copy column IMAX to column K+1 of W and update it | |||
| * | |||
| CALL CCOPY( IMAX-K, A( IMAX, K ), LDA, W( K, K+1 ), 1 ) | |||
| @@ -540,7 +686,8 @@ | |||
| W( IMAX, K+1 ) = REAL( W( IMAX, K+1 ) ) | |||
| * | |||
| * JMAX is the column-index of the largest off-diagonal | |||
| * element in row IMAX, and ROWMAX is its absolute value | |||
| * element in row IMAX, and ROWMAX is its absolute value. | |||
| * Determine only ROWMAX. | |||
| * | |||
| JMAX = K - 1 + ICAMAX( IMAX-K, W( K, K+1 ), 1 ) | |||
| ROWMAX = CABS1( W( JMAX, K+1 ) ) | |||
| @@ -549,11 +696,14 @@ | |||
| ROWMAX = MAX( ROWMAX, CABS1( W( JMAX, K+1 ) ) ) | |||
| END IF | |||
| * | |||
| * Case(2) | |||
| IF( ABSAKK.GE.ALPHA*COLMAX*( COLMAX / ROWMAX ) ) THEN | |||
| * | |||
| * no interchange, use 1-by-1 pivot block | |||
| * | |||
| KP = K | |||
| * | |||
| * Case(3) | |||
| ELSE IF( ABS( REAL( W( IMAX, K+1 ) ) ).GE.ALPHA*ROWMAX ) | |||
| $ THEN | |||
| * | |||
| @@ -562,9 +712,11 @@ | |||
| * | |||
| KP = IMAX | |||
| * | |||
| * copy column K+1 of W to column K | |||
| * copy column K+1 of W to column K of W | |||
| * | |||
| CALL CCOPY( N-K+1, W( K, K+1 ), 1, W( K, K ), 1 ) | |||
| * | |||
| * Case(4) | |||
| ELSE | |||
| * | |||
| * interchange rows and columns K+1 and IMAX, use 2-by-2 | |||
| @@ -573,15 +725,29 @@ | |||
| KP = IMAX | |||
| KSTEP = 2 | |||
| END IF | |||
| * | |||
| * | |||
| * END pivot search along IMAX row | |||
| * | |||
| END IF | |||
| * | |||
| * END pivot search | |||
| * | |||
| * ============================================================ | |||
| * | |||
| * KK is the column of A where pivoting step stopped | |||
| * | |||
| KK = K + KSTEP - 1 | |||
| * | |||
| * Updated column KP is already stored in column KK of W | |||
| * Interchange rows and columns KP and KK. | |||
| * Updated column KP is already stored in column KK of W. | |||
| * | |||
| IF( KP.NE.KK ) THEN | |||
| * | |||
| * Copy non-updated column KK to column KP | |||
| * Copy non-updated column KK to column KP of submatrix A | |||
| * at step K. No need to copy element into column K | |||
| * (or K and K+1 for 2-by-2 pivot) of A, since these columns | |||
| * will be later overwritten. | |||
| * | |||
| A( KP, KP ) = REAL( A( KK, KK ) ) | |||
| CALL CCOPY( KP-KK-1, A( KK+1, KK ), 1, A( KP, KK+1 ), | |||
| @@ -590,9 +756,13 @@ | |||
| IF( KP.LT.N ) | |||
| $ CALL CCOPY( N-KP, A( KP+1, KK ), 1, A( KP+1, KP ), 1 ) | |||
| * | |||
| * Interchange rows KK and KP in first KK columns of A and W | |||
| * Interchange rows KK and KP in first K-1 columns of A | |||
| * (columns K (or K and K+1 for 2-by-2 pivot) of A will be | |||
| * later overwritten). Interchange rows KK and KP | |||
| * in first KK columns of W. | |||
| * | |||
| CALL CSWAP( KK-1, A( KK, 1 ), LDA, A( KP, 1 ), LDA ) | |||
| IF( K.GT.1 ) | |||
| $ CALL CSWAP( K-1, A( KK, 1 ), LDA, A( KP, 1 ), LDA ) | |||
| CALL CSWAP( KK, W( KK, 1 ), LDW, W( KP, 1 ), LDW ) | |||
| END IF | |||
| * | |||
| @@ -600,21 +770,35 @@ | |||
| * | |||
| * 1-by-1 pivot block D(k): column k of W now holds | |||
| * | |||
| * W(k) = L(k)*D(k) | |||
| * W(k) = L(k)*D(k), | |||
| * | |||
| * where L(k) is the k-th column of L | |||
| * | |||
| * Store L(k) in column k of A | |||
| * (1) Store subdiag. elements of column L(k) | |||
| * and 1-by-1 block D(k) in column k of A. | |||
| * (NOTE: Diagonal element L(k,k) is a UNIT element | |||
| * and not stored) | |||
| * A(k,k) := D(k,k) = W(k,k) | |||
| * A(k+1:N,k) := L(k+1:N,k) = W(k+1:N,k)/D(k,k) | |||
| * | |||
| * (NOTE: No need to use for Hermitian matrix | |||
| * A( K, K ) = DBLE( W( K, K) ) to separately copy diagonal | |||
| * element D(k,k) from W (potentially saves only one load)) | |||
| CALL CCOPY( N-K+1, W( K, K ), 1, A( K, K ), 1 ) | |||
| IF( K.LT.N ) THEN | |||
| * | |||
| * (NOTE: No need to check if A(k,k) is NOT ZERO, | |||
| * since that was ensured earlier in pivot search: | |||
| * case A(k,k) = 0 falls into 2x2 pivot case(4)) | |||
| * | |||
| R1 = ONE / REAL( A( K, K ) ) | |||
| CALL CSSCAL( N-K, R1, A( K+1, K ), 1 ) | |||
| * | |||
| * Conjugate W(k) | |||
| * (2) Conjugate column W(k) | |||
| * | |||
| CALL CLACGV( N-K, W( K+1, K ), 1 ) | |||
| END IF | |||
| * | |||
| ELSE | |||
| * | |||
| * 2-by-2 pivot block D(k): columns k and k+1 of W now hold | |||
| @@ -623,16 +807,69 @@ | |||
| * | |||
| * where L(k) and L(k+1) are the k-th and (k+1)-th columns | |||
| * of L | |||
| * | |||
| * (1) Store L(k+2:N,k) and L(k+2:N,k+1) and 2-by-2 | |||
| * block D(k:k+1,k:k+1) in columns k and k+1 of A. | |||
| * (NOTE: 2-by-2 diagonal block L(k:k+1,k:k+1) is a UNIT | |||
| * block and not stored) | |||
| * A(k:k+1,k:k+1) := D(k:k+1,k:k+1) = W(k:k+1,k:k+1) | |||
| * A(k+2:N,k:k+1) := L(k+2:N,k:k+1) = | |||
| * = W(k+2:N,k:k+1) * ( D(k:k+1,k:k+1)**(-1) ) | |||
| * | |||
| IF( K.LT.N-1 ) THEN | |||
| * | |||
| * Store L(k) and L(k+1) in columns k and k+1 of A | |||
| * Factor out the columns of the inverse of 2-by-2 pivot | |||
| * block D, so that each column contains 1, to reduce the | |||
| * number of FLOPS when we multiply panel | |||
| * ( W(kw-1) W(kw) ) by this inverse, i.e. by D**(-1). | |||
| * | |||
| * D**(-1) = ( d11 cj(d21) )**(-1) = | |||
| * ( d21 d22 ) | |||
| * | |||
| * = 1/(d11*d22-|d21|**2) * ( ( d22) (-cj(d21) ) ) = | |||
| * ( (-d21) ( d11 ) ) | |||
| * | |||
| * = 1/(|d21|**2) * 1/((d11/cj(d21))*(d22/d21)-1) * | |||
| * | |||
| * * ( d21*( d22/d21 ) conj(d21)*( - 1 ) ) = | |||
| * ( ( -1 ) ( d11/conj(d21) ) ) | |||
| * | |||
| * = 1/(|d21|**2) * 1/(D22*D11-1) * | |||
| * | |||
| * * ( d21*( D11 ) conj(d21)*( -1 ) ) = | |||
| * ( ( -1 ) ( D22 ) ) | |||
| * | |||
| * = (1/|d21|**2) * T * ( d21*( D11 ) conj(d21)*( -1 ) ) = | |||
| * ( ( -1 ) ( D22 ) ) | |||
| * | |||
| * = ( (T/conj(d21))*( D11 ) (T/d21)*( -1 ) ) = | |||
| * ( ( -1 ) ( D22 ) ) | |||
| * | |||
| * = ( conj(D21)*( D11 ) D21*( -1 ) ) | |||
| * ( ( -1 ) ( D22 ) ) | |||
| * | |||
| * where D11 = d22/d21, | |||
| * D22 = d11/conj(d21), | |||
| * D21 = T/d21, | |||
| * T = 1/(D22*D11-1). | |||
| * | |||
| * (NOTE: No need to check for division by ZERO, | |||
| * since that was ensured earlier in pivot search: | |||
| * (a) d21 != 0, since in 2x2 pivot case(4) | |||
| * |d21| should be larger than |d11| and |d22|; | |||
| * (b) (D22*D11 - 1) != 0, since from (a), | |||
| * both |D11| < 1, |D22| < 1, hence |D22*D11| << 1.) | |||
| * | |||
| D21 = W( K+1, K ) | |||
| D11 = W( K+1, K+1 ) / D21 | |||
| D22 = W( K, K ) / CONJG( D21 ) | |||
| T = ONE / ( REAL( D11*D22 )-ONE ) | |||
| D21 = T / D21 | |||
| * | |||
| * Update elements in columns A(k) and A(k+1) as | |||
| * dot products of rows of ( W(k) W(k+1) ) and columns | |||
| * of D**(-1) | |||
| * | |||
| DO 80 J = K + 2, N | |||
| A( J, K ) = CONJG( D21 )* | |||
| $ ( D11*W( J, K )-W( J, K+1 ) ) | |||
| @@ -646,11 +883,13 @@ | |||
| A( K+1, K ) = W( K+1, K ) | |||
| A( K+1, K+1 ) = W( K+1, K+1 ) | |||
| * | |||
| * Conjugate W(k) and W(k+1) | |||
| * (2) Conjugate columns W(k) and W(k+1) | |||
| * | |||
| CALL CLACGV( N-K, W( K+1, K ), 1 ) | |||
| CALL CLACGV( N-K-1, W( K+2, K+1 ), 1 ) | |||
| * | |||
| END IF | |||
| * | |||
| END IF | |||
| * | |||
| * Store details of the interchanges in IPIV | |||
| @@ -698,19 +937,27 @@ | |||
| 110 CONTINUE | |||
| * | |||
| * Put L21 in standard form by partially undoing the interchanges | |||
| * in columns 1:k-1 | |||
| * of rows in columns 1:k-1 looping backwards from k-1 to 1 | |||
| * | |||
| J = K - 1 | |||
| 120 CONTINUE | |||
| JJ = J | |||
| JP = IPIV( J ) | |||
| IF( JP.LT.0 ) THEN | |||
| JP = -JP | |||
| * | |||
| * Undo the interchanges (if any) of rows J and JP | |||
| * at each step J | |||
| * | |||
| * (Here, J is a diagonal index) | |||
| JJ = J | |||
| JP = IPIV( J ) | |||
| IF( JP.LT.0 ) THEN | |||
| JP = -JP | |||
| * (Here, J is a diagonal index) | |||
| J = J - 1 | |||
| END IF | |||
| * (NOTE: Here, J is used to determine row length. Length J | |||
| * of the rows to swap back doesn't include diagonal element) | |||
| J = J - 1 | |||
| END IF | |||
| J = J - 1 | |||
| IF( JP.NE.JJ .AND. J.GE.1 ) | |||
| $ CALL CSWAP( J, A( JP, 1 ), LDA, A( JJ, 1 ), LDA ) | |||
| IF( JP.NE.JJ .AND. J.GE.1 ) | |||
| $ CALL CSWAP( J, A( JP, 1 ), LDA, A( JJ, 1 ), LDA ) | |||
| IF( J.GE.1 ) | |||
| $ GO TO 120 | |||
| * | |||
| @@ -159,7 +159,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date September 2012 | |||
| *> \date June 2013 | |||
| * | |||
| *> \ingroup complexOTHERauxiliary | |||
| * | |||
| @@ -195,10 +195,10 @@ | |||
| SUBROUTINE CLARFB( SIDE, TRANS, DIRECT, STOREV, M, N, K, V, LDV, | |||
| $ T, LDT, C, LDC, WORK, LDWORK ) | |||
| * | |||
| * -- LAPACK auxiliary routine (version 3.4.2) -- | |||
| * -- LAPACK auxiliary routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * September 2012 | |||
| * June 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER DIRECT, SIDE, STOREV, TRANS | |||
| @@ -217,12 +217,11 @@ | |||
| * .. | |||
| * .. Local Scalars .. | |||
| CHARACTER TRANST | |||
| INTEGER I, J, LASTV, LASTC | |||
| INTEGER I, J | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| INTEGER ILACLR, ILACLC | |||
| EXTERNAL LSAME, ILACLR, ILACLC | |||
| EXTERNAL LSAME | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL CCOPY, CGEMM, CLACGV, CTRMM | |||
| @@ -255,36 +254,33 @@ | |||
| * | |||
| * Form H * C or H**H * C where C = ( C1 ) | |||
| * ( C2 ) | |||
| * | |||
| LASTV = MAX( K, ILACLR( M, K, V, LDV ) ) | |||
| LASTC = ILACLC( LASTV, N, C, LDC ) | |||
| * | |||
| * W := C**H * V = (C1**H * V1 + C2**H * V2) (stored in WORK) | |||
| * | |||
| * W := C1**H | |||
| * | |||
| DO 10 J = 1, K | |||
| CALL CCOPY( LASTC, C( J, 1 ), LDC, WORK( 1, J ), 1 ) | |||
| CALL CLACGV( LASTC, WORK( 1, J ), 1 ) | |||
| CALL CCOPY( N, C( J, 1 ), LDC, WORK( 1, J ), 1 ) | |||
| CALL CLACGV( N, WORK( 1, J ), 1 ) | |||
| 10 CONTINUE | |||
| * | |||
| * W := W * V1 | |||
| * | |||
| CALL CTRMM( 'Right', 'Lower', 'No transpose', 'Unit', | |||
| $ LASTC, K, ONE, V, LDV, WORK, LDWORK ) | |||
| IF( LASTV.GT.K ) THEN | |||
| CALL CTRMM( 'Right', 'Lower', 'No transpose', 'Unit', N, | |||
| $ K, ONE, V, LDV, WORK, LDWORK ) | |||
| IF( M.GT.K ) THEN | |||
| * | |||
| * W := W + C2**H *V2 | |||
| * | |||
| CALL CGEMM( 'Conjugate transpose', 'No transpose', | |||
| $ LASTC, K, LASTV-K, ONE, C( K+1, 1 ), LDC, | |||
| $ V( K+1, 1 ), LDV, ONE, WORK, LDWORK ) | |||
| CALL CGEMM( 'Conjugate transpose', 'No transpose', N, | |||
| $ K, M-K, ONE, C( K+1, 1 ), LDC, | |||
| $ V( K+1, 1 ), LDV, ONE, WORK, LDWORK ) | |||
| END IF | |||
| * | |||
| * W := W * T**H or W * T | |||
| * | |||
| CALL CTRMM( 'Right', 'Upper', TRANST, 'Non-unit', | |||
| $ LASTC, K, ONE, T, LDT, WORK, LDWORK ) | |||
| CALL CTRMM( 'Right', 'Upper', TRANST, 'Non-unit', N, K, | |||
| $ ONE, T, LDT, WORK, LDWORK ) | |||
| * | |||
| * C := C - V * W**H | |||
| * | |||
| @@ -293,19 +289,19 @@ | |||
| * C2 := C2 - V2 * W**H | |||
| * | |||
| CALL CGEMM( 'No transpose', 'Conjugate transpose', | |||
| $ LASTV-K, LASTC, K, -ONE, V( K+1, 1 ), LDV, | |||
| $ WORK, LDWORK, ONE, C( K+1, 1 ), LDC ) | |||
| $ M-K, N, K, -ONE, V( K+1, 1 ), LDV, WORK, | |||
| $ LDWORK, ONE, C( K+1, 1 ), LDC ) | |||
| END IF | |||
| * | |||
| * W := W * V1**H | |||
| * | |||
| CALL CTRMM( 'Right', 'Lower', 'Conjugate transpose', | |||
| $ 'Unit', LASTC, K, ONE, V, LDV, WORK, LDWORK ) | |||
| $ 'Unit', N, K, ONE, V, LDV, WORK, LDWORK ) | |||
| * | |||
| * C1 := C1 - W**H | |||
| * | |||
| DO 30 J = 1, K | |||
| DO 20 I = 1, LASTC | |||
| DO 20 I = 1, N | |||
| C( J, I ) = C( J, I ) - CONJG( WORK( I, J ) ) | |||
| 20 CONTINUE | |||
| 30 CONTINUE | |||
| @@ -313,58 +309,53 @@ | |||
| ELSE IF( LSAME( SIDE, 'R' ) ) THEN | |||
| * | |||
| * Form C * H or C * H**H where C = ( C1 C2 ) | |||
| * | |||
| LASTV = MAX( K, ILACLR( N, K, V, LDV ) ) | |||
| LASTC = ILACLR( M, LASTV, C, LDC ) | |||
| * | |||
| * W := C * V = (C1*V1 + C2*V2) (stored in WORK) | |||
| * | |||
| * W := C1 | |||
| * | |||
| DO 40 J = 1, K | |||
| CALL CCOPY( LASTC, C( 1, J ), 1, WORK( 1, J ), 1 ) | |||
| CALL CCOPY( M, C( 1, J ), 1, WORK( 1, J ), 1 ) | |||
| 40 CONTINUE | |||
| * | |||
| * W := W * V1 | |||
| * | |||
| CALL CTRMM( 'Right', 'Lower', 'No transpose', 'Unit', | |||
| $ LASTC, K, ONE, V, LDV, WORK, LDWORK ) | |||
| IF( LASTV.GT.K ) THEN | |||
| CALL CTRMM( 'Right', 'Lower', 'No transpose', 'Unit', M, | |||
| $ K, ONE, V, LDV, WORK, LDWORK ) | |||
| IF( N.GT.K ) THEN | |||
| * | |||
| * W := W + C2 * V2 | |||
| * | |||
| CALL CGEMM( 'No transpose', 'No transpose', | |||
| $ LASTC, K, LASTV-K, | |||
| $ ONE, C( 1, K+1 ), LDC, V( K+1, 1 ), LDV, | |||
| $ ONE, WORK, LDWORK ) | |||
| CALL CGEMM( 'No transpose', 'No transpose', M, K, N-K, | |||
| $ ONE, C( 1, K+1 ), LDC, V( K+1, 1 ), LDV, | |||
| $ ONE, WORK, LDWORK ) | |||
| END IF | |||
| * | |||
| * W := W * T or W * T**H | |||
| * | |||
| CALL CTRMM( 'Right', 'Upper', TRANS, 'Non-unit', | |||
| $ LASTC, K, ONE, T, LDT, WORK, LDWORK ) | |||
| CALL CTRMM( 'Right', 'Upper', TRANS, 'Non-unit', M, K, | |||
| $ ONE, T, LDT, WORK, LDWORK ) | |||
| * | |||
| * C := C - W * V**H | |||
| * | |||
| IF( LASTV.GT.K ) THEN | |||
| IF( N.GT.K ) THEN | |||
| * | |||
| * C2 := C2 - W * V2**H | |||
| * | |||
| CALL CGEMM( 'No transpose', 'Conjugate transpose', | |||
| $ LASTC, LASTV-K, K, | |||
| $ -ONE, WORK, LDWORK, V( K+1, 1 ), LDV, | |||
| $ ONE, C( 1, K+1 ), LDC ) | |||
| CALL CGEMM( 'No transpose', 'Conjugate transpose', M, | |||
| $ N-K, K, -ONE, WORK, LDWORK, V( K+1, 1 ), | |||
| $ LDV, ONE, C( 1, K+1 ), LDC ) | |||
| END IF | |||
| * | |||
| * W := W * V1**H | |||
| * | |||
| CALL CTRMM( 'Right', 'Lower', 'Conjugate transpose', | |||
| $ 'Unit', LASTC, K, ONE, V, LDV, WORK, LDWORK ) | |||
| $ 'Unit', M, K, ONE, V, LDV, WORK, LDWORK ) | |||
| * | |||
| * C1 := C1 - W | |||
| * | |||
| DO 60 J = 1, K | |||
| DO 50 I = 1, LASTC | |||
| DO 50 I = 1, M | |||
| C( I, J ) = C( I, J ) - WORK( I, J ) | |||
| 50 CONTINUE | |||
| 60 CONTINUE | |||
| @@ -379,38 +370,34 @@ | |||
| IF( LSAME( SIDE, 'L' ) ) THEN | |||
| * | |||
| * Form H * C or H**H * C where C = ( C1 ) | |||
| * ( C2 ) | |||
| * | |||
| LASTC = ILACLC( M, N, C, LDC ) | |||
| * ( C2 ) | |||
| * | |||
| * W := C**H * V = (C1**H * V1 + C2**H * V2) (stored in WORK) | |||
| * | |||
| * W := C2**H | |||
| * | |||
| DO 70 J = 1, K | |||
| CALL CCOPY( LASTC, C( M-K+J, 1 ), LDC, | |||
| $ WORK( 1, J ), 1 ) | |||
| CALL CLACGV( LASTC, WORK( 1, J ), 1 ) | |||
| CALL CCOPY( N, C( M-K+J, 1 ), LDC, WORK( 1, J ), 1 ) | |||
| CALL CLACGV( N, WORK( 1, J ), 1 ) | |||
| 70 CONTINUE | |||
| * | |||
| * W := W * V2 | |||
| * | |||
| CALL CTRMM( 'Right', 'Upper', 'No transpose', 'Unit', | |||
| $ LASTC, K, ONE, V( M-K+1, 1 ), LDV, | |||
| $ WORK, LDWORK ) | |||
| CALL CTRMM( 'Right', 'Upper', 'No transpose', 'Unit', N, | |||
| $ K, ONE, V( M-K+1, 1 ), LDV, WORK, LDWORK ) | |||
| IF( M.GT.K ) THEN | |||
| * | |||
| * W := W + C1**H*V1 | |||
| * W := W + C1**H * V1 | |||
| * | |||
| CALL CGEMM( 'Conjugate transpose', 'No transpose', | |||
| $ LASTC, K, M-K, ONE, C, LDC, V, LDV, | |||
| $ ONE, WORK, LDWORK ) | |||
| CALL CGEMM( 'Conjugate transpose', 'No transpose', N, | |||
| $ K, M-K, ONE, C, LDC, V, LDV, ONE, WORK, | |||
| $ LDWORK ) | |||
| END IF | |||
| * | |||
| * W := W * T**H or W * T | |||
| * | |||
| CALL CTRMM( 'Right', 'Lower', TRANST, 'Non-unit', | |||
| $ LASTC, K, ONE, T, LDT, WORK, LDWORK ) | |||
| CALL CTRMM( 'Right', 'Lower', TRANST, 'Non-unit', N, K, | |||
| $ ONE, T, LDT, WORK, LDWORK ) | |||
| * | |||
| * C := C - V * W**H | |||
| * | |||
| @@ -419,20 +406,20 @@ | |||
| * C1 := C1 - V1 * W**H | |||
| * | |||
| CALL CGEMM( 'No transpose', 'Conjugate transpose', | |||
| $ M-K, LASTC, K, -ONE, V, LDV, WORK, LDWORK, | |||
| $ ONE, C, LDC ) | |||
| $ M-K, N, K, -ONE, V, LDV, WORK, LDWORK, | |||
| $ ONE, C, LDC ) | |||
| END IF | |||
| * | |||
| * W := W * V2**H | |||
| * | |||
| CALL CTRMM( 'Right', 'Upper', 'Conjugate transpose', | |||
| $ 'Unit', LASTC, K, ONE, V( M-K+1, 1 ), LDV, | |||
| $ WORK, LDWORK ) | |||
| $ 'Unit', N, K, ONE, V( M-K+1, 1 ), LDV, WORK, | |||
| $ LDWORK ) | |||
| * | |||
| * C2 := C2 - W**H | |||
| * | |||
| DO 90 J = 1, K | |||
| DO 80 I = 1, LASTC | |||
| DO 80 I = 1, N | |||
| C( M-K+J, I ) = C( M-K+J, I ) - | |||
| $ CONJG( WORK( I, J ) ) | |||
| 80 CONTINUE | |||
| @@ -441,36 +428,31 @@ | |||
| ELSE IF( LSAME( SIDE, 'R' ) ) THEN | |||
| * | |||
| * Form C * H or C * H**H where C = ( C1 C2 ) | |||
| * | |||
| LASTC = ILACLR( M, N, C, LDC ) | |||
| * | |||
| * W := C * V = (C1*V1 + C2*V2) (stored in WORK) | |||
| * | |||
| * W := C2 | |||
| * | |||
| DO 100 J = 1, K | |||
| CALL CCOPY( LASTC, C( 1, N-K+J ), 1, | |||
| $ WORK( 1, J ), 1 ) | |||
| CALL CCOPY( M, C( 1, N-K+J ), 1, WORK( 1, J ), 1 ) | |||
| 100 CONTINUE | |||
| * | |||
| * W := W * V2 | |||
| * | |||
| CALL CTRMM( 'Right', 'Upper', 'No transpose', 'Unit', | |||
| $ LASTC, K, ONE, V( N-K+1, 1 ), LDV, | |||
| $ WORK, LDWORK ) | |||
| CALL CTRMM( 'Right', 'Upper', 'No transpose', 'Unit', M, | |||
| $ K, ONE, V( N-K+1, 1 ), LDV, WORK, LDWORK ) | |||
| IF( N.GT.K ) THEN | |||
| * | |||
| * W := W + C1 * V1 | |||
| * | |||
| CALL CGEMM( 'No transpose', 'No transpose', | |||
| $ LASTC, K, N-K, | |||
| $ ONE, C, LDC, V, LDV, ONE, WORK, LDWORK ) | |||
| CALL CGEMM( 'No transpose', 'No transpose', M, K, N-K, | |||
| $ ONE, C, LDC, V, LDV, ONE, WORK, LDWORK ) | |||
| END IF | |||
| * | |||
| * W := W * T or W * T**H | |||
| * | |||
| CALL CTRMM( 'Right', 'Lower', TRANS, 'Non-unit', | |||
| $ LASTC, K, ONE, T, LDT, WORK, LDWORK ) | |||
| CALL CTRMM( 'Right', 'Lower', TRANS, 'Non-unit', M, K, | |||
| $ ONE, T, LDT, WORK, LDWORK ) | |||
| * | |||
| * C := C - W * V**H | |||
| * | |||
| @@ -478,23 +460,22 @@ | |||
| * | |||
| * C1 := C1 - W * V1**H | |||
| * | |||
| CALL CGEMM( 'No transpose', 'Conjugate transpose', | |||
| $ LASTC, N-K, K, -ONE, WORK, LDWORK, V, LDV, | |||
| $ ONE, C, LDC ) | |||
| CALL CGEMM( 'No transpose', 'Conjugate transpose', M, | |||
| $ N-K, K, -ONE, WORK, LDWORK, V, LDV, ONE, | |||
| $ C, LDC ) | |||
| END IF | |||
| * | |||
| * W := W * V2**H | |||
| * | |||
| CALL CTRMM( 'Right', 'Upper', 'Conjugate transpose', | |||
| $ 'Unit', LASTC, K, ONE, V( N-K+1, 1 ), LDV, | |||
| $ WORK, LDWORK ) | |||
| $ 'Unit', M, K, ONE, V( N-K+1, 1 ), LDV, WORK, | |||
| $ LDWORK ) | |||
| * | |||
| * C2 := C2 - W | |||
| * | |||
| DO 120 J = 1, K | |||
| DO 110 I = 1, LASTC | |||
| C( I, N-K+J ) = C( I, N-K+J ) | |||
| $ - WORK( I, J ) | |||
| DO 110 I = 1, M | |||
| C( I, N-K+J ) = C( I, N-K+J ) - WORK( I, J ) | |||
| 110 CONTINUE | |||
| 120 CONTINUE | |||
| END IF | |||
| @@ -511,59 +492,56 @@ | |||
| * | |||
| * Form H * C or H**H * C where C = ( C1 ) | |||
| * ( C2 ) | |||
| * | |||
| LASTV = MAX( K, ILACLC( K, M, V, LDV ) ) | |||
| LASTC = ILACLC( LASTV, N, C, LDC ) | |||
| * | |||
| * W := C**H * V**H = (C1**H * V1**H + C2**H * V2**H) (stored in WORK) | |||
| * | |||
| * W := C1**H | |||
| * | |||
| DO 130 J = 1, K | |||
| CALL CCOPY( LASTC, C( J, 1 ), LDC, WORK( 1, J ), 1 ) | |||
| CALL CLACGV( LASTC, WORK( 1, J ), 1 ) | |||
| CALL CCOPY( N, C( J, 1 ), LDC, WORK( 1, J ), 1 ) | |||
| CALL CLACGV( N, WORK( 1, J ), 1 ) | |||
| 130 CONTINUE | |||
| * | |||
| * W := W * V1**H | |||
| * | |||
| CALL CTRMM( 'Right', 'Upper', 'Conjugate transpose', | |||
| $ 'Unit', LASTC, K, ONE, V, LDV, WORK, LDWORK ) | |||
| IF( LASTV.GT.K ) THEN | |||
| $ 'Unit', N, K, ONE, V, LDV, WORK, LDWORK ) | |||
| IF( M.GT.K ) THEN | |||
| * | |||
| * W := W + C2**H*V2**H | |||
| * W := W + C2**H * V2**H | |||
| * | |||
| CALL CGEMM( 'Conjugate transpose', | |||
| $ 'Conjugate transpose', LASTC, K, LASTV-K, | |||
| $ ONE, C( K+1, 1 ), LDC, V( 1, K+1 ), LDV, | |||
| $ ONE, WORK, LDWORK ) | |||
| $ 'Conjugate transpose', N, K, M-K, ONE, | |||
| $ C( K+1, 1 ), LDC, V( 1, K+1 ), LDV, ONE, | |||
| $ WORK, LDWORK ) | |||
| END IF | |||
| * | |||
| * W := W * T**H or W * T | |||
| * | |||
| CALL CTRMM( 'Right', 'Upper', TRANST, 'Non-unit', | |||
| $ LASTC, K, ONE, T, LDT, WORK, LDWORK ) | |||
| CALL CTRMM( 'Right', 'Upper', TRANST, 'Non-unit', N, K, | |||
| $ ONE, T, LDT, WORK, LDWORK ) | |||
| * | |||
| * C := C - V**H * W**H | |||
| * | |||
| IF( LASTV.GT.K ) THEN | |||
| IF( M.GT.K ) THEN | |||
| * | |||
| * C2 := C2 - V2**H * W**H | |||
| * | |||
| CALL CGEMM( 'Conjugate transpose', | |||
| $ 'Conjugate transpose', LASTV-K, LASTC, K, | |||
| $ -ONE, V( 1, K+1 ), LDV, WORK, LDWORK, | |||
| $ ONE, C( K+1, 1 ), LDC ) | |||
| $ 'Conjugate transpose', M-K, N, K, -ONE, | |||
| $ V( 1, K+1 ), LDV, WORK, LDWORK, ONE, | |||
| $ C( K+1, 1 ), LDC ) | |||
| END IF | |||
| * | |||
| * W := W * V1 | |||
| * | |||
| CALL CTRMM( 'Right', 'Upper', 'No transpose', 'Unit', | |||
| $ LASTC, K, ONE, V, LDV, WORK, LDWORK ) | |||
| CALL CTRMM( 'Right', 'Upper', 'No transpose', 'Unit', N, | |||
| $ K, ONE, V, LDV, WORK, LDWORK ) | |||
| * | |||
| * C1 := C1 - W**H | |||
| * | |||
| DO 150 J = 1, K | |||
| DO 140 I = 1, LASTC | |||
| DO 140 I = 1, N | |||
| C( J, I ) = C( J, I ) - CONJG( WORK( I, J ) ) | |||
| 140 CONTINUE | |||
| 150 CONTINUE | |||
| @@ -571,57 +549,53 @@ | |||
| ELSE IF( LSAME( SIDE, 'R' ) ) THEN | |||
| * | |||
| * Form C * H or C * H**H where C = ( C1 C2 ) | |||
| * | |||
| LASTV = MAX( K, ILACLC( K, N, V, LDV ) ) | |||
| LASTC = ILACLR( M, LASTV, C, LDC ) | |||
| * | |||
| * W := C * V**H = (C1*V1**H + C2*V2**H) (stored in WORK) | |||
| * | |||
| * W := C1 | |||
| * | |||
| DO 160 J = 1, K | |||
| CALL CCOPY( LASTC, C( 1, J ), 1, WORK( 1, J ), 1 ) | |||
| CALL CCOPY( M, C( 1, J ), 1, WORK( 1, J ), 1 ) | |||
| 160 CONTINUE | |||
| * | |||
| * W := W * V1**H | |||
| * | |||
| CALL CTRMM( 'Right', 'Upper', 'Conjugate transpose', | |||
| $ 'Unit', LASTC, K, ONE, V, LDV, WORK, LDWORK ) | |||
| IF( LASTV.GT.K ) THEN | |||
| $ 'Unit', M, K, ONE, V, LDV, WORK, LDWORK ) | |||
| IF( N.GT.K ) THEN | |||
| * | |||
| * W := W + C2 * V2**H | |||
| * | |||
| CALL CGEMM( 'No transpose', 'Conjugate transpose', | |||
| $ LASTC, K, LASTV-K, ONE, C( 1, K+1 ), LDC, | |||
| $ V( 1, K+1 ), LDV, ONE, WORK, LDWORK ) | |||
| CALL CGEMM( 'No transpose', 'Conjugate transpose', M, | |||
| $ K, N-K, ONE, C( 1, K+1 ), LDC, | |||
| $ V( 1, K+1 ), LDV, ONE, WORK, LDWORK ) | |||
| END IF | |||
| * | |||
| * W := W * T or W * T**H | |||
| * | |||
| CALL CTRMM( 'Right', 'Upper', TRANS, 'Non-unit', | |||
| $ LASTC, K, ONE, T, LDT, WORK, LDWORK ) | |||
| CALL CTRMM( 'Right', 'Upper', TRANS, 'Non-unit', M, K, | |||
| $ ONE, T, LDT, WORK, LDWORK ) | |||
| * | |||
| * C := C - W * V | |||
| * | |||
| IF( LASTV.GT.K ) THEN | |||
| IF( N.GT.K ) THEN | |||
| * | |||
| * C2 := C2 - W * V2 | |||
| * | |||
| CALL CGEMM( 'No transpose', 'No transpose', | |||
| $ LASTC, LASTV-K, K, | |||
| $ -ONE, WORK, LDWORK, V( 1, K+1 ), LDV, | |||
| $ ONE, C( 1, K+1 ), LDC ) | |||
| CALL CGEMM( 'No transpose', 'No transpose', M, N-K, K, | |||
| $ -ONE, WORK, LDWORK, V( 1, K+1 ), LDV, ONE, | |||
| $ C( 1, K+1 ), LDC ) | |||
| END IF | |||
| * | |||
| * W := W * V1 | |||
| * | |||
| CALL CTRMM( 'Right', 'Upper', 'No transpose', 'Unit', | |||
| $ LASTC, K, ONE, V, LDV, WORK, LDWORK ) | |||
| CALL CTRMM( 'Right', 'Upper', 'No transpose', 'Unit', M, | |||
| $ K, ONE, V, LDV, WORK, LDWORK ) | |||
| * | |||
| * C1 := C1 - W | |||
| * | |||
| DO 180 J = 1, K | |||
| DO 170 I = 1, LASTC | |||
| DO 170 I = 1, M | |||
| C( I, J ) = C( I, J ) - WORK( I, J ) | |||
| 170 CONTINUE | |||
| 180 CONTINUE | |||
| @@ -637,37 +611,34 @@ | |||
| * | |||
| * Form H * C or H**H * C where C = ( C1 ) | |||
| * ( C2 ) | |||
| * | |||
| LASTC = ILACLC( M, N, C, LDC ) | |||
| * | |||
| * W := C**H * V**H = (C1**H * V1**H + C2**H * V2**H) (stored in WORK) | |||
| * | |||
| * W := C2**H | |||
| * | |||
| DO 190 J = 1, K | |||
| CALL CCOPY( LASTC, C( M-K+J, 1 ), LDC, | |||
| $ WORK( 1, J ), 1 ) | |||
| CALL CLACGV( LASTC, WORK( 1, J ), 1 ) | |||
| CALL CCOPY( N, C( M-K+J, 1 ), LDC, WORK( 1, J ), 1 ) | |||
| CALL CLACGV( N, WORK( 1, J ), 1 ) | |||
| 190 CONTINUE | |||
| * | |||
| * W := W * V2**H | |||
| * | |||
| CALL CTRMM( 'Right', 'Lower', 'Conjugate transpose', | |||
| $ 'Unit', LASTC, K, ONE, V( 1, M-K+1 ), LDV, | |||
| $ WORK, LDWORK ) | |||
| $ 'Unit', N, K, ONE, V( 1, M-K+1 ), LDV, WORK, | |||
| $ LDWORK ) | |||
| IF( M.GT.K ) THEN | |||
| * | |||
| * W := W + C1**H * V1**H | |||
| * | |||
| CALL CGEMM( 'Conjugate transpose', | |||
| $ 'Conjugate transpose', LASTC, K, M-K, | |||
| $ ONE, C, LDC, V, LDV, ONE, WORK, LDWORK ) | |||
| $ 'Conjugate transpose', N, K, M-K, ONE, C, | |||
| $ LDC, V, LDV, ONE, WORK, LDWORK ) | |||
| END IF | |||
| * | |||
| * W := W * T**H or W * T | |||
| * | |||
| CALL CTRMM( 'Right', 'Lower', TRANST, 'Non-unit', | |||
| $ LASTC, K, ONE, T, LDT, WORK, LDWORK ) | |||
| CALL CTRMM( 'Right', 'Lower', TRANST, 'Non-unit', N, K, | |||
| $ ONE, T, LDT, WORK, LDWORK ) | |||
| * | |||
| * C := C - V**H * W**H | |||
| * | |||
| @@ -676,20 +647,19 @@ | |||
| * C1 := C1 - V1**H * W**H | |||
| * | |||
| CALL CGEMM( 'Conjugate transpose', | |||
| $ 'Conjugate transpose', M-K, LASTC, K, | |||
| $ -ONE, V, LDV, WORK, LDWORK, ONE, C, LDC ) | |||
| $ 'Conjugate transpose', M-K, N, K, -ONE, V, | |||
| $ LDV, WORK, LDWORK, ONE, C, LDC ) | |||
| END IF | |||
| * | |||
| * W := W * V2 | |||
| * | |||
| CALL CTRMM( 'Right', 'Lower', 'No transpose', 'Unit', | |||
| $ LASTC, K, ONE, V( 1, M-K+1 ), LDV, | |||
| $ WORK, LDWORK ) | |||
| CALL CTRMM( 'Right', 'Lower', 'No transpose', 'Unit', N, | |||
| $ K, ONE, V( 1, M-K+1 ), LDV, WORK, LDWORK ) | |||
| * | |||
| * C2 := C2 - W**H | |||
| * | |||
| DO 210 J = 1, K | |||
| DO 200 I = 1, LASTC | |||
| DO 200 I = 1, N | |||
| C( M-K+J, I ) = C( M-K+J, I ) - | |||
| $ CONJG( WORK( I, J ) ) | |||
| 200 CONTINUE | |||
| @@ -698,36 +668,33 @@ | |||
| ELSE IF( LSAME( SIDE, 'R' ) ) THEN | |||
| * | |||
| * Form C * H or C * H**H where C = ( C1 C2 ) | |||
| * | |||
| LASTC = ILACLR( M, N, C, LDC ) | |||
| * | |||
| * W := C * V**H = (C1*V1**H + C2*V2**H) (stored in WORK) | |||
| * | |||
| * W := C2 | |||
| * | |||
| DO 220 J = 1, K | |||
| CALL CCOPY( LASTC, C( 1, N-K+J ), 1, | |||
| $ WORK( 1, J ), 1 ) | |||
| CALL CCOPY( M, C( 1, N-K+J ), 1, WORK( 1, J ), 1 ) | |||
| 220 CONTINUE | |||
| * | |||
| * W := W * V2**H | |||
| * | |||
| CALL CTRMM( 'Right', 'Lower', 'Conjugate transpose', | |||
| $ 'Unit', LASTC, K, ONE, V( 1, N-K+1 ), LDV, | |||
| $ WORK, LDWORK ) | |||
| $ 'Unit', M, K, ONE, V( 1, N-K+1 ), LDV, WORK, | |||
| $ LDWORK ) | |||
| IF( N.GT.K ) THEN | |||
| * | |||
| * W := W + C1 * V1**H | |||
| * | |||
| CALL CGEMM( 'No transpose', 'Conjugate transpose', | |||
| $ LASTC, K, N-K, ONE, C, LDC, V, LDV, ONE, | |||
| $ WORK, LDWORK ) | |||
| CALL CGEMM( 'No transpose', 'Conjugate transpose', M, | |||
| $ K, N-K, ONE, C, LDC, V, LDV, ONE, WORK, | |||
| $ LDWORK ) | |||
| END IF | |||
| * | |||
| * W := W * T or W * T**H | |||
| * | |||
| CALL CTRMM( 'Right', 'Lower', TRANS, 'Non-unit', | |||
| $ LASTC, K, ONE, T, LDT, WORK, LDWORK ) | |||
| CALL CTRMM( 'Right', 'Lower', TRANS, 'Non-unit', M, K, | |||
| $ ONE, T, LDT, WORK, LDWORK ) | |||
| * | |||
| * C := C - W * V | |||
| * | |||
| @@ -735,21 +702,19 @@ | |||
| * | |||
| * C1 := C1 - W * V1 | |||
| * | |||
| CALL CGEMM( 'No transpose', 'No transpose', | |||
| $ LASTC, N-K, K, -ONE, WORK, LDWORK, V, LDV, | |||
| $ ONE, C, LDC ) | |||
| CALL CGEMM( 'No transpose', 'No transpose', M, N-K, K, | |||
| $ -ONE, WORK, LDWORK, V, LDV, ONE, C, LDC ) | |||
| END IF | |||
| * | |||
| * W := W * V2 | |||
| * | |||
| CALL CTRMM( 'Right', 'Lower', 'No transpose', 'Unit', | |||
| $ LASTC, K, ONE, V( 1, N-K+1 ), LDV, | |||
| $ WORK, LDWORK ) | |||
| CALL CTRMM( 'Right', 'Lower', 'No transpose', 'Unit', M, | |||
| $ K, ONE, V( 1, N-K+1 ), LDV, WORK, LDWORK ) | |||
| * | |||
| * C1 := C1 - W | |||
| * | |||
| DO 240 J = 1, K | |||
| DO 230 I = 1, LASTC | |||
| DO 230 I = 1, M | |||
| C( I, N-K+J ) = C( I, N-K+J ) - WORK( I, J ) | |||
| 230 CONTINUE | |||
| 240 CONTINUE | |||
| @@ -85,7 +85,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date September 2012 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup complexOTHERauxiliary | |||
| * | |||
| @@ -103,10 +103,10 @@ | |||
| * ===================================================================== | |||
| SUBROUTINE CLARTG( F, G, CS, SN, R ) | |||
| * | |||
| * -- LAPACK auxiliary routine (version 3.4.2) -- | |||
| * -- LAPACK auxiliary routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * September 2012 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| REAL CS | |||
| @@ -130,7 +130,8 @@ | |||
| * .. | |||
| * .. External Functions .. | |||
| REAL SLAMCH, SLAPY2 | |||
| EXTERNAL SLAMCH, SLAPY2 | |||
| LOGICAL SISNAN | |||
| EXTERNAL SLAMCH, SLAPY2, SISNAN | |||
| * .. | |||
| * .. Intrinsic Functions .. | |||
| INTRINSIC ABS, AIMAG, CMPLX, CONJG, INT, LOG, MAX, REAL, | |||
| @@ -139,26 +140,17 @@ | |||
| * .. Statement Functions .. | |||
| REAL ABS1, ABSSQ | |||
| * .. | |||
| * .. Save statement .. | |||
| * SAVE FIRST, SAFMX2, SAFMIN, SAFMN2 | |||
| * .. | |||
| * .. Data statements .. | |||
| * DATA FIRST / .TRUE. / | |||
| * .. | |||
| * .. Statement Function definitions .. | |||
| ABS1( FF ) = MAX( ABS( REAL( FF ) ), ABS( AIMAG( FF ) ) ) | |||
| ABSSQ( FF ) = REAL( FF )**2 + AIMAG( FF )**2 | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * IF( FIRST ) THEN | |||
| SAFMIN = SLAMCH( 'S' ) | |||
| EPS = SLAMCH( 'E' ) | |||
| SAFMN2 = SLAMCH( 'B' )**INT( LOG( SAFMIN / EPS ) / | |||
| $ LOG( SLAMCH( 'B' ) ) / TWO ) | |||
| SAFMX2 = ONE / SAFMN2 | |||
| * FIRST = .FALSE. | |||
| * END IF | |||
| SAFMIN = SLAMCH( 'S' ) | |||
| EPS = SLAMCH( 'E' ) | |||
| SAFMN2 = SLAMCH( 'B' )**INT( LOG( SAFMIN / EPS ) / | |||
| $ LOG( SLAMCH( 'B' ) ) / TWO ) | |||
| SAFMX2 = ONE / SAFMN2 | |||
| SCALE = MAX( ABS1( F ), ABS1( G ) ) | |||
| FS = F | |||
| GS = G | |||
| @@ -172,7 +164,7 @@ | |||
| IF( SCALE.GE.SAFMX2 ) | |||
| $ GO TO 10 | |||
| ELSE IF( SCALE.LE.SAFMN2 ) THEN | |||
| IF( G.EQ.CZERO ) THEN | |||
| IF( G.EQ.CZERO.OR.SISNAN( ABS( G ) ) ) THEN | |||
| CS = ONE | |||
| SN = CZERO | |||
| R = F | |||
| @@ -1,25 +1,25 @@ | |||
| *> \brief \b CLASYF computes a partial factorization of a complex symmetric matrix, using the diagonal pivoting method. | |||
| *> \brief \b CLASYF computes a partial factorization of a complex symmetric matrix using the Bunch-Kaufman diagonal pivoting method. | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download CLASYF + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/clasyf.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/clasyf.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/clasyf.f"> | |||
| *> Download CLASYF + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/clasyf.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/clasyf.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/clasyf.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE CLASYF( UPLO, N, NB, KB, A, LDA, IPIV, W, LDW, INFO ) | |||
| * | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * CHARACTER UPLO | |||
| * INTEGER INFO, KB, LDA, LDW, N, NB | |||
| @@ -28,7 +28,7 @@ | |||
| * INTEGER IPIV( * ) | |||
| * COMPLEX A( LDA, * ), W( LDW, * ) | |||
| * .. | |||
| * | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| * ============= | |||
| @@ -110,16 +110,26 @@ | |||
| *> \verbatim | |||
| *> IPIV is INTEGER array, dimension (N) | |||
| *> Details of the interchanges and the block structure of D. | |||
| *> If UPLO = 'U', only the last KB elements of IPIV are set; | |||
| *> if UPLO = 'L', only the first KB elements are set. | |||
| *> | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) were | |||
| *> interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> If UPLO = 'U' and IPIV(k) = IPIV(k-1) < 0, then rows and | |||
| *> columns k-1 and -IPIV(k) were interchanged and D(k-1:k,k-1:k) | |||
| *> is a 2-by-2 diagonal block. If UPLO = 'L' and IPIV(k) = | |||
| *> IPIV(k+1) < 0, then rows and columns k+1 and -IPIV(k) were | |||
| *> interchanged and D(k:k+1,k:k+1) is a 2-by-2 diagonal block. | |||
| *> If UPLO = 'U': | |||
| *> Only the last KB elements of IPIV are set. | |||
| *> | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) were | |||
| *> interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) = IPIV(k-1) < 0, then rows and columns | |||
| *> k-1 and -IPIV(k) were interchanged and D(k-1:k,k-1:k) | |||
| *> is a 2-by-2 diagonal block. | |||
| *> | |||
| *> If UPLO = 'L': | |||
| *> Only the first KB elements of IPIV are set. | |||
| *> | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) were | |||
| *> interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) = IPIV(k+1) < 0, then rows and columns | |||
| *> k+1 and -IPIV(k) were interchanged and D(k:k+1,k:k+1) | |||
| *> is a 2-by-2 diagonal block. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] W | |||
| @@ -145,22 +155,32 @@ | |||
| * Authors: | |||
| * ======== | |||
| * | |||
| *> \author Univ. of Tennessee | |||
| *> \author Univ. of California Berkeley | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| *> \author Univ. of Tennessee | |||
| *> \author Univ. of California Berkeley | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date September 2012 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup complexSYcomputational | |||
| * | |||
| *> \par Contributors: | |||
| * ================== | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> November 2013, Igor Kozachenko, | |||
| *> Computer Science Division, | |||
| *> University of California, Berkeley | |||
| *> \endverbatim | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE CLASYF( UPLO, N, NB, KB, A, LDA, IPIV, W, LDW, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.2) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * September 2012 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER UPLO | |||
| @@ -246,7 +266,8 @@ | |||
| ABSAKK = CABS1( W( K, KW ) ) | |||
| * | |||
| * IMAX is the row-index of the largest off-diagonal element in | |||
| * column K, and COLMAX is its absolute value | |||
| * column K, and COLMAX is its absolute value. | |||
| * Determine both COLMAX and IMAX. | |||
| * | |||
| IF( K.GT.1 ) THEN | |||
| IMAX = ICAMAX( K-1, W( 1, KW ), 1 ) | |||
| @@ -257,7 +278,7 @@ | |||
| * | |||
| IF( MAX( ABSAKK, COLMAX ).EQ.ZERO ) THEN | |||
| * | |||
| * Column K is zero: set INFO and continue | |||
| * Column K is zero or underflow: set INFO and continue | |||
| * | |||
| IF( INFO.EQ.0 ) | |||
| $ INFO = K | |||
| @@ -302,7 +323,7 @@ | |||
| * | |||
| KP = IMAX | |||
| * | |||
| * copy column KW-1 of W to column KW | |||
| * copy column KW-1 of W to column KW of W | |||
| * | |||
| CALL CCOPY( K, W( 1, KW-1 ), 1, W( 1, KW ), 1 ) | |||
| ELSE | |||
| @@ -314,59 +335,117 @@ | |||
| KSTEP = 2 | |||
| END IF | |||
| END IF | |||
| * | |||
| * ============================================================ | |||
| * | |||
| * KK is the column of A where pivoting step stopped | |||
| * | |||
| KK = K - KSTEP + 1 | |||
| * | |||
| * KKW is the column of W which corresponds to column KK of A | |||
| * | |||
| KKW = NB + KK - N | |||
| * | |||
| * Updated column KP is already stored in column KKW of W | |||
| * Interchange rows and columns KP and KK. | |||
| * Updated column KP is already stored in column KKW of W. | |||
| * | |||
| IF( KP.NE.KK ) THEN | |||
| * | |||
| * Copy non-updated column KK to column KP | |||
| * Copy non-updated column KK to column KP of submatrix A | |||
| * at step K. No need to copy element into column K | |||
| * (or K and K-1 for 2-by-2 pivot) of A, since these columns | |||
| * will be later overwritten. | |||
| * | |||
| A( KP, K ) = A( KK, K ) | |||
| CALL CCOPY( K-1-KP, A( KP+1, KK ), 1, A( KP, KP+1 ), | |||
| A( KP, KP ) = A( KK, KK ) | |||
| CALL CCOPY( KK-1-KP, A( KP+1, KK ), 1, A( KP, KP+1 ), | |||
| $ LDA ) | |||
| CALL CCOPY( KP, A( 1, KK ), 1, A( 1, KP ), 1 ) | |||
| IF( KP.GT.1 ) | |||
| $ CALL CCOPY( KP-1, A( 1, KK ), 1, A( 1, KP ), 1 ) | |||
| * | |||
| * Interchange rows KK and KP in last KK columns of A and W | |||
| * Interchange rows KK and KP in last K+1 to N columns of A | |||
| * (columns K (or K and K-1 for 2-by-2 pivot) of A will be | |||
| * later overwritten). Interchange rows KK and KP | |||
| * in last KKW to NB columns of W. | |||
| * | |||
| CALL CSWAP( N-KK+1, A( KK, KK ), LDA, A( KP, KK ), LDA ) | |||
| IF( K.LT.N ) | |||
| $ CALL CSWAP( N-K, A( KK, K+1 ), LDA, A( KP, K+1 ), | |||
| $ LDA ) | |||
| CALL CSWAP( N-KK+1, W( KK, KKW ), LDW, W( KP, KKW ), | |||
| $ LDW ) | |||
| END IF | |||
| * | |||
| IF( KSTEP.EQ.1 ) THEN | |||
| * | |||
| * 1-by-1 pivot block D(k): column KW of W now holds | |||
| * 1-by-1 pivot block D(k): column kw of W now holds | |||
| * | |||
| * W(k) = U(k)*D(k) | |||
| * W(kw) = U(k)*D(k), | |||
| * | |||
| * where U(k) is the k-th column of U | |||
| * | |||
| * Store U(k) in column k of A | |||
| * Store subdiag. elements of column U(k) | |||
| * and 1-by-1 block D(k) in column k of A. | |||
| * NOTE: Diagonal element U(k,k) is a UNIT element | |||
| * and not stored. | |||
| * A(k,k) := D(k,k) = W(k,kw) | |||
| * A(1:k-1,k) := U(1:k-1,k) = W(1:k-1,kw)/D(k,k) | |||
| * | |||
| CALL CCOPY( K, W( 1, KW ), 1, A( 1, K ), 1 ) | |||
| R1 = CONE / A( K, K ) | |||
| CALL CSCAL( K-1, R1, A( 1, K ), 1 ) | |||
| * | |||
| ELSE | |||
| * | |||
| * 2-by-2 pivot block D(k): columns KW and KW-1 of W now | |||
| * hold | |||
| * 2-by-2 pivot block D(k): columns kw and kw-1 of W now hold | |||
| * | |||
| * ( W(k-1) W(k) ) = ( U(k-1) U(k) )*D(k) | |||
| * ( W(kw-1) W(kw) ) = ( U(k-1) U(k) )*D(k) | |||
| * | |||
| * where U(k) and U(k-1) are the k-th and (k-1)-th columns | |||
| * of U | |||
| * | |||
| * Store U(1:k-2,k-1) and U(1:k-2,k) and 2-by-2 | |||
| * block D(k-1:k,k-1:k) in columns k-1 and k of A. | |||
| * NOTE: 2-by-2 diagonal block U(k-1:k,k-1:k) is a UNIT | |||
| * block and not stored. | |||
| * A(k-1:k,k-1:k) := D(k-1:k,k-1:k) = W(k-1:k,kw-1:kw) | |||
| * A(1:k-2,k-1:k) := U(1:k-2,k:k-1:k) = | |||
| * = W(1:k-2,kw-1:kw) * ( D(k-1:k,k-1:k)**(-1) ) | |||
| * | |||
| IF( K.GT.2 ) THEN | |||
| * | |||
| * Store U(k) and U(k-1) in columns k and k-1 of A | |||
| * Compose the columns of the inverse of 2-by-2 pivot | |||
| * block D in the following way to reduce the number | |||
| * of FLOPS when we myltiply panel ( W(kw-1) W(kw) ) by | |||
| * this inverse | |||
| * | |||
| * D**(-1) = ( d11 d21 )**(-1) = | |||
| * ( d21 d22 ) | |||
| * | |||
| * = 1/(d11*d22-d21**2) * ( ( d22 ) (-d21 ) ) = | |||
| * ( (-d21 ) ( d11 ) ) | |||
| * | |||
| * = 1/d21 * 1/((d11/d21)*(d22/d21)-1) * | |||
| * | |||
| * * ( ( d22/d21 ) ( -1 ) ) = | |||
| * ( ( -1 ) ( d11/d21 ) ) | |||
| * | |||
| * = 1/d21 * 1/(D22*D11-1) * ( ( D11 ) ( -1 ) ) = | |||
| * ( ( -1 ) ( D22 ) ) | |||
| * | |||
| * = 1/d21 * T * ( ( D11 ) ( -1 ) ) | |||
| * ( ( -1 ) ( D22 ) ) | |||
| * | |||
| * = D21 * ( ( D11 ) ( -1 ) ) | |||
| * ( ( -1 ) ( D22 ) ) | |||
| * | |||
| D21 = W( K-1, KW ) | |||
| D11 = W( K, KW ) / D21 | |||
| D22 = W( K-1, KW-1 ) / D21 | |||
| T = CONE / ( D11*D22-CONE ) | |||
| * | |||
| * Update elements in columns A(k-1) and A(k) as | |||
| * dot products of rows of ( W(kw-1) W(kw) ) and columns | |||
| * of D**(-1) | |||
| * | |||
| D21 = T / D21 | |||
| DO 20 J = 1, K - 2 | |||
| A( J, K-1 ) = D21*( D11*W( J, KW-1 )-W( J, KW ) ) | |||
| @@ -379,7 +458,9 @@ | |||
| A( K-1, K-1 ) = W( K-1, KW-1 ) | |||
| A( K-1, K ) = W( K-1, KW ) | |||
| A( K, K ) = W( K, KW ) | |||
| * | |||
| END IF | |||
| * | |||
| END IF | |||
| * | |||
| * Store details of the interchanges in IPIV | |||
| @@ -423,20 +504,28 @@ | |||
| 50 CONTINUE | |||
| * | |||
| * Put U12 in standard form by partially undoing the interchanges | |||
| * in columns k+1:n | |||
| * in columns k+1:n looping backwards from k+1 to n | |||
| * | |||
| J = K + 1 | |||
| 60 CONTINUE | |||
| JJ = J | |||
| JP = IPIV( J ) | |||
| IF( JP.LT.0 ) THEN | |||
| JP = -JP | |||
| * | |||
| * Undo the interchanges (if any) of rows JJ and JP at each | |||
| * step J | |||
| * | |||
| * (Here, J is a diagonal index) | |||
| JJ = J | |||
| JP = IPIV( J ) | |||
| IF( JP.LT.0 ) THEN | |||
| JP = -JP | |||
| * (Here, J is a diagonal index) | |||
| J = J + 1 | |||
| END IF | |||
| * (NOTE: Here, J is used to determine row length. Length N-J+1 | |||
| * of the rows to swap back doesn't include diagonal element) | |||
| J = J + 1 | |||
| END IF | |||
| J = J + 1 | |||
| IF( JP.NE.JJ .AND. J.LE.N ) | |||
| $ CALL CSWAP( N-J+1, A( JP, J ), LDA, A( JJ, J ), LDA ) | |||
| IF( J.LE.N ) | |||
| IF( JP.NE.JJ .AND. J.LE.N ) | |||
| $ CALL CSWAP( N-J+1, A( JP, J ), LDA, A( JJ, J ), LDA ) | |||
| IF( J.LT.N ) | |||
| $ GO TO 60 | |||
| * | |||
| * Set KB to the number of columns factorized | |||
| @@ -473,7 +562,8 @@ | |||
| ABSAKK = CABS1( W( K, K ) ) | |||
| * | |||
| * IMAX is the row-index of the largest off-diagonal element in | |||
| * column K, and COLMAX is its absolute value | |||
| * column K, and COLMAX is its absolute value. | |||
| * Determine both COLMAX and IMAX. | |||
| * | |||
| IF( K.LT.N ) THEN | |||
| IMAX = K + ICAMAX( N-K, W( K+1, K ), 1 ) | |||
| @@ -484,7 +574,7 @@ | |||
| * | |||
| IF( MAX( ABSAKK, COLMAX ).EQ.ZERO ) THEN | |||
| * | |||
| * Column K is zero: set INFO and continue | |||
| * Column K is zero or underflow: set INFO and continue | |||
| * | |||
| IF( INFO.EQ.0 ) | |||
| $ INFO = K | |||
| @@ -528,7 +618,7 @@ | |||
| * | |||
| KP = IMAX | |||
| * | |||
| * copy column K+1 of W to column K | |||
| * copy column K+1 of W to column K of W | |||
| * | |||
| CALL CCOPY( N-K+1, W( K, K+1 ), 1, W( K, K ), 1 ) | |||
| ELSE | |||
| @@ -540,22 +630,36 @@ | |||
| KSTEP = 2 | |||
| END IF | |||
| END IF | |||
| * | |||
| * ============================================================ | |||
| * | |||
| * KK is the column of A where pivoting step stopped | |||
| * | |||
| KK = K + KSTEP - 1 | |||
| * | |||
| * Updated column KP is already stored in column KK of W | |||
| * Interchange rows and columns KP and KK. | |||
| * Updated column KP is already stored in column KK of W. | |||
| * | |||
| IF( KP.NE.KK ) THEN | |||
| * | |||
| * Copy non-updated column KK to column KP | |||
| * Copy non-updated column KK to column KP of submatrix A | |||
| * at step K. No need to copy element into column K | |||
| * (or K and K+1 for 2-by-2 pivot) of A, since these columns | |||
| * will be later overwritten. | |||
| * | |||
| A( KP, K ) = A( KK, K ) | |||
| CALL CCOPY( KP-K-1, A( K+1, KK ), 1, A( KP, K+1 ), LDA ) | |||
| CALL CCOPY( N-KP+1, A( KP, KK ), 1, A( KP, KP ), 1 ) | |||
| A( KP, KP ) = A( KK, KK ) | |||
| CALL CCOPY( KP-KK-1, A( KK+1, KK ), 1, A( KP, KK+1 ), | |||
| $ LDA ) | |||
| IF( KP.LT.N ) | |||
| $ CALL CCOPY( N-KP, A( KP+1, KK ), 1, A( KP+1, KP ), 1 ) | |||
| * | |||
| * Interchange rows KK and KP in first KK columns of A and W | |||
| * Interchange rows KK and KP in first K-1 columns of A | |||
| * (columns K (or K and K+1 for 2-by-2 pivot) of A will be | |||
| * later overwritten). Interchange rows KK and KP | |||
| * in first KK columns of W. | |||
| * | |||
| CALL CSWAP( KK, A( KK, 1 ), LDA, A( KP, 1 ), LDA ) | |||
| IF( K.GT.1 ) | |||
| $ CALL CSWAP( K-1, A( KK, 1 ), LDA, A( KP, 1 ), LDA ) | |||
| CALL CSWAP( KK, W( KK, 1 ), LDW, W( KP, 1 ), LDW ) | |||
| END IF | |||
| * | |||
| @@ -563,17 +667,23 @@ | |||
| * | |||
| * 1-by-1 pivot block D(k): column k of W now holds | |||
| * | |||
| * W(k) = L(k)*D(k) | |||
| * W(k) = L(k)*D(k), | |||
| * | |||
| * where L(k) is the k-th column of L | |||
| * | |||
| * Store L(k) in column k of A | |||
| * Store subdiag. elements of column L(k) | |||
| * and 1-by-1 block D(k) in column k of A. | |||
| * (NOTE: Diagonal element L(k,k) is a UNIT element | |||
| * and not stored) | |||
| * A(k,k) := D(k,k) = W(k,k) | |||
| * A(k+1:N,k) := L(k+1:N,k) = W(k+1:N,k)/D(k,k) | |||
| * | |||
| CALL CCOPY( N-K+1, W( K, K ), 1, A( K, K ), 1 ) | |||
| IF( K.LT.N ) THEN | |||
| R1 = CONE / A( K, K ) | |||
| CALL CSCAL( N-K, R1, A( K+1, K ), 1 ) | |||
| END IF | |||
| * | |||
| ELSE | |||
| * | |||
| * 2-by-2 pivot block D(k): columns k and k+1 of W now hold | |||
| @@ -582,16 +692,52 @@ | |||
| * | |||
| * where L(k) and L(k+1) are the k-th and (k+1)-th columns | |||
| * of L | |||
| * | |||
| * Store L(k+2:N,k) and L(k+2:N,k+1) and 2-by-2 | |||
| * block D(k:k+1,k:k+1) in columns k and k+1 of A. | |||
| * (NOTE: 2-by-2 diagonal block L(k:k+1,k:k+1) is a UNIT | |||
| * block and not stored) | |||
| * A(k:k+1,k:k+1) := D(k:k+1,k:k+1) = W(k:k+1,k:k+1) | |||
| * A(k+2:N,k:k+1) := L(k+2:N,k:k+1) = | |||
| * = W(k+2:N,k:k+1) * ( D(k:k+1,k:k+1)**(-1) ) | |||
| * | |||
| IF( K.LT.N-1 ) THEN | |||
| * | |||
| * Store L(k) and L(k+1) in columns k and k+1 of A | |||
| * Compose the columns of the inverse of 2-by-2 pivot | |||
| * block D in the following way to reduce the number | |||
| * of FLOPS when we myltiply panel ( W(k) W(k+1) ) by | |||
| * this inverse | |||
| * | |||
| * D**(-1) = ( d11 d21 )**(-1) = | |||
| * ( d21 d22 ) | |||
| * | |||
| * = 1/(d11*d22-d21**2) * ( ( d22 ) (-d21 ) ) = | |||
| * ( (-d21 ) ( d11 ) ) | |||
| * | |||
| * = 1/d21 * 1/((d11/d21)*(d22/d21)-1) * | |||
| * | |||
| * * ( ( d22/d21 ) ( -1 ) ) = | |||
| * ( ( -1 ) ( d11/d21 ) ) | |||
| * | |||
| * = 1/d21 * 1/(D22*D11-1) * ( ( D11 ) ( -1 ) ) = | |||
| * ( ( -1 ) ( D22 ) ) | |||
| * | |||
| * = 1/d21 * T * ( ( D11 ) ( -1 ) ) | |||
| * ( ( -1 ) ( D22 ) ) | |||
| * | |||
| * = D21 * ( ( D11 ) ( -1 ) ) | |||
| * ( ( -1 ) ( D22 ) ) | |||
| * | |||
| D21 = W( K+1, K ) | |||
| D11 = W( K+1, K+1 ) / D21 | |||
| D22 = W( K, K ) / D21 | |||
| T = CONE / ( D11*D22-CONE ) | |||
| D21 = T / D21 | |||
| * | |||
| * Update elements in columns A(k) and A(k+1) as | |||
| * dot products of rows of ( W(k) W(k+1) ) and columns | |||
| * of D**(-1) | |||
| * | |||
| DO 80 J = K + 2, N | |||
| A( J, K ) = D21*( D11*W( J, K )-W( J, K+1 ) ) | |||
| A( J, K+1 ) = D21*( D22*W( J, K+1 )-W( J, K ) ) | |||
| @@ -603,7 +749,9 @@ | |||
| A( K, K ) = W( K, K ) | |||
| A( K+1, K ) = W( K+1, K ) | |||
| A( K+1, K+1 ) = W( K+1, K+1 ) | |||
| * | |||
| END IF | |||
| * | |||
| END IF | |||
| * | |||
| * Store details of the interchanges in IPIV | |||
| @@ -648,20 +796,28 @@ | |||
| 110 CONTINUE | |||
| * | |||
| * Put L21 in standard form by partially undoing the interchanges | |||
| * in columns 1:k-1 | |||
| * of rows in columns 1:k-1 looping backwards from k-1 to 1 | |||
| * | |||
| J = K - 1 | |||
| 120 CONTINUE | |||
| JJ = J | |||
| JP = IPIV( J ) | |||
| IF( JP.LT.0 ) THEN | |||
| JP = -JP | |||
| * | |||
| * Undo the interchanges (if any) of rows JJ and JP at each | |||
| * step J | |||
| * | |||
| * (Here, J is a diagonal index) | |||
| JJ = J | |||
| JP = IPIV( J ) | |||
| IF( JP.LT.0 ) THEN | |||
| JP = -JP | |||
| * (Here, J is a diagonal index) | |||
| J = J - 1 | |||
| END IF | |||
| * (NOTE: Here, J is used to determine row length. Length J | |||
| * of the rows to swap back doesn't include diagonal element) | |||
| J = J - 1 | |||
| END IF | |||
| J = J - 1 | |||
| IF( JP.NE.JJ .AND. J.GE.1 ) | |||
| $ CALL CSWAP( J, A( JP, 1 ), LDA, A( JJ, 1 ), LDA ) | |||
| IF( J.GE.1 ) | |||
| IF( JP.NE.JJ .AND. J.GE.1 ) | |||
| $ CALL CSWAP( J, A( JP, 1 ), LDA, A( JJ, 1 ), LDA ) | |||
| IF( J.GT.1 ) | |||
| $ GO TO 120 | |||
| * | |||
| * Set KB to the number of columns factorized | |||
| @@ -0,0 +1,900 @@ | |||
| *> \brief \b CLASYF_ROOK computes a partial factorization of a complex symmetric matrix using the bounded Bunch-Kaufman ("rook") diagonal pivoting method. | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download CLASYF_ROOK + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/clasyf_rook.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/clasyf_rook.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/clasyf_rook.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE CLASYF_ROOK( UPLO, N, NB, KB, A, LDA, IPIV, W, LDW, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * CHARACTER UPLO | |||
| * INTEGER INFO, KB, LDA, LDW, N, NB | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * INTEGER IPIV( * ) | |||
| * COMPLEX A( LDA, * ), W( LDW, * ) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| * ============= | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> CLASYF_ROOK computes a partial factorization of a complex symmetric | |||
| *> matrix A using the bounded Bunch-Kaufman ("rook") diagonal | |||
| *> pivoting method. The partial factorization has the form: | |||
| *> | |||
| *> A = ( I U12 ) ( A11 0 ) ( I 0 ) if UPLO = 'U', or: | |||
| *> ( 0 U22 ) ( 0 D ) ( U12**T U22**T ) | |||
| *> | |||
| *> A = ( L11 0 ) ( D 0 ) ( L11**T L21**T ) if UPLO = 'L' | |||
| *> ( L21 I ) ( 0 A22 ) ( 0 I ) | |||
| *> | |||
| *> where the order of D is at most NB. The actual order is returned in | |||
| *> the argument KB, and is either NB or NB-1, or N if N <= NB. | |||
| *> | |||
| *> CLASYF_ROOK is an auxiliary routine called by CSYTRF_ROOK. It uses | |||
| *> blocked code (calling Level 3 BLAS) to update the submatrix | |||
| *> A11 (if UPLO = 'U') or A22 (if UPLO = 'L'). | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] UPLO | |||
| *> \verbatim | |||
| *> UPLO is CHARACTER*1 | |||
| *> Specifies whether the upper or lower triangular part of the | |||
| *> symmetric matrix A is stored: | |||
| *> = 'U': Upper triangular | |||
| *> = 'L': Lower triangular | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] N | |||
| *> \verbatim | |||
| *> N is INTEGER | |||
| *> The order of the matrix A. N >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] NB | |||
| *> \verbatim | |||
| *> NB is INTEGER | |||
| *> The maximum number of columns of the matrix A that should be | |||
| *> factored. NB should be at least 2 to allow for 2-by-2 pivot | |||
| *> blocks. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] KB | |||
| *> \verbatim | |||
| *> KB is INTEGER | |||
| *> The number of columns of A that were actually factored. | |||
| *> KB is either NB-1 or NB, or N if N <= NB. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] A | |||
| *> \verbatim | |||
| *> 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 | |||
| *> triangular part of A is not referenced. If UPLO = 'L', the | |||
| *> leading n-by-n lower triangular part of A contains the lower | |||
| *> triangular part of the matrix A, and the strictly upper | |||
| *> triangular part of A is not referenced. | |||
| *> On exit, A contains details of the partial factorization. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDA | |||
| *> \verbatim | |||
| *> LDA is INTEGER | |||
| *> The leading dimension of the array A. LDA >= max(1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] IPIV | |||
| *> \verbatim | |||
| *> IPIV is INTEGER array, dimension (N) | |||
| *> Details of the interchanges and the block structure of D. | |||
| *> | |||
| *> If UPLO = 'U': | |||
| *> Only the last KB elements of IPIV are set. | |||
| *> | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) were | |||
| *> interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) < 0 and IPIV(k-1) < 0, then rows and | |||
| *> columns k and -IPIV(k) were interchanged and rows and | |||
| *> columns k-1 and -IPIV(k-1) were inerchaged, | |||
| *> D(k-1:k,k-1:k) is a 2-by-2 diagonal block. | |||
| *> | |||
| *> If UPLO = 'L': | |||
| *> Only the first KB elements of IPIV are set. | |||
| *> | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) | |||
| *> were interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) < 0 and IPIV(k+1) < 0, then rows and | |||
| *> columns k and -IPIV(k) were interchanged and rows and | |||
| *> columns k+1 and -IPIV(k+1) were inerchaged, | |||
| *> D(k:k+1,k:k+1) is a 2-by-2 diagonal block. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] W | |||
| *> \verbatim | |||
| *> W is COMPLEX array, dimension (LDW,NB) | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDW | |||
| *> \verbatim | |||
| *> LDW is INTEGER | |||
| *> The leading dimension of the array W. LDW >= max(1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] INFO | |||
| *> \verbatim | |||
| *> INFO is INTEGER | |||
| *> = 0: successful exit | |||
| *> > 0: if INFO = k, D(k,k) is exactly zero. The factorization | |||
| *> has been completed, but the block diagonal matrix D is | |||
| *> exactly singular. | |||
| *> \endverbatim | |||
| * | |||
| * Authors: | |||
| * ======== | |||
| * | |||
| *> \author Univ. of Tennessee | |||
| *> \author Univ. of California Berkeley | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup complexSYcomputational | |||
| * | |||
| *> \par Contributors: | |||
| * ================== | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> November 2013, Igor Kozachenko, | |||
| *> Computer Science Division, | |||
| *> University of California, Berkeley | |||
| *> | |||
| *> September 2007, Sven Hammarling, Nicholas J. Higham, Craig Lucas, | |||
| *> School of Mathematics, | |||
| *> University of Manchester | |||
| *> | |||
| *> \endverbatim | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE CLASYF_ROOK( UPLO, N, NB, KB, A, LDA, IPIV, W, LDW, | |||
| $ INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER UPLO | |||
| INTEGER INFO, KB, LDA, LDW, N, NB | |||
| * .. | |||
| * .. Array Arguments .. | |||
| INTEGER IPIV( * ) | |||
| COMPLEX A( LDA, * ), W( LDW, * ) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| REAL ZERO, ONE | |||
| PARAMETER ( ZERO = 0.0E+0, ONE = 1.0E+0 ) | |||
| REAL EIGHT, SEVTEN | |||
| PARAMETER ( EIGHT = 8.0E+0, SEVTEN = 17.0E+0 ) | |||
| COMPLEX CONE, CZERO | |||
| PARAMETER ( CONE = ( 1.0E+0, 0.0E+0 ), | |||
| $ CZERO = ( 0.0E+0, 0.0E+0 ) ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| LOGICAL DONE | |||
| INTEGER IMAX, ITEMP, J, JB, JJ, JMAX, JP1, JP2, K, KK, | |||
| $ KW, KKW, KP, KSTEP, P, II | |||
| REAL ABSAKK, ALPHA, COLMAX, ROWMAX, STEMP, SFMIN | |||
| COMPLEX D11, D12, D21, D22, R1, T, Z | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| INTEGER ICAMAX | |||
| REAL SLAMCH | |||
| EXTERNAL LSAME, ICAMAX, SLAMCH | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL CCOPY, CGEMM, CGEMV, CSCAL, CSWAP | |||
| * .. | |||
| * .. Intrinsic Functions .. | |||
| INTRINSIC ABS, MAX, MIN, SQRT, AIMAG, REAL | |||
| * .. | |||
| * .. Statement Functions .. | |||
| REAL CABS1 | |||
| * .. | |||
| * .. Statement Function definitions .. | |||
| CABS1( Z ) = ABS( REAL( Z ) ) + ABS( AIMAG( Z ) ) | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| INFO = 0 | |||
| * | |||
| * Initialize ALPHA for use in choosing pivot block size. | |||
| * | |||
| ALPHA = ( ONE+SQRT( SEVTEN ) ) / EIGHT | |||
| * | |||
| * Compute machine safe minimum | |||
| * | |||
| SFMIN = SLAMCH( 'S' ) | |||
| * | |||
| IF( LSAME( UPLO, 'U' ) ) THEN | |||
| * | |||
| * Factorize the trailing columns of A using the upper triangle | |||
| * of A and working backwards, and compute the matrix W = U12*D | |||
| * for use in updating A11 | |||
| * | |||
| * K is the main loop index, decreasing from N in steps of 1 or 2 | |||
| * | |||
| K = N | |||
| 10 CONTINUE | |||
| * | |||
| * KW is the column of W which corresponds to column K of A | |||
| * | |||
| KW = NB + K - N | |||
| * | |||
| * Exit from loop | |||
| * | |||
| IF( ( K.LE.N-NB+1 .AND. NB.LT.N ) .OR. K.LT.1 ) | |||
| $ GO TO 30 | |||
| * | |||
| KSTEP = 1 | |||
| P = K | |||
| * | |||
| * Copy column K of A to column KW of W and update it | |||
| * | |||
| CALL CCOPY( K, A( 1, K ), 1, W( 1, KW ), 1 ) | |||
| IF( K.LT.N ) | |||
| $ CALL CGEMV( 'No transpose', K, N-K, -CONE, A( 1, K+1 ), | |||
| $ LDA, W( K, KW+1 ), LDW, CONE, W( 1, KW ), 1 ) | |||
| * | |||
| * Determine rows and columns to be interchanged and whether | |||
| * a 1-by-1 or 2-by-2 pivot block will be used | |||
| * | |||
| ABSAKK = CABS1( W( K, KW ) ) | |||
| * | |||
| * IMAX is the row-index of the largest off-diagonal element in | |||
| * column K, and COLMAX is its absolute value. | |||
| * Determine both COLMAX and IMAX. | |||
| * | |||
| IF( K.GT.1 ) THEN | |||
| IMAX = ICAMAX( K-1, W( 1, KW ), 1 ) | |||
| COLMAX = CABS1( W( IMAX, KW ) ) | |||
| ELSE | |||
| COLMAX = ZERO | |||
| END IF | |||
| * | |||
| IF( MAX( ABSAKK, COLMAX ).EQ.ZERO ) THEN | |||
| * | |||
| * Column K is zero or underflow: set INFO and continue | |||
| * | |||
| IF( INFO.EQ.0 ) | |||
| $ INFO = K | |||
| KP = K | |||
| CALL CCOPY( K, W( 1, KW ), 1, A( 1, K ), 1 ) | |||
| ELSE | |||
| * | |||
| * ============================================================ | |||
| * | |||
| * Test for interchange | |||
| * | |||
| * Equivalent to testing for ABSAKK.GE.ALPHA*COLMAX | |||
| * (used to handle NaN and Inf) | |||
| * | |||
| IF( .NOT.( ABSAKK.LT.ALPHA*COLMAX ) ) THEN | |||
| * | |||
| * no interchange, use 1-by-1 pivot block | |||
| * | |||
| KP = K | |||
| * | |||
| ELSE | |||
| * | |||
| DONE = .FALSE. | |||
| * | |||
| * Loop until pivot found | |||
| * | |||
| 12 CONTINUE | |||
| * | |||
| * Begin pivot search loop body | |||
| * | |||
| * | |||
| * Copy column IMAX to column KW-1 of W and update it | |||
| * | |||
| CALL CCOPY( IMAX, A( 1, IMAX ), 1, W( 1, KW-1 ), 1 ) | |||
| CALL CCOPY( K-IMAX, A( IMAX, IMAX+1 ), LDA, | |||
| $ W( IMAX+1, KW-1 ), 1 ) | |||
| * | |||
| IF( K.LT.N ) | |||
| $ CALL CGEMV( 'No transpose', K, N-K, -CONE, | |||
| $ A( 1, K+1 ), LDA, W( IMAX, KW+1 ), LDW, | |||
| $ CONE, W( 1, KW-1 ), 1 ) | |||
| * | |||
| * JMAX is the column-index of the largest off-diagonal | |||
| * element in row IMAX, and ROWMAX is its absolute value. | |||
| * Determine both ROWMAX and JMAX. | |||
| * | |||
| IF( IMAX.NE.K ) THEN | |||
| JMAX = IMAX + ICAMAX( K-IMAX, W( IMAX+1, KW-1 ), | |||
| $ 1 ) | |||
| ROWMAX = CABS1( W( JMAX, KW-1 ) ) | |||
| ELSE | |||
| ROWMAX = ZERO | |||
| END IF | |||
| * | |||
| IF( IMAX.GT.1 ) THEN | |||
| ITEMP = ICAMAX( IMAX-1, W( 1, KW-1 ), 1 ) | |||
| STEMP = CABS1( W( ITEMP, KW-1 ) ) | |||
| IF( STEMP.GT.ROWMAX ) THEN | |||
| ROWMAX = STEMP | |||
| JMAX = ITEMP | |||
| END IF | |||
| END IF | |||
| * | |||
| * Equivalent to testing for | |||
| * CABS1( W( IMAX, KW-1 ) ).GE.ALPHA*ROWMAX | |||
| * (used to handle NaN and Inf) | |||
| * | |||
| IF( .NOT.(CABS1( W( IMAX, KW-1 ) ).LT.ALPHA*ROWMAX ) ) | |||
| $ THEN | |||
| * | |||
| * interchange rows and columns K and IMAX, | |||
| * use 1-by-1 pivot block | |||
| * | |||
| KP = IMAX | |||
| * | |||
| * copy column KW-1 of W to column KW of W | |||
| * | |||
| CALL CCOPY( K, W( 1, KW-1 ), 1, W( 1, KW ), 1 ) | |||
| * | |||
| DONE = .TRUE. | |||
| * | |||
| * Equivalent to testing for ROWMAX.EQ.COLMAX, | |||
| * (used to handle NaN and Inf) | |||
| * | |||
| ELSE IF( ( P.EQ.JMAX ) .OR. ( ROWMAX.LE.COLMAX ) ) | |||
| $ THEN | |||
| * | |||
| * interchange rows and columns K-1 and IMAX, | |||
| * use 2-by-2 pivot block | |||
| * | |||
| KP = IMAX | |||
| KSTEP = 2 | |||
| DONE = .TRUE. | |||
| ELSE | |||
| * | |||
| * Pivot not found: set params and repeat | |||
| * | |||
| P = IMAX | |||
| COLMAX = ROWMAX | |||
| IMAX = JMAX | |||
| * | |||
| * Copy updated JMAXth (next IMAXth) column to Kth of W | |||
| * | |||
| CALL CCOPY( K, W( 1, KW-1 ), 1, W( 1, KW ), 1 ) | |||
| * | |||
| END IF | |||
| * | |||
| * End pivot search loop body | |||
| * | |||
| IF( .NOT. DONE ) GOTO 12 | |||
| * | |||
| END IF | |||
| * | |||
| * ============================================================ | |||
| * | |||
| KK = K - KSTEP + 1 | |||
| * | |||
| * KKW is the column of W which corresponds to column KK of A | |||
| * | |||
| KKW = NB + KK - N | |||
| * | |||
| IF( ( KSTEP.EQ.2 ) .AND. ( P.NE.K ) ) THEN | |||
| * | |||
| * Copy non-updated column K to column P | |||
| * | |||
| CALL CCOPY( K-P, A( P+1, K ), 1, A( P, P+1 ), LDA ) | |||
| CALL CCOPY( P, A( 1, K ), 1, A( 1, P ), 1 ) | |||
| * | |||
| * Interchange rows K and P in last N-K+1 columns of A | |||
| * and last N-K+2 columns of W | |||
| * | |||
| CALL CSWAP( N-K+1, A( K, K ), LDA, A( P, K ), LDA ) | |||
| CALL CSWAP( N-KK+1, W( K, KKW ), LDW, W( P, KKW ), LDW ) | |||
| END IF | |||
| * | |||
| * Updated column KP is already stored in column KKW of W | |||
| * | |||
| IF( KP.NE.KK ) THEN | |||
| * | |||
| * Copy non-updated column KK to column KP | |||
| * | |||
| A( KP, K ) = A( KK, K ) | |||
| CALL CCOPY( K-1-KP, A( KP+1, KK ), 1, A( KP, KP+1 ), | |||
| $ LDA ) | |||
| CALL CCOPY( KP, A( 1, KK ), 1, A( 1, KP ), 1 ) | |||
| * | |||
| * Interchange rows KK and KP in last N-KK+1 columns | |||
| * of A and W | |||
| * | |||
| CALL CSWAP( N-KK+1, A( KK, KK ), LDA, A( KP, KK ), LDA ) | |||
| CALL CSWAP( N-KK+1, W( KK, KKW ), LDW, W( KP, KKW ), | |||
| $ LDW ) | |||
| END IF | |||
| * | |||
| IF( KSTEP.EQ.1 ) THEN | |||
| * | |||
| * 1-by-1 pivot block D(k): column KW of W now holds | |||
| * | |||
| * W(k) = U(k)*D(k) | |||
| * | |||
| * where U(k) is the k-th column of U | |||
| * | |||
| * Store U(k) in column k of A | |||
| * | |||
| CALL CCOPY( K, W( 1, KW ), 1, A( 1, K ), 1 ) | |||
| IF( K.GT.1 ) THEN | |||
| IF( CABS1( A( K, K ) ).GE.SFMIN ) THEN | |||
| R1 = CONE / A( K, K ) | |||
| CALL CSCAL( K-1, R1, A( 1, K ), 1 ) | |||
| ELSE IF( A( K, K ).NE.CZERO ) THEN | |||
| DO 14 II = 1, K - 1 | |||
| A( II, K ) = A( II, K ) / A( K, K ) | |||
| 14 CONTINUE | |||
| END IF | |||
| END IF | |||
| * | |||
| ELSE | |||
| * | |||
| * 2-by-2 pivot block D(k): columns KW and KW-1 of W now | |||
| * hold | |||
| * | |||
| * ( W(k-1) W(k) ) = ( U(k-1) U(k) )*D(k) | |||
| * | |||
| * where U(k) and U(k-1) are the k-th and (k-1)-th columns | |||
| * of U | |||
| * | |||
| IF( K.GT.2 ) THEN | |||
| * | |||
| * Store U(k) and U(k-1) in columns k and k-1 of A | |||
| * | |||
| D12 = W( K-1, KW ) | |||
| D11 = W( K, KW ) / D12 | |||
| D22 = W( K-1, KW-1 ) / D12 | |||
| T = CONE / ( D11*D22-CONE ) | |||
| DO 20 J = 1, K - 2 | |||
| A( J, K-1 ) = T*( (D11*W( J, KW-1 )-W( J, KW ) ) / | |||
| $ D12 ) | |||
| A( J, K ) = T*( ( D22*W( J, KW )-W( J, KW-1 ) ) / | |||
| $ D12 ) | |||
| 20 CONTINUE | |||
| END IF | |||
| * | |||
| * Copy D(k) to A | |||
| * | |||
| A( K-1, K-1 ) = W( K-1, KW-1 ) | |||
| A( K-1, K ) = W( K-1, KW ) | |||
| A( K, K ) = W( K, KW ) | |||
| END IF | |||
| END IF | |||
| * | |||
| * Store details of the interchanges in IPIV | |||
| * | |||
| IF( KSTEP.EQ.1 ) THEN | |||
| IPIV( K ) = KP | |||
| ELSE | |||
| IPIV( K ) = -P | |||
| IPIV( K-1 ) = -KP | |||
| END IF | |||
| * | |||
| * Decrease K and return to the start of the main loop | |||
| * | |||
| K = K - KSTEP | |||
| GO TO 10 | |||
| * | |||
| 30 CONTINUE | |||
| * | |||
| * Update the upper triangle of A11 (= A(1:k,1:k)) as | |||
| * | |||
| * A11 := A11 - U12*D*U12**T = A11 - U12*W**T | |||
| * | |||
| * computing blocks of NB columns at a time | |||
| * | |||
| DO 50 J = ( ( K-1 ) / NB )*NB + 1, 1, -NB | |||
| JB = MIN( NB, K-J+1 ) | |||
| * | |||
| * Update the upper triangle of the diagonal block | |||
| * | |||
| DO 40 JJ = J, J + JB - 1 | |||
| CALL CGEMV( 'No transpose', JJ-J+1, N-K, -CONE, | |||
| $ A( J, K+1 ), LDA, W( JJ, KW+1 ), LDW, CONE, | |||
| $ A( J, JJ ), 1 ) | |||
| 40 CONTINUE | |||
| * | |||
| * Update the rectangular superdiagonal block | |||
| * | |||
| IF( J.GE.2 ) | |||
| $ CALL CGEMM( 'No transpose', 'Transpose', J-1, JB, | |||
| $ N-K, -CONE, A( 1, K+1 ), LDA, W( J, KW+1 ), LDW, | |||
| $ CONE, A( 1, J ), LDA ) | |||
| 50 CONTINUE | |||
| * | |||
| * Put U12 in standard form by partially undoing the interchanges | |||
| * in columns k+1:n | |||
| * | |||
| J = K + 1 | |||
| 60 CONTINUE | |||
| * | |||
| KSTEP = 1 | |||
| JP1 = 1 | |||
| JJ = J | |||
| JP2 = IPIV( J ) | |||
| IF( JP2.LT.0 ) THEN | |||
| JP2 = -JP2 | |||
| J = J + 1 | |||
| JP1 = -IPIV( J ) | |||
| KSTEP = 2 | |||
| END IF | |||
| * | |||
| J = J + 1 | |||
| IF( JP2.NE.JJ .AND. J.LE.N ) | |||
| $ CALL CSWAP( N-J+1, A( JP2, J ), LDA, A( JJ, J ), LDA ) | |||
| JJ = J - 1 | |||
| IF( JP1.NE.JJ .AND. KSTEP.EQ.2 ) | |||
| $ CALL CSWAP( N-J+1, A( JP1, J ), LDA, A( JJ, J ), LDA ) | |||
| IF( J.LE.N ) | |||
| $ GO TO 60 | |||
| * | |||
| * Set KB to the number of columns factorized | |||
| * | |||
| KB = N - K | |||
| * | |||
| ELSE | |||
| * | |||
| * Factorize the leading columns of A using the lower triangle | |||
| * of A and working forwards, and compute the matrix W = L21*D | |||
| * for use in updating A22 | |||
| * | |||
| * K is the main loop index, increasing from 1 in steps of 1 or 2 | |||
| * | |||
| K = 1 | |||
| 70 CONTINUE | |||
| * | |||
| * Exit from loop | |||
| * | |||
| IF( ( K.GE.NB .AND. NB.LT.N ) .OR. K.GT.N ) | |||
| $ GO TO 90 | |||
| * | |||
| KSTEP = 1 | |||
| P = K | |||
| * | |||
| * Copy column K of A to column K of W and update it | |||
| * | |||
| CALL CCOPY( N-K+1, A( K, K ), 1, W( K, K ), 1 ) | |||
| IF( K.GT.1 ) | |||
| $ CALL CGEMV( 'No transpose', N-K+1, K-1, -CONE, A( K, 1 ), | |||
| $ LDA, W( K, 1 ), LDW, CONE, W( K, K ), 1 ) | |||
| * | |||
| * Determine rows and columns to be interchanged and whether | |||
| * a 1-by-1 or 2-by-2 pivot block will be used | |||
| * | |||
| ABSAKK = CABS1( W( K, K ) ) | |||
| * | |||
| * IMAX is the row-index of the largest off-diagonal element in | |||
| * column K, and COLMAX is its absolute value. | |||
| * Determine both COLMAX and IMAX. | |||
| * | |||
| IF( K.LT.N ) THEN | |||
| IMAX = K + ICAMAX( N-K, W( K+1, K ), 1 ) | |||
| COLMAX = CABS1( W( IMAX, K ) ) | |||
| ELSE | |||
| COLMAX = ZERO | |||
| END IF | |||
| * | |||
| IF( MAX( ABSAKK, COLMAX ).EQ.ZERO ) THEN | |||
| * | |||
| * Column K is zero or underflow: set INFO and continue | |||
| * | |||
| IF( INFO.EQ.0 ) | |||
| $ INFO = K | |||
| KP = K | |||
| CALL CCOPY( N-K+1, W( K, K ), 1, A( K, K ), 1 ) | |||
| ELSE | |||
| * | |||
| * ============================================================ | |||
| * | |||
| * Test for interchange | |||
| * | |||
| * Equivalent to testing for ABSAKK.GE.ALPHA*COLMAX | |||
| * (used to handle NaN and Inf) | |||
| * | |||
| IF( .NOT.( ABSAKK.LT.ALPHA*COLMAX ) ) THEN | |||
| * | |||
| * no interchange, use 1-by-1 pivot block | |||
| * | |||
| KP = K | |||
| * | |||
| ELSE | |||
| * | |||
| DONE = .FALSE. | |||
| * | |||
| * Loop until pivot found | |||
| * | |||
| 72 CONTINUE | |||
| * | |||
| * Begin pivot search loop body | |||
| * | |||
| * | |||
| * Copy column IMAX to column K+1 of W and update it | |||
| * | |||
| CALL CCOPY( IMAX-K, A( IMAX, K ), LDA, W( K, K+1 ), 1) | |||
| CALL CCOPY( N-IMAX+1, A( IMAX, IMAX ), 1, | |||
| $ W( IMAX, K+1 ), 1 ) | |||
| IF( K.GT.1 ) | |||
| $ CALL CGEMV( 'No transpose', N-K+1, K-1, -CONE, | |||
| $ A( K, 1 ), LDA, W( IMAX, 1 ), LDW, | |||
| $ CONE, W( K, K+1 ), 1 ) | |||
| * | |||
| * JMAX is the column-index of the largest off-diagonal | |||
| * element in row IMAX, and ROWMAX is its absolute value. | |||
| * Determine both ROWMAX and JMAX. | |||
| * | |||
| IF( IMAX.NE.K ) THEN | |||
| JMAX = K - 1 + ICAMAX( IMAX-K, W( K, K+1 ), 1 ) | |||
| ROWMAX = CABS1( W( JMAX, K+1 ) ) | |||
| ELSE | |||
| ROWMAX = ZERO | |||
| END IF | |||
| * | |||
| IF( IMAX.LT.N ) THEN | |||
| ITEMP = IMAX + ICAMAX( N-IMAX, W( IMAX+1, K+1 ), 1) | |||
| STEMP = CABS1( W( ITEMP, K+1 ) ) | |||
| IF( STEMP.GT.ROWMAX ) THEN | |||
| ROWMAX = STEMP | |||
| JMAX = ITEMP | |||
| END IF | |||
| END IF | |||
| * | |||
| * Equivalent to testing for | |||
| * CABS1( W( IMAX, K+1 ) ).GE.ALPHA*ROWMAX | |||
| * (used to handle NaN and Inf) | |||
| * | |||
| IF( .NOT.( CABS1( W( IMAX, K+1 ) ).LT.ALPHA*ROWMAX ) ) | |||
| $ THEN | |||
| * | |||
| * interchange rows and columns K and IMAX, | |||
| * use 1-by-1 pivot block | |||
| * | |||
| KP = IMAX | |||
| * | |||
| * copy column K+1 of W to column K of W | |||
| * | |||
| CALL CCOPY( N-K+1, W( K, K+1 ), 1, W( K, K ), 1 ) | |||
| * | |||
| DONE = .TRUE. | |||
| * | |||
| * Equivalent to testing for ROWMAX.EQ.COLMAX, | |||
| * (used to handle NaN and Inf) | |||
| * | |||
| ELSE IF( ( P.EQ.JMAX ) .OR. ( ROWMAX.LE.COLMAX ) ) | |||
| $ THEN | |||
| * | |||
| * interchange rows and columns K+1 and IMAX, | |||
| * use 2-by-2 pivot block | |||
| * | |||
| KP = IMAX | |||
| KSTEP = 2 | |||
| DONE = .TRUE. | |||
| ELSE | |||
| * | |||
| * Pivot not found: set params and repeat | |||
| * | |||
| P = IMAX | |||
| COLMAX = ROWMAX | |||
| IMAX = JMAX | |||
| * | |||
| * Copy updated JMAXth (next IMAXth) column to Kth of W | |||
| * | |||
| CALL CCOPY( N-K+1, W( K, K+1 ), 1, W( K, K ), 1 ) | |||
| * | |||
| END IF | |||
| * | |||
| * End pivot search loop body | |||
| * | |||
| IF( .NOT. DONE ) GOTO 72 | |||
| * | |||
| END IF | |||
| * | |||
| * ============================================================ | |||
| * | |||
| KK = K + KSTEP - 1 | |||
| * | |||
| IF( ( KSTEP.EQ.2 ) .AND. ( P.NE.K ) ) THEN | |||
| * | |||
| * Copy non-updated column K to column P | |||
| * | |||
| CALL CCOPY( P-K, A( K, K ), 1, A( P, K ), LDA ) | |||
| CALL CCOPY( N-P+1, A( P, K ), 1, A( P, P ), 1 ) | |||
| * | |||
| * Interchange rows K and P in first K columns of A | |||
| * and first K+1 columns of W | |||
| * | |||
| CALL CSWAP( K, A( K, 1 ), LDA, A( P, 1 ), LDA ) | |||
| CALL CSWAP( KK, W( K, 1 ), LDW, W( P, 1 ), LDW ) | |||
| END IF | |||
| * | |||
| * Updated column KP is already stored in column KK of W | |||
| * | |||
| IF( KP.NE.KK ) THEN | |||
| * | |||
| * Copy non-updated column KK to column KP | |||
| * | |||
| A( KP, K ) = A( KK, K ) | |||
| CALL CCOPY( KP-K-1, A( K+1, KK ), 1, A( KP, K+1 ), LDA ) | |||
| CALL CCOPY( N-KP+1, A( KP, KK ), 1, A( KP, KP ), 1 ) | |||
| * | |||
| * Interchange rows KK and KP in first KK columns of A and W | |||
| * | |||
| CALL CSWAP( KK, A( KK, 1 ), LDA, A( KP, 1 ), LDA ) | |||
| CALL CSWAP( KK, W( KK, 1 ), LDW, W( KP, 1 ), LDW ) | |||
| END IF | |||
| * | |||
| IF( KSTEP.EQ.1 ) THEN | |||
| * | |||
| * 1-by-1 pivot block D(k): column k of W now holds | |||
| * | |||
| * W(k) = L(k)*D(k) | |||
| * | |||
| * where L(k) is the k-th column of L | |||
| * | |||
| * Store L(k) in column k of A | |||
| * | |||
| CALL CCOPY( N-K+1, W( K, K ), 1, A( K, K ), 1 ) | |||
| IF( K.LT.N ) THEN | |||
| IF( CABS1( A( K, K ) ).GE.SFMIN ) THEN | |||
| R1 = CONE / A( K, K ) | |||
| CALL CSCAL( N-K, R1, A( K+1, K ), 1 ) | |||
| ELSE IF( A( K, K ).NE.CZERO ) THEN | |||
| DO 74 II = K + 1, N | |||
| A( II, K ) = A( II, K ) / A( K, K ) | |||
| 74 CONTINUE | |||
| END IF | |||
| END IF | |||
| * | |||
| ELSE | |||
| * | |||
| * 2-by-2 pivot block D(k): columns k and k+1 of W now hold | |||
| * | |||
| * ( W(k) W(k+1) ) = ( L(k) L(k+1) )*D(k) | |||
| * | |||
| * where L(k) and L(k+1) are the k-th and (k+1)-th columns | |||
| * of L | |||
| * | |||
| IF( K.LT.N-1 ) THEN | |||
| * | |||
| * Store L(k) and L(k+1) in columns k and k+1 of A | |||
| * | |||
| D21 = W( K+1, K ) | |||
| D11 = W( K+1, K+1 ) / D21 | |||
| D22 = W( K, K ) / D21 | |||
| T = CONE / ( D11*D22-CONE ) | |||
| DO 80 J = K + 2, N | |||
| A( J, K ) = T*( ( D11*W( J, K )-W( J, K+1 ) ) / | |||
| $ D21 ) | |||
| A( J, K+1 ) = T*( ( D22*W( J, K+1 )-W( J, K ) ) / | |||
| $ D21 ) | |||
| 80 CONTINUE | |||
| END IF | |||
| * | |||
| * Copy D(k) to A | |||
| * | |||
| A( K, K ) = W( K, K ) | |||
| A( K+1, K ) = W( K+1, K ) | |||
| A( K+1, K+1 ) = W( K+1, K+1 ) | |||
| END IF | |||
| END IF | |||
| * | |||
| * Store details of the interchanges in IPIV | |||
| * | |||
| IF( KSTEP.EQ.1 ) THEN | |||
| IPIV( K ) = KP | |||
| ELSE | |||
| IPIV( K ) = -P | |||
| IPIV( K+1 ) = -KP | |||
| END IF | |||
| * | |||
| * Increase K and return to the start of the main loop | |||
| * | |||
| K = K + KSTEP | |||
| GO TO 70 | |||
| * | |||
| 90 CONTINUE | |||
| * | |||
| * Update the lower triangle of A22 (= A(k:n,k:n)) as | |||
| * | |||
| * A22 := A22 - L21*D*L21**T = A22 - L21*W**T | |||
| * | |||
| * computing blocks of NB columns at a time | |||
| * | |||
| DO 110 J = K, N, NB | |||
| JB = MIN( NB, N-J+1 ) | |||
| * | |||
| * Update the lower triangle of the diagonal block | |||
| * | |||
| DO 100 JJ = J, J + JB - 1 | |||
| CALL CGEMV( 'No transpose', J+JB-JJ, K-1, -CONE, | |||
| $ A( JJ, 1 ), LDA, W( JJ, 1 ), LDW, CONE, | |||
| $ A( JJ, JJ ), 1 ) | |||
| 100 CONTINUE | |||
| * | |||
| * Update the rectangular subdiagonal block | |||
| * | |||
| IF( J+JB.LE.N ) | |||
| $ CALL CGEMM( 'No transpose', 'Transpose', N-J-JB+1, JB, | |||
| $ K-1, -CONE, A( J+JB, 1 ), LDA, W( J, 1 ), LDW, | |||
| $ CONE, A( J+JB, J ), LDA ) | |||
| 110 CONTINUE | |||
| * | |||
| * Put L21 in standard form by partially undoing the interchanges | |||
| * in columns 1:k-1 | |||
| * | |||
| J = K - 1 | |||
| 120 CONTINUE | |||
| * | |||
| KSTEP = 1 | |||
| JP1 = 1 | |||
| JJ = J | |||
| JP2 = IPIV( J ) | |||
| IF( JP2.LT.0 ) THEN | |||
| JP2 = -JP2 | |||
| J = J - 1 | |||
| JP1 = -IPIV( J ) | |||
| KSTEP = 2 | |||
| END IF | |||
| * | |||
| J = J - 1 | |||
| IF( JP2.NE.JJ .AND. J.GE.1 ) | |||
| $ CALL CSWAP( J, A( JP2, 1 ), LDA, A( JJ, 1 ), LDA ) | |||
| JJ = J + 1 | |||
| IF( JP1.NE.JJ .AND. KSTEP.EQ.2 ) | |||
| $ CALL CSWAP( J, A( JP1, 1 ), LDA, A( JJ, 1 ), LDA ) | |||
| IF( J.GE.1 ) | |||
| $ GO TO 120 | |||
| * | |||
| * Set KB to the number of columns factorized | |||
| * | |||
| KB = K - 1 | |||
| * | |||
| END IF | |||
| RETURN | |||
| * | |||
| * End of CLASYF_ROOK | |||
| * | |||
| END | |||
| @@ -311,7 +311,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date September 2012 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup complexOTHERcomputational | |||
| * | |||
| @@ -329,10 +329,10 @@ | |||
| $ M, W, Z, LDZ, NZC, ISUPPZ, TRYRAC, WORK, LWORK, | |||
| $ IWORK, LIWORK, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.2) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * September 2012 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER JOBZ, RANGE | |||
| @@ -408,6 +408,7 @@ | |||
| WU = ZERO | |||
| IIL = 0 | |||
| IIU = 0 | |||
| NSPLIT = 0 | |||
| IF( VALEIG ) THEN | |||
| * We do not reference VL, VU in the cases RANGE = 'I','A' | |||
| @@ -0,0 +1,255 @@ | |||
| *> \brief \b CSYCON_ROOK | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download CSYCON_ROOK + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/csycon_rook.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/csycon_rook.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/csycon_rook.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE CSYCON_ROOK( UPLO, N, A, LDA, IPIV, ANORM, RCOND, | |||
| * WORK, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * CHARACTER UPLO | |||
| * INTEGER INFO, LDA, N | |||
| * REAL ANORM, RCOND | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * INTEGER IPIV( * ) | |||
| * COMPLEX A( LDA, * ), WORK( * ) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| * ============= | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> CSYCON_ROOK estimates the reciprocal of the condition number (in the | |||
| *> 1-norm) of a complex symmetric matrix A using the factorization | |||
| *> A = U*D*U**T or A = L*D*L**T computed by CSYTRF_ROOK. | |||
| *> | |||
| *> An estimate is obtained for norm(inv(A)), and the reciprocal of the | |||
| *> condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))). | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] UPLO | |||
| *> \verbatim | |||
| *> UPLO is CHARACTER*1 | |||
| *> Specifies whether the details of the factorization are stored | |||
| *> as an upper or lower triangular matrix. | |||
| *> = 'U': Upper triangular, form is A = U*D*U**T; | |||
| *> = 'L': Lower triangular, form is A = L*D*L**T. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] N | |||
| *> \verbatim | |||
| *> N is INTEGER | |||
| *> The order of the matrix A. N >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] A | |||
| *> \verbatim | |||
| *> A is COMPLEX array, dimension (LDA,N) | |||
| *> The block diagonal matrix D and the multipliers used to | |||
| *> obtain the factor U or L as computed by CSYTRF_ROOK. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDA | |||
| *> \verbatim | |||
| *> LDA is INTEGER | |||
| *> The leading dimension of the array A. LDA >= max(1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] IPIV | |||
| *> \verbatim | |||
| *> IPIV is INTEGER array, dimension (N) | |||
| *> Details of the interchanges and the block structure of D | |||
| *> as determined by CSYTRF_ROOK. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] ANORM | |||
| *> \verbatim | |||
| *> ANORM is REAL | |||
| *> The 1-norm of the original matrix A. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] RCOND | |||
| *> \verbatim | |||
| *> RCOND is REAL | |||
| *> The reciprocal of the condition number of the matrix A, | |||
| *> computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is an | |||
| *> estimate of the 1-norm of inv(A) computed in this routine. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] WORK | |||
| *> \verbatim | |||
| *> WORK is COMPLEX array, dimension (2*N) | |||
| *> \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 April 2012 | |||
| * | |||
| *> \ingroup complexSYcomputational | |||
| * | |||
| *> \par Contributors: | |||
| * ================== | |||
| *> \verbatim | |||
| *> | |||
| *> April 2012, Igor Kozachenko, | |||
| *> Computer Science Division, | |||
| *> University of California, Berkeley | |||
| *> | |||
| *> September 2007, Sven Hammarling, Nicholas J. Higham, Craig Lucas, | |||
| *> School of Mathematics, | |||
| *> University of Manchester | |||
| *> | |||
| *> \endverbatim | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE CSYCON_ROOK( UPLO, N, A, LDA, IPIV, ANORM, RCOND, WORK, | |||
| $ INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.1) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * April 2012 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER UPLO | |||
| INTEGER INFO, LDA, N | |||
| REAL ANORM, RCOND | |||
| * .. | |||
| * .. Array Arguments .. | |||
| INTEGER IPIV( * ) | |||
| COMPLEX A( LDA, * ), WORK( * ) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| REAL ONE, ZERO | |||
| PARAMETER ( ONE = 1.0E+0, ZERO = 0.0E+0 ) | |||
| COMPLEX CZERO | |||
| PARAMETER ( CZERO = ( 0.0E+0, 0.0E+0 ) ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| LOGICAL UPPER | |||
| INTEGER I, KASE | |||
| REAL AINVNM | |||
| * .. | |||
| * .. Local Arrays .. | |||
| INTEGER ISAVE( 3 ) | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| EXTERNAL LSAME | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL CLACN2, CSYTRS_ROOK, XERBLA | |||
| * .. | |||
| * .. Intrinsic Functions .. | |||
| INTRINSIC MAX | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Test the input parameters. | |||
| * | |||
| INFO = 0 | |||
| UPPER = LSAME( UPLO, 'U' ) | |||
| IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN | |||
| INFO = -1 | |||
| ELSE IF( N.LT.0 ) THEN | |||
| INFO = -2 | |||
| ELSE IF( LDA.LT.MAX( 1, N ) ) THEN | |||
| INFO = -4 | |||
| ELSE IF( ANORM.LT.ZERO ) THEN | |||
| INFO = -6 | |||
| END IF | |||
| IF( INFO.NE.0 ) THEN | |||
| CALL XERBLA( 'CSYCON_ROOK', -INFO ) | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Quick return if possible | |||
| * | |||
| RCOND = ZERO | |||
| IF( N.EQ.0 ) THEN | |||
| RCOND = ONE | |||
| RETURN | |||
| ELSE IF( ANORM.LE.ZERO ) THEN | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Check that the diagonal matrix D is nonsingular. | |||
| * | |||
| IF( UPPER ) THEN | |||
| * | |||
| * Upper triangular storage: examine D from bottom to top | |||
| * | |||
| DO 10 I = N, 1, -1 | |||
| IF( IPIV( I ).GT.0 .AND. A( I, I ).EQ.CZERO ) | |||
| $ RETURN | |||
| 10 CONTINUE | |||
| ELSE | |||
| * | |||
| * Lower triangular storage: examine D from top to bottom. | |||
| * | |||
| DO 20 I = 1, N | |||
| IF( IPIV( I ).GT.0 .AND. A( I, I ).EQ.CZERO ) | |||
| $ RETURN | |||
| 20 CONTINUE | |||
| END IF | |||
| * | |||
| * Estimate the 1-norm of the inverse. | |||
| * | |||
| KASE = 0 | |||
| 30 CONTINUE | |||
| CALL CLACN2( N, WORK( N+1 ), WORK, AINVNM, KASE, ISAVE ) | |||
| IF( KASE.NE.0 ) THEN | |||
| * | |||
| * Multiply by inv(L*D*L**T) or inv(U*D*U**T). | |||
| * | |||
| CALL CSYTRS_ROOK( UPLO, N, 1, A, LDA, IPIV, WORK, N, INFO ) | |||
| GO TO 30 | |||
| END IF | |||
| * | |||
| * Compute the estimate of the reciprocal condition number. | |||
| * | |||
| IF( AINVNM.NE.ZERO ) | |||
| $ RCOND = ( ONE / AINVNM ) / ANORM | |||
| * | |||
| RETURN | |||
| * | |||
| * End of CSYCON_ROOK | |||
| * | |||
| END | |||
| @@ -0,0 +1,293 @@ | |||
| *> \brief <b> CSYSV_ROOK computes the solution to system of linear equations A * X = B for SY matrices</b> | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download CSYSV_ROOK + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/csysv_rook.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/csysv_rook.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/csysv_rook.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE CSYSV_ROOK( UPLO, N, NRHS, A, LDA, IPIV, B, LDB, WORK, | |||
| * LWORK, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * CHARACTER UPLO | |||
| * INTEGER INFO, LDA, LDB, LWORK, N, NRHS | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * INTEGER IPIV( * ) | |||
| * COMPLEX A( LDA, * ), B( LDB, * ), WORK( * ) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| * ============= | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> CSYSV_ROOK computes the solution to a complex system of linear | |||
| *> equations | |||
| *> A * X = B, | |||
| *> where A is an N-by-N symmetric matrix and X and B are N-by-NRHS | |||
| *> matrices. | |||
| *> | |||
| *> The diagonal pivoting method is used to factor A as | |||
| *> A = U * D * U**T, if UPLO = 'U', or | |||
| *> A = L * D * L**T, if UPLO = 'L', | |||
| *> where U (or L) is a product of permutation and unit upper (lower) | |||
| *> triangular matrices, and D is symmetric and block diagonal with | |||
| *> 1-by-1 and 2-by-2 diagonal blocks. | |||
| *> | |||
| *> CSYTRF_ROOK is called to compute the factorization of a complex | |||
| *> symmetric matrix A using the bounded Bunch-Kaufman ("rook") diagonal | |||
| *> pivoting method. | |||
| *> | |||
| *> The factored form of A is then used to solve the system | |||
| *> of equations A * X = B by calling CSYTRS_ROOK. | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] UPLO | |||
| *> \verbatim | |||
| *> UPLO is CHARACTER*1 | |||
| *> = 'U': Upper triangle of A is stored; | |||
| *> = 'L': Lower triangle of A is stored. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] N | |||
| *> \verbatim | |||
| *> N is INTEGER | |||
| *> The number of linear equations, i.e., the order of the | |||
| *> matrix A. N >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] NRHS | |||
| *> \verbatim | |||
| *> NRHS is INTEGER | |||
| *> The number of right hand sides, i.e., the number of columns | |||
| *> of the matrix B. NRHS >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] A | |||
| *> \verbatim | |||
| *> 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 | |||
| *> triangular part of A is not referenced. If UPLO = 'L', the | |||
| *> leading N-by-N lower triangular part of A contains the lower | |||
| *> triangular part of the matrix A, and the strictly upper | |||
| *> triangular part of A is not referenced. | |||
| *> | |||
| *> On exit, if INFO = 0, the block diagonal matrix D and the | |||
| *> multipliers used to obtain the factor U or L from the | |||
| *> factorization A = U*D*U**T or A = L*D*L**T as computed by | |||
| *> CSYTRF_ROOK. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDA | |||
| *> \verbatim | |||
| *> LDA is INTEGER | |||
| *> The leading dimension of the array A. LDA >= max(1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] IPIV | |||
| *> \verbatim | |||
| *> IPIV is INTEGER array, dimension (N) | |||
| *> Details of the interchanges and the block structure of D, | |||
| *> as determined by CSYTRF_ROOK. | |||
| *> | |||
| *> If UPLO = 'U': | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) | |||
| *> were interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) < 0 and IPIV(k-1) < 0, then rows and | |||
| *> columns k and -IPIV(k) were interchanged and rows and | |||
| *> columns k-1 and -IPIV(k-1) were inerchaged, | |||
| *> D(k-1:k,k-1:k) is a 2-by-2 diagonal block. | |||
| *> | |||
| *> If UPLO = 'L': | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) | |||
| *> were interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) < 0 and IPIV(k+1) < 0, then rows and | |||
| *> columns k and -IPIV(k) were interchanged and rows and | |||
| *> columns k+1 and -IPIV(k+1) were inerchaged, | |||
| *> D(k:k+1,k:k+1) is a 2-by-2 diagonal block. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] B | |||
| *> \verbatim | |||
| *> B is COMPLEX array, dimension (LDB,NRHS) | |||
| *> On entry, the N-by-NRHS right hand side matrix B. | |||
| *> On exit, if INFO = 0, the N-by-NRHS solution matrix X. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDB | |||
| *> \verbatim | |||
| *> LDB is INTEGER | |||
| *> The leading dimension of the array B. LDB >= max(1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] WORK | |||
| *> \verbatim | |||
| *> WORK is COMPLEX array, dimension (MAX(1,LWORK)) | |||
| *> On exit, if INFO = 0, WORK(1) returns the optimal LWORK. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LWORK | |||
| *> \verbatim | |||
| *> LWORK is INTEGER | |||
| *> The length of WORK. LWORK >= 1, and for best performance | |||
| *> LWORK >= max(1,N*NB), where NB is the optimal blocksize for | |||
| *> CSYTRF_ROOK. | |||
| *> | |||
| *> TRS will be done with Level 2 BLAS | |||
| *> | |||
| *> 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 | |||
| *> > 0: if INFO = i, D(i,i) is exactly zero. The factorization | |||
| *> has been completed, but the block diagonal matrix D is | |||
| *> exactly singular, so the solution could not be computed. | |||
| *> \endverbatim | |||
| * | |||
| * Authors: | |||
| * ======== | |||
| * | |||
| *> \author Univ. of Tennessee | |||
| *> \author Univ. of California Berkeley | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date April 2012 | |||
| * | |||
| *> \ingroup complexSYsolve | |||
| * | |||
| *> \par Contributors: | |||
| * ================== | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> April 2012, Igor Kozachenko, | |||
| *> Computer Science Division, | |||
| *> University of California, Berkeley | |||
| *> | |||
| *> September 2007, Sven Hammarling, Nicholas J. Higham, Craig Lucas, | |||
| *> School of Mathematics, | |||
| *> University of Manchester | |||
| *> | |||
| *> \endverbatim | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE CSYSV_ROOK( UPLO, N, NRHS, A, LDA, IPIV, B, LDB, WORK, | |||
| $ LWORK, INFO ) | |||
| * | |||
| * -- LAPACK driver routine (version 3.4.1) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * April 2012 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER UPLO | |||
| INTEGER INFO, LDA, LDB, LWORK, N, NRHS | |||
| * .. | |||
| * .. Array Arguments .. | |||
| INTEGER IPIV( * ) | |||
| COMPLEX A( LDA, * ), B( LDB, * ), WORK( * ) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Local Scalars .. | |||
| LOGICAL LQUERY | |||
| INTEGER LWKOPT | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| EXTERNAL LSAME | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL XERBLA, CSYTRF_ROOK, CSYTRS_ROOK | |||
| * .. | |||
| * .. Intrinsic Functions .. | |||
| INTRINSIC MAX | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Test the input parameters. | |||
| * | |||
| INFO = 0 | |||
| LQUERY = ( LWORK.EQ.-1 ) | |||
| IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN | |||
| INFO = -1 | |||
| ELSE IF( N.LT.0 ) THEN | |||
| INFO = -2 | |||
| ELSE IF( NRHS.LT.0 ) THEN | |||
| INFO = -3 | |||
| ELSE IF( LDA.LT.MAX( 1, N ) ) THEN | |||
| INFO = -5 | |||
| ELSE IF( LDB.LT.MAX( 1, N ) ) THEN | |||
| INFO = -8 | |||
| ELSE IF( LWORK.LT.1 .AND. .NOT.LQUERY ) THEN | |||
| INFO = -10 | |||
| END IF | |||
| * | |||
| IF( INFO.EQ.0 ) THEN | |||
| IF( N.EQ.0 ) THEN | |||
| LWKOPT = 1 | |||
| ELSE | |||
| CALL CSYTRF_ROOK( UPLO, N, A, LDA, IPIV, WORK, -1, INFO ) | |||
| LWKOPT = WORK(1) | |||
| END IF | |||
| WORK( 1 ) = LWKOPT | |||
| END IF | |||
| * | |||
| IF( INFO.NE.0 ) THEN | |||
| CALL XERBLA( 'CSYSV_ROOK ', -INFO ) | |||
| RETURN | |||
| ELSE IF( LQUERY ) THEN | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Compute the factorization A = U*D*U**T or A = L*D*L**T. | |||
| * | |||
| CALL CSYTRF_ROOK( UPLO, N, A, LDA, IPIV, WORK, LWORK, INFO ) | |||
| IF( INFO.EQ.0 ) THEN | |||
| * | |||
| * Solve the system A*X = B, overwriting B with X. | |||
| * | |||
| * Solve with TRS_ROOK ( Use Level 2 BLAS) | |||
| * | |||
| CALL CSYTRS_ROOK( UPLO, N, NRHS, A, LDA, IPIV, B, LDB, INFO ) | |||
| * | |||
| END IF | |||
| * | |||
| WORK( 1 ) = LWKOPT | |||
| * | |||
| RETURN | |||
| * | |||
| * End of CSYSV_ROOK | |||
| * | |||
| END | |||
| @@ -90,13 +90,22 @@ | |||
| *> \verbatim | |||
| *> IPIV is INTEGER array, dimension (N) | |||
| *> Details of the interchanges and the block structure of D. | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) were | |||
| *> interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> If UPLO = 'U' and IPIV(k) = IPIV(k-1) < 0, then rows and | |||
| *> columns k-1 and -IPIV(k) were interchanged and D(k-1:k,k-1:k) | |||
| *> is a 2-by-2 diagonal block. If UPLO = 'L' and IPIV(k) = | |||
| *> IPIV(k+1) < 0, then rows and columns k+1 and -IPIV(k) were | |||
| *> interchanged and D(k:k+1,k:k+1) is a 2-by-2 diagonal block. | |||
| *> | |||
| *> If UPLO = 'U': | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) were | |||
| *> interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) = IPIV(k-1) < 0, then rows and columns | |||
| *> k-1 and -IPIV(k) were interchanged and D(k-1:k,k-1:k) | |||
| *> is a 2-by-2 diagonal block. | |||
| *> | |||
| *> If UPLO = 'L': | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) were | |||
| *> interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) = IPIV(k+1) < 0, then rows and columns | |||
| *> k+1 and -IPIV(k) were interchanged and D(k:k+1,k:k+1) | |||
| *> is a 2-by-2 diagonal block. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] INFO | |||
| @@ -118,7 +127,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date September 2012 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup complexSYcomputational | |||
| * | |||
| @@ -182,10 +191,10 @@ | |||
| * ===================================================================== | |||
| SUBROUTINE CSYTF2( UPLO, N, A, LDA, IPIV, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.2) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * September 2012 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER UPLO | |||
| @@ -273,7 +282,8 @@ | |||
| ABSAKK = CABS1( A( K, K ) ) | |||
| * | |||
| * IMAX is the row-index of the largest off-diagonal element in | |||
| * column K, and COLMAX is its absolute value | |||
| * column K, and COLMAX is its absolute value. | |||
| * Determine both COLMAX and IMAX. | |||
| * | |||
| IF( K.GT.1 ) THEN | |||
| IMAX = ICAMAX( K-1, A( 1, K ), 1 ) | |||
| @@ -284,7 +294,8 @@ | |||
| * | |||
| IF( MAX( ABSAKK, COLMAX ).EQ.ZERO .OR. SISNAN(ABSAKK) ) THEN | |||
| * | |||
| * Column K is zero or NaN: set INFO and continue | |||
| * Column K is zero or underflow, or contains a NaN: | |||
| * set INFO and continue | |||
| * | |||
| IF( INFO.EQ.0 ) | |||
| $ INFO = K | |||
| @@ -441,7 +452,8 @@ | |||
| ABSAKK = CABS1( A( K, K ) ) | |||
| * | |||
| * IMAX is the row-index of the largest off-diagonal element in | |||
| * column K, and COLMAX is its absolute value | |||
| * column K, and COLMAX is its absolute value. | |||
| * Determine both COLMAX and IMAX. | |||
| * | |||
| IF( K.LT.N ) THEN | |||
| IMAX = K + ICAMAX( N-K, A( K+1, K ), 1 ) | |||
| @@ -452,7 +464,8 @@ | |||
| * | |||
| IF( MAX( ABSAKK, COLMAX ).EQ.ZERO .OR. SISNAN(ABSAKK) ) THEN | |||
| * | |||
| * Column K is zero or NaN: set INFO and continue | |||
| * Column K is zero or underflow, or contains a NaN: | |||
| * set INFO and continue | |||
| * | |||
| IF( INFO.EQ.0 ) | |||
| $ INFO = K | |||
| @@ -0,0 +1,821 @@ | |||
| *> \brief \b CSYTF2_ROOK computes the factorization of a complex symmetric indefinite matrix using the bounded Bunch-Kaufman ("rook") diagonal pivoting method (unblocked algorithm). | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download CSYTF2_ROOK + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/csytf2_rook.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/csytf2_rook.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/csytf2_rook.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE CSYTF2_ROOK( UPLO, N, A, LDA, IPIV, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * CHARACTER UPLO | |||
| * INTEGER INFO, LDA, N | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * INTEGER IPIV( * ) | |||
| * COMPLEX A( LDA, * ) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| * ============= | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> CSYTF2_ROOK computes the factorization of a complex symmetric matrix A | |||
| *> using the bounded Bunch-Kaufman ("rook") diagonal pivoting method: | |||
| *> | |||
| *> A = U*D*U**T or A = L*D*L**T | |||
| *> | |||
| *> where U (or L) is a product of permutation and unit upper (lower) | |||
| *> triangular matrices, U**T is the transpose of U, and D is symmetric and | |||
| *> block diagonal with 1-by-1 and 2-by-2 diagonal blocks. | |||
| *> | |||
| *> This is the unblocked version of the algorithm, calling Level 2 BLAS. | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] UPLO | |||
| *> \verbatim | |||
| *> UPLO is CHARACTER*1 | |||
| *> Specifies whether the upper or lower triangular part of the | |||
| *> symmetric matrix A is stored: | |||
| *> = 'U': Upper triangular | |||
| *> = 'L': Lower triangular | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] N | |||
| *> \verbatim | |||
| *> N is INTEGER | |||
| *> The order of the matrix A. N >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] A | |||
| *> \verbatim | |||
| *> 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 | |||
| *> triangular part of A is not referenced. If UPLO = 'L', the | |||
| *> leading n-by-n lower triangular part of A contains the lower | |||
| *> triangular part of the matrix A, and the strictly upper | |||
| *> triangular part of A is not referenced. | |||
| *> | |||
| *> On exit, the block diagonal matrix D and the multipliers used | |||
| *> to obtain the factor U or L (see below for further details). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDA | |||
| *> \verbatim | |||
| *> LDA is INTEGER | |||
| *> The leading dimension of the array A. LDA >= max(1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] IPIV | |||
| *> \verbatim | |||
| *> IPIV is INTEGER array, dimension (N) | |||
| *> Details of the interchanges and the block structure of D. | |||
| *> | |||
| *> If UPLO = 'U': | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) | |||
| *> were interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) < 0 and IPIV(k-1) < 0, then rows and | |||
| *> columns k and -IPIV(k) were interchanged and rows and | |||
| *> columns k-1 and -IPIV(k-1) were inerchaged, | |||
| *> D(k-1:k,k-1:k) is a 2-by-2 diagonal block. | |||
| *> | |||
| *> If UPLO = 'L': | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) | |||
| *> were interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) < 0 and IPIV(k+1) < 0, then rows and | |||
| *> columns k and -IPIV(k) were interchanged and rows and | |||
| *> columns k+1 and -IPIV(k+1) were inerchaged, | |||
| *> D(k:k+1,k:k+1) is a 2-by-2 diagonal block. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] INFO | |||
| *> \verbatim | |||
| *> INFO is INTEGER | |||
| *> = 0: successful exit | |||
| *> < 0: if INFO = -k, the k-th argument had an illegal value | |||
| *> > 0: if INFO = k, D(k,k) is exactly zero. The factorization | |||
| *> has been completed, but the block diagonal matrix D is | |||
| *> exactly singular, and division by zero will occur if it | |||
| *> is used to solve a system of equations. | |||
| *> \endverbatim | |||
| * | |||
| * Authors: | |||
| * ======== | |||
| * | |||
| *> \author Univ. of Tennessee | |||
| *> \author Univ. of California Berkeley | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup complexSYcomputational | |||
| * | |||
| *> \par Further Details: | |||
| * ===================== | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> If UPLO = 'U', then A = U*D*U**T, where | |||
| *> U = P(n)*U(n)* ... *P(k)U(k)* ..., | |||
| *> i.e., U is a product of terms P(k)*U(k), where k decreases from n to | |||
| *> 1 in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1 | |||
| *> and 2-by-2 diagonal blocks D(k). P(k) is a permutation matrix as | |||
| *> defined by IPIV(k), and U(k) is a unit upper triangular matrix, such | |||
| *> that if the diagonal block D(k) is of order s (s = 1 or 2), then | |||
| *> | |||
| *> ( I v 0 ) k-s | |||
| *> U(k) = ( 0 I 0 ) s | |||
| *> ( 0 0 I ) n-k | |||
| *> k-s s n-k | |||
| *> | |||
| *> If s = 1, D(k) overwrites A(k,k), and v overwrites A(1:k-1,k). | |||
| *> If s = 2, the upper triangle of D(k) overwrites A(k-1,k-1), A(k-1,k), | |||
| *> and A(k,k), and v overwrites A(1:k-2,k-1:k). | |||
| *> | |||
| *> If UPLO = 'L', then A = L*D*L**T, where | |||
| *> L = P(1)*L(1)* ... *P(k)*L(k)* ..., | |||
| *> i.e., L is a product of terms P(k)*L(k), where k increases from 1 to | |||
| *> n in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1 | |||
| *> and 2-by-2 diagonal blocks D(k). P(k) is a permutation matrix as | |||
| *> defined by IPIV(k), and L(k) is a unit lower triangular matrix, such | |||
| *> that if the diagonal block D(k) is of order s (s = 1 or 2), then | |||
| *> | |||
| *> ( I 0 0 ) k-1 | |||
| *> L(k) = ( 0 I 0 ) s | |||
| *> ( 0 v I ) n-k-s+1 | |||
| *> k-1 s n-k-s+1 | |||
| *> | |||
| *> If s = 1, D(k) overwrites A(k,k), and v overwrites A(k+1:n,k). | |||
| *> If s = 2, the lower triangle of D(k) overwrites A(k,k), A(k+1,k), | |||
| *> and A(k+1,k+1), and v overwrites A(k+2:n,k:k+1). | |||
| *> \endverbatim | |||
| * | |||
| *> \par Contributors: | |||
| * ================== | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> November 2013, Igor Kozachenko, | |||
| *> Computer Science Division, | |||
| *> University of California, Berkeley | |||
| *> | |||
| *> September 2007, Sven Hammarling, Nicholas J. Higham, Craig Lucas, | |||
| *> School of Mathematics, | |||
| *> University of Manchester | |||
| *> | |||
| *> 01-01-96 - Based on modifications by | |||
| *> J. Lewis, Boeing Computer Services Company | |||
| *> A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville abd , USA | |||
| *> \endverbatim | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE CSYTF2_ROOK( UPLO, N, A, LDA, IPIV, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER UPLO | |||
| INTEGER INFO, LDA, N | |||
| * .. | |||
| * .. Array Arguments .. | |||
| INTEGER IPIV( * ) | |||
| COMPLEX A( LDA, * ) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| REAL ZERO, ONE | |||
| PARAMETER ( ZERO = 0.0E+0, ONE = 1.0E+0 ) | |||
| REAL EIGHT, SEVTEN | |||
| PARAMETER ( EIGHT = 8.0E+0, SEVTEN = 17.0E+0 ) | |||
| COMPLEX CONE | |||
| PARAMETER ( CONE = ( 1.0E+0, 0.0E+0 ) ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| LOGICAL UPPER, DONE | |||
| INTEGER I, IMAX, J, JMAX, ITEMP, K, KK, KP, KSTEP, | |||
| $ P, II | |||
| REAL ABSAKK, ALPHA, COLMAX, ROWMAX, STEMP, SFMIN | |||
| COMPLEX D11, D12, D21, D22, T, WK, WKM1, WKP1, Z | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| INTEGER ICAMAX | |||
| REAL SLAMCH | |||
| EXTERNAL LSAME, ICAMAX, SLAMCH | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL CSCAL, CSWAP, CSYR, XERBLA | |||
| * .. | |||
| * .. Intrinsic Functions .. | |||
| INTRINSIC ABS, MAX, SQRT, AIMAG, REAL | |||
| * .. | |||
| * .. Statement Functions .. | |||
| REAL CABS1 | |||
| * .. | |||
| * .. Statement Function definitions .. | |||
| CABS1( Z ) = ABS( REAL( Z ) ) + ABS( AIMAG( Z ) ) | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Test the input parameters. | |||
| * | |||
| INFO = 0 | |||
| UPPER = LSAME( UPLO, 'U' ) | |||
| IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN | |||
| INFO = -1 | |||
| ELSE IF( N.LT.0 ) THEN | |||
| INFO = -2 | |||
| ELSE IF( LDA.LT.MAX( 1, N ) ) THEN | |||
| INFO = -4 | |||
| END IF | |||
| IF( INFO.NE.0 ) THEN | |||
| CALL XERBLA( 'CSYTF2_ROOK', -INFO ) | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Initialize ALPHA for use in choosing pivot block size. | |||
| * | |||
| ALPHA = ( ONE+SQRT( SEVTEN ) ) / EIGHT | |||
| * | |||
| * Compute machine safe minimum | |||
| * | |||
| SFMIN = SLAMCH( 'S' ) | |||
| * | |||
| IF( UPPER ) THEN | |||
| * | |||
| * Factorize A as U*D*U**T using the upper triangle of A | |||
| * | |||
| * K is the main loop index, decreasing from N to 1 in steps of | |||
| * 1 or 2 | |||
| * | |||
| K = N | |||
| 10 CONTINUE | |||
| * | |||
| * If K < 1, exit from loop | |||
| * | |||
| IF( K.LT.1 ) | |||
| $ GO TO 70 | |||
| KSTEP = 1 | |||
| P = K | |||
| * | |||
| * Determine rows and columns to be interchanged and whether | |||
| * a 1-by-1 or 2-by-2 pivot block will be used | |||
| * | |||
| ABSAKK = CABS1( A( K, K ) ) | |||
| * | |||
| * IMAX is the row-index of the largest off-diagonal element in | |||
| * column K, and COLMAX is its absolute value. | |||
| * Determine both COLMAX and IMAX. | |||
| * | |||
| IF( K.GT.1 ) THEN | |||
| IMAX = ICAMAX( K-1, A( 1, K ), 1 ) | |||
| COLMAX = CABS1( A( IMAX, K ) ) | |||
| ELSE | |||
| COLMAX = ZERO | |||
| END IF | |||
| * | |||
| IF( (MAX( ABSAKK, COLMAX ).EQ.ZERO) ) THEN | |||
| * | |||
| * Column K is zero or underflow: set INFO and continue | |||
| * | |||
| IF( INFO.EQ.0 ) | |||
| $ INFO = K | |||
| KP = K | |||
| ELSE | |||
| * | |||
| * Test for interchange | |||
| * | |||
| * Equivalent to testing for (used to handle NaN and Inf) | |||
| * ABSAKK.GE.ALPHA*COLMAX | |||
| * | |||
| IF( .NOT.( ABSAKK.LT.ALPHA*COLMAX ) ) THEN | |||
| * | |||
| * no interchange, | |||
| * use 1-by-1 pivot block | |||
| * | |||
| KP = K | |||
| ELSE | |||
| * | |||
| DONE = .FALSE. | |||
| * | |||
| * Loop until pivot found | |||
| * | |||
| 12 CONTINUE | |||
| * | |||
| * Begin pivot search loop body | |||
| * | |||
| * JMAX is the column-index of the largest off-diagonal | |||
| * element in row IMAX, and ROWMAX is its absolute value. | |||
| * Determine both ROWMAX and JMAX. | |||
| * | |||
| IF( IMAX.NE.K ) THEN | |||
| JMAX = IMAX + ICAMAX( K-IMAX, A( IMAX, IMAX+1 ), | |||
| $ LDA ) | |||
| ROWMAX = CABS1( A( IMAX, JMAX ) ) | |||
| ELSE | |||
| ROWMAX = ZERO | |||
| END IF | |||
| * | |||
| IF( IMAX.GT.1 ) THEN | |||
| ITEMP = ICAMAX( IMAX-1, A( 1, IMAX ), 1 ) | |||
| STEMP = CABS1( A( ITEMP, IMAX ) ) | |||
| IF( STEMP.GT.ROWMAX ) THEN | |||
| ROWMAX = STEMP | |||
| JMAX = ITEMP | |||
| END IF | |||
| END IF | |||
| * | |||
| * Equivalent to testing for (used to handle NaN and Inf) | |||
| * CABS1( A( IMAX, IMAX ) ).GE.ALPHA*ROWMAX | |||
| * | |||
| IF( .NOT.( CABS1(A( IMAX, IMAX )).LT.ALPHA*ROWMAX ) ) | |||
| $ THEN | |||
| * | |||
| * interchange rows and columns K and IMAX, | |||
| * use 1-by-1 pivot block | |||
| * | |||
| KP = IMAX | |||
| DONE = .TRUE. | |||
| * | |||
| * Equivalent to testing for ROWMAX .EQ. COLMAX, | |||
| * used to handle NaN and Inf | |||
| * | |||
| ELSE IF( ( P.EQ.JMAX ).OR.( ROWMAX.LE.COLMAX ) ) THEN | |||
| * | |||
| * interchange rows and columns K+1 and IMAX, | |||
| * use 2-by-2 pivot block | |||
| * | |||
| KP = IMAX | |||
| KSTEP = 2 | |||
| DONE = .TRUE. | |||
| ELSE | |||
| * | |||
| * Pivot NOT found, set variables and repeat | |||
| * | |||
| P = IMAX | |||
| COLMAX = ROWMAX | |||
| IMAX = JMAX | |||
| END IF | |||
| * | |||
| * End pivot search loop body | |||
| * | |||
| IF( .NOT. DONE ) GOTO 12 | |||
| * | |||
| END IF | |||
| * | |||
| * Swap TWO rows and TWO columns | |||
| * | |||
| * First swap | |||
| * | |||
| IF( ( KSTEP.EQ.2 ) .AND. ( P.NE.K ) ) THEN | |||
| * | |||
| * Interchange rows and column K and P in the leading | |||
| * submatrix A(1:k,1:k) if we have a 2-by-2 pivot | |||
| * | |||
| IF( P.GT.1 ) | |||
| $ CALL CSWAP( P-1, A( 1, K ), 1, A( 1, P ), 1 ) | |||
| IF( P.LT.(K-1) ) | |||
| $ CALL CSWAP( K-P-1, A( P+1, K ), 1, A( P, P+1 ), | |||
| $ LDA ) | |||
| T = A( K, K ) | |||
| A( K, K ) = A( P, P ) | |||
| A( P, P ) = T | |||
| END IF | |||
| * | |||
| * Second swap | |||
| * | |||
| KK = K - KSTEP + 1 | |||
| IF( KP.NE.KK ) THEN | |||
| * | |||
| * Interchange rows and columns KK and KP in the leading | |||
| * submatrix A(1:k,1:k) | |||
| * | |||
| IF( KP.GT.1 ) | |||
| $ CALL CSWAP( KP-1, A( 1, KK ), 1, A( 1, KP ), 1 ) | |||
| IF( ( KK.GT.1 ) .AND. ( KP.LT.(KK-1) ) ) | |||
| $ CALL CSWAP( KK-KP-1, A( KP+1, KK ), 1, A( KP, KP+1 ), | |||
| $ LDA ) | |||
| T = A( KK, KK ) | |||
| A( KK, KK ) = A( KP, KP ) | |||
| A( KP, KP ) = T | |||
| IF( KSTEP.EQ.2 ) THEN | |||
| T = A( K-1, K ) | |||
| A( K-1, K ) = A( KP, K ) | |||
| A( KP, K ) = T | |||
| END IF | |||
| END IF | |||
| * | |||
| * Update the leading submatrix | |||
| * | |||
| IF( KSTEP.EQ.1 ) THEN | |||
| * | |||
| * 1-by-1 pivot block D(k): column k now holds | |||
| * | |||
| * W(k) = U(k)*D(k) | |||
| * | |||
| * where U(k) is the k-th column of U | |||
| * | |||
| IF( K.GT.1 ) THEN | |||
| * | |||
| * Perform a rank-1 update of A(1:k-1,1:k-1) and | |||
| * store U(k) in column k | |||
| * | |||
| IF( CABS1( A( K, K ) ).GE.SFMIN ) THEN | |||
| * | |||
| * Perform a rank-1 update of A(1:k-1,1:k-1) as | |||
| * A := A - U(k)*D(k)*U(k)**T | |||
| * = A - W(k)*1/D(k)*W(k)**T | |||
| * | |||
| D11 = CONE / A( K, K ) | |||
| CALL CSYR( UPLO, K-1, -D11, A( 1, K ), 1, A, LDA ) | |||
| * | |||
| * Store U(k) in column k | |||
| * | |||
| CALL CSCAL( K-1, D11, A( 1, K ), 1 ) | |||
| ELSE | |||
| * | |||
| * Store L(k) in column K | |||
| * | |||
| D11 = A( K, K ) | |||
| DO 16 II = 1, K - 1 | |||
| A( II, K ) = A( II, K ) / D11 | |||
| 16 CONTINUE | |||
| * | |||
| * Perform a rank-1 update of A(k+1:n,k+1:n) as | |||
| * A := A - U(k)*D(k)*U(k)**T | |||
| * = A - W(k)*(1/D(k))*W(k)**T | |||
| * = A - (W(k)/D(k))*(D(k))*(W(k)/D(K))**T | |||
| * | |||
| CALL CSYR( UPLO, K-1, -D11, A( 1, K ), 1, A, LDA ) | |||
| END IF | |||
| END IF | |||
| * | |||
| ELSE | |||
| * | |||
| * 2-by-2 pivot block D(k): columns k and k-1 now hold | |||
| * | |||
| * ( W(k-1) W(k) ) = ( U(k-1) U(k) )*D(k) | |||
| * | |||
| * where U(k) and U(k-1) are the k-th and (k-1)-th columns | |||
| * of U | |||
| * | |||
| * Perform a rank-2 update of A(1:k-2,1:k-2) as | |||
| * | |||
| * A := A - ( U(k-1) U(k) )*D(k)*( U(k-1) U(k) )**T | |||
| * = A - ( ( A(k-1)A(k) )*inv(D(k)) ) * ( A(k-1)A(k) )**T | |||
| * | |||
| * and store L(k) and L(k+1) in columns k and k+1 | |||
| * | |||
| IF( K.GT.2 ) THEN | |||
| * | |||
| D12 = A( K-1, K ) | |||
| D22 = A( K-1, K-1 ) / D12 | |||
| D11 = A( K, K ) / D12 | |||
| T = CONE / ( D11*D22-CONE ) | |||
| * | |||
| DO 30 J = K - 2, 1, -1 | |||
| * | |||
| WKM1 = T*( D11*A( J, K-1 )-A( J, K ) ) | |||
| WK = T*( D22*A( J, K )-A( J, K-1 ) ) | |||
| * | |||
| DO 20 I = J, 1, -1 | |||
| A( I, J ) = A( I, J ) - (A( I, K ) / D12 )*WK - | |||
| $ ( A( I, K-1 ) / D12 )*WKM1 | |||
| 20 CONTINUE | |||
| * | |||
| * Store U(k) and U(k-1) in cols k and k-1 for row J | |||
| * | |||
| A( J, K ) = WK / D12 | |||
| A( J, K-1 ) = WKM1 / D12 | |||
| * | |||
| 30 CONTINUE | |||
| * | |||
| END IF | |||
| * | |||
| END IF | |||
| END IF | |||
| * | |||
| * Store details of the interchanges in IPIV | |||
| * | |||
| IF( KSTEP.EQ.1 ) THEN | |||
| IPIV( K ) = KP | |||
| ELSE | |||
| IPIV( K ) = -P | |||
| IPIV( K-1 ) = -KP | |||
| END IF | |||
| * | |||
| * Decrease K and return to the start of the main loop | |||
| * | |||
| K = K - KSTEP | |||
| GO TO 10 | |||
| * | |||
| ELSE | |||
| * | |||
| * Factorize A as L*D*L**T using the lower triangle of A | |||
| * | |||
| * K is the main loop index, increasing from 1 to N in steps of | |||
| * 1 or 2 | |||
| * | |||
| K = 1 | |||
| 40 CONTINUE | |||
| * | |||
| * If K > N, exit from loop | |||
| * | |||
| IF( K.GT.N ) | |||
| $ GO TO 70 | |||
| KSTEP = 1 | |||
| P = K | |||
| * | |||
| * Determine rows and columns to be interchanged and whether | |||
| * a 1-by-1 or 2-by-2 pivot block will be used | |||
| * | |||
| ABSAKK = CABS1( A( K, K ) ) | |||
| * | |||
| * IMAX is the row-index of the largest off-diagonal element in | |||
| * column K, and COLMAX is its absolute value. | |||
| * Determine both COLMAX and IMAX. | |||
| * | |||
| IF( K.LT.N ) THEN | |||
| IMAX = K + ICAMAX( N-K, A( K+1, K ), 1 ) | |||
| COLMAX = CABS1( A( IMAX, K ) ) | |||
| ELSE | |||
| COLMAX = ZERO | |||
| END IF | |||
| * | |||
| IF( ( MAX( ABSAKK, COLMAX ).EQ.ZERO ) ) THEN | |||
| * | |||
| * Column K is zero or underflow: set INFO and continue | |||
| * | |||
| IF( INFO.EQ.0 ) | |||
| $ INFO = K | |||
| KP = K | |||
| ELSE | |||
| * | |||
| * Test for interchange | |||
| * | |||
| * Equivalent to testing for (used to handle NaN and Inf) | |||
| * ABSAKK.GE.ALPHA*COLMAX | |||
| * | |||
| IF( .NOT.( ABSAKK.LT.ALPHA*COLMAX ) ) THEN | |||
| * | |||
| * no interchange, use 1-by-1 pivot block | |||
| * | |||
| KP = K | |||
| ELSE | |||
| * | |||
| DONE = .FALSE. | |||
| * | |||
| * Loop until pivot found | |||
| * | |||
| 42 CONTINUE | |||
| * | |||
| * Begin pivot search loop body | |||
| * | |||
| * JMAX is the column-index of the largest off-diagonal | |||
| * element in row IMAX, and ROWMAX is its absolute value. | |||
| * Determine both ROWMAX and JMAX. | |||
| * | |||
| IF( IMAX.NE.K ) THEN | |||
| JMAX = K - 1 + ICAMAX( IMAX-K, A( IMAX, K ), LDA ) | |||
| ROWMAX = CABS1( A( IMAX, JMAX ) ) | |||
| ELSE | |||
| ROWMAX = ZERO | |||
| END IF | |||
| * | |||
| IF( IMAX.LT.N ) THEN | |||
| ITEMP = IMAX + ICAMAX( N-IMAX, A( IMAX+1, IMAX ), | |||
| $ 1 ) | |||
| STEMP = CABS1( A( ITEMP, IMAX ) ) | |||
| IF( STEMP.GT.ROWMAX ) THEN | |||
| ROWMAX = STEMP | |||
| JMAX = ITEMP | |||
| END IF | |||
| END IF | |||
| * | |||
| * Equivalent to testing for (used to handle NaN and Inf) | |||
| * CABS1( A( IMAX, IMAX ) ).GE.ALPHA*ROWMAX | |||
| * | |||
| IF( .NOT.( CABS1(A( IMAX, IMAX )).LT.ALPHA*ROWMAX ) ) | |||
| $ THEN | |||
| * | |||
| * interchange rows and columns K and IMAX, | |||
| * use 1-by-1 pivot block | |||
| * | |||
| KP = IMAX | |||
| DONE = .TRUE. | |||
| * | |||
| * Equivalent to testing for ROWMAX .EQ. COLMAX, | |||
| * used to handle NaN and Inf | |||
| * | |||
| ELSE IF( ( P.EQ.JMAX ).OR.( ROWMAX.LE.COLMAX ) ) THEN | |||
| * | |||
| * interchange rows and columns K+1 and IMAX, | |||
| * use 2-by-2 pivot block | |||
| * | |||
| KP = IMAX | |||
| KSTEP = 2 | |||
| DONE = .TRUE. | |||
| ELSE | |||
| * | |||
| * Pivot NOT found, set variables and repeat | |||
| * | |||
| P = IMAX | |||
| COLMAX = ROWMAX | |||
| IMAX = JMAX | |||
| END IF | |||
| * | |||
| * End pivot search loop body | |||
| * | |||
| IF( .NOT. DONE ) GOTO 42 | |||
| * | |||
| END IF | |||
| * | |||
| * Swap TWO rows and TWO columns | |||
| * | |||
| * First swap | |||
| * | |||
| IF( ( KSTEP.EQ.2 ) .AND. ( P.NE.K ) ) THEN | |||
| * | |||
| * Interchange rows and column K and P in the trailing | |||
| * submatrix A(k:n,k:n) if we have a 2-by-2 pivot | |||
| * | |||
| IF( P.LT.N ) | |||
| $ CALL CSWAP( N-P, A( P+1, K ), 1, A( P+1, P ), 1 ) | |||
| IF( P.GT.(K+1) ) | |||
| $ CALL CSWAP( P-K-1, A( K+1, K ), 1, A( P, K+1 ), LDA ) | |||
| T = A( K, K ) | |||
| A( K, K ) = A( P, P ) | |||
| A( P, P ) = T | |||
| END IF | |||
| * | |||
| * Second swap | |||
| * | |||
| KK = K + KSTEP - 1 | |||
| IF( KP.NE.KK ) THEN | |||
| * | |||
| * Interchange rows and columns KK and KP in the trailing | |||
| * submatrix A(k:n,k:n) | |||
| * | |||
| IF( KP.LT.N ) | |||
| $ CALL CSWAP( N-KP, A( KP+1, KK ), 1, A( KP+1, KP ), 1 ) | |||
| IF( ( KK.LT.N ) .AND. ( KP.GT.(KK+1) ) ) | |||
| $ CALL CSWAP( KP-KK-1, A( KK+1, KK ), 1, A( KP, KK+1 ), | |||
| $ LDA ) | |||
| T = A( KK, KK ) | |||
| A( KK, KK ) = A( KP, KP ) | |||
| A( KP, KP ) = T | |||
| IF( KSTEP.EQ.2 ) THEN | |||
| T = A( K+1, K ) | |||
| A( K+1, K ) = A( KP, K ) | |||
| A( KP, K ) = T | |||
| END IF | |||
| END IF | |||
| * | |||
| * Update the trailing submatrix | |||
| * | |||
| IF( KSTEP.EQ.1 ) THEN | |||
| * | |||
| * 1-by-1 pivot block D(k): column k now holds | |||
| * | |||
| * W(k) = L(k)*D(k) | |||
| * | |||
| * where L(k) is the k-th column of L | |||
| * | |||
| IF( K.LT.N ) THEN | |||
| * | |||
| * Perform a rank-1 update of A(k+1:n,k+1:n) and | |||
| * store L(k) in column k | |||
| * | |||
| IF( CABS1( A( K, K ) ).GE.SFMIN ) THEN | |||
| * | |||
| * Perform a rank-1 update of A(k+1:n,k+1:n) as | |||
| * A := A - L(k)*D(k)*L(k)**T | |||
| * = A - W(k)*(1/D(k))*W(k)**T | |||
| * | |||
| D11 = CONE / A( K, K ) | |||
| CALL CSYR( UPLO, N-K, -D11, A( K+1, K ), 1, | |||
| $ A( K+1, K+1 ), LDA ) | |||
| * | |||
| * Store L(k) in column k | |||
| * | |||
| CALL CSCAL( N-K, D11, A( K+1, K ), 1 ) | |||
| ELSE | |||
| * | |||
| * Store L(k) in column k | |||
| * | |||
| D11 = A( K, K ) | |||
| DO 46 II = K + 1, N | |||
| A( II, K ) = A( II, K ) / D11 | |||
| 46 CONTINUE | |||
| * | |||
| * Perform a rank-1 update of A(k+1:n,k+1:n) as | |||
| * A := A - L(k)*D(k)*L(k)**T | |||
| * = A - W(k)*(1/D(k))*W(k)**T | |||
| * = A - (W(k)/D(k))*(D(k))*(W(k)/D(K))**T | |||
| * | |||
| CALL CSYR( UPLO, N-K, -D11, A( K+1, K ), 1, | |||
| $ A( K+1, K+1 ), LDA ) | |||
| END IF | |||
| END IF | |||
| * | |||
| ELSE | |||
| * | |||
| * 2-by-2 pivot block D(k): columns k and k+1 now hold | |||
| * | |||
| * ( W(k) W(k+1) ) = ( L(k) L(k+1) )*D(k) | |||
| * | |||
| * where L(k) and L(k+1) are the k-th and (k+1)-th columns | |||
| * of L | |||
| * | |||
| * | |||
| * Perform a rank-2 update of A(k+2:n,k+2:n) as | |||
| * | |||
| * A := A - ( L(k) L(k+1) ) * D(k) * ( L(k) L(k+1) )**T | |||
| * = A - ( ( A(k)A(k+1) )*inv(D(k) ) * ( A(k)A(k+1) )**T | |||
| * | |||
| * and store L(k) and L(k+1) in columns k and k+1 | |||
| * | |||
| IF( K.LT.N-1 ) THEN | |||
| * | |||
| D21 = A( K+1, K ) | |||
| D11 = A( K+1, K+1 ) / D21 | |||
| D22 = A( K, K ) / D21 | |||
| T = CONE / ( D11*D22-CONE ) | |||
| * | |||
| DO 60 J = K + 2, N | |||
| * | |||
| * Compute D21 * ( W(k)W(k+1) ) * inv(D(k)) for row J | |||
| * | |||
| WK = T*( D11*A( J, K )-A( J, K+1 ) ) | |||
| WKP1 = T*( D22*A( J, K+1 )-A( J, K ) ) | |||
| * | |||
| * Perform a rank-2 update of A(k+2:n,k+2:n) | |||
| * | |||
| DO 50 I = J, N | |||
| A( I, J ) = A( I, J ) - ( A( I, K ) / D21 )*WK - | |||
| $ ( A( I, K+1 ) / D21 )*WKP1 | |||
| 50 CONTINUE | |||
| * | |||
| * Store L(k) and L(k+1) in cols k and k+1 for row J | |||
| * | |||
| A( J, K ) = WK / D21 | |||
| A( J, K+1 ) = WKP1 / D21 | |||
| * | |||
| 60 CONTINUE | |||
| * | |||
| END IF | |||
| * | |||
| END IF | |||
| END IF | |||
| * | |||
| * Store details of the interchanges in IPIV | |||
| * | |||
| IF( KSTEP.EQ.1 ) THEN | |||
| IPIV( K ) = KP | |||
| ELSE | |||
| IPIV( K ) = -P | |||
| IPIV( K+1 ) = -KP | |||
| END IF | |||
| * | |||
| * Increase K and return to the start of the main loop | |||
| * | |||
| K = K + KSTEP | |||
| GO TO 40 | |||
| * | |||
| END IF | |||
| * | |||
| 70 CONTINUE | |||
| * | |||
| RETURN | |||
| * | |||
| * End of CSYTF2_ROOK | |||
| * | |||
| END | |||
| @@ -0,0 +1,393 @@ | |||
| *> \brief \b CSYTRF_ROOK | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download CSYTRF_ROOK + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/csytrf_rook.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/csytrf_rook.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/csytrf_rook.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE CSYTRF_ROOK( UPLO, N, A, LDA, IPIV, WORK, LWORK, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * CHARACTER UPLO | |||
| * INTEGER INFO, LDA, LWORK, N | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * INTEGER IPIV( * ) | |||
| * COMPLEX A( LDA, * ), WORK( * ) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| * ============= | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> CSYTRF_ROOK computes the factorization of a complex symmetric matrix A | |||
| *> using the bounded Bunch-Kaufman ("rook") diagonal pivoting method. | |||
| *> The form of the factorization is | |||
| *> | |||
| *> A = U*D*U**T or A = L*D*L**T | |||
| *> | |||
| *> where U (or L) is a product of permutation and unit upper (lower) | |||
| *> triangular matrices, and D is symmetric and block diagonal with | |||
| *> 1-by-1 and 2-by-2 diagonal blocks. | |||
| *> | |||
| *> This is the blocked version of the algorithm, calling Level 3 BLAS. | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] UPLO | |||
| *> \verbatim | |||
| *> UPLO is CHARACTER*1 | |||
| *> = 'U': Upper triangle of A is stored; | |||
| *> = 'L': Lower triangle of A is stored. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] N | |||
| *> \verbatim | |||
| *> N is INTEGER | |||
| *> The order of the matrix A. N >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] A | |||
| *> \verbatim | |||
| *> 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 | |||
| *> triangular part of A is not referenced. If UPLO = 'L', the | |||
| *> leading N-by-N lower triangular part of A contains the lower | |||
| *> triangular part of the matrix A, and the strictly upper | |||
| *> triangular part of A is not referenced. | |||
| *> | |||
| *> On exit, the block diagonal matrix D and the multipliers used | |||
| *> to obtain the factor U or L (see below for further details). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDA | |||
| *> \verbatim | |||
| *> LDA is INTEGER | |||
| *> The leading dimension of the array A. LDA >= max(1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] IPIV | |||
| *> \verbatim | |||
| *> IPIV is INTEGER array, dimension (N) | |||
| *> Details of the interchanges and the block structure of D. | |||
| *> | |||
| *> If UPLO = 'U': | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) | |||
| *> were interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) < 0 and IPIV(k-1) < 0, then rows and | |||
| *> columns k and -IPIV(k) were interchanged and rows and | |||
| *> columns k-1 and -IPIV(k-1) were inerchaged, | |||
| *> D(k-1:k,k-1:k) is a 2-by-2 diagonal block. | |||
| *> | |||
| *> If UPLO = 'L': | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) | |||
| *> were interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) < 0 and IPIV(k+1) < 0, then rows and | |||
| *> columns k and -IPIV(k) were interchanged and rows and | |||
| *> columns k+1 and -IPIV(k+1) were inerchaged, | |||
| *> D(k:k+1,k:k+1) is a 2-by-2 diagonal block. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] WORK | |||
| *> \verbatim | |||
| *> WORK is COMPLEX array, dimension (MAX(1,LWORK)). | |||
| *> On exit, if INFO = 0, WORK(1) returns the optimal LWORK. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LWORK | |||
| *> \verbatim | |||
| *> LWORK is INTEGER | |||
| *> The length of WORK. LWORK >=1. For best performance | |||
| *> LWORK >= N*NB, where NB is the block size returned by ILAENV. | |||
| *> | |||
| *> 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 | |||
| *> > 0: if INFO = i, D(i,i) is exactly zero. The factorization | |||
| *> has been completed, but the block diagonal matrix D is | |||
| *> exactly singular, and division by zero will occur if it | |||
| *> is used to solve a system of equations. | |||
| *> \endverbatim | |||
| * | |||
| * Authors: | |||
| * ======== | |||
| * | |||
| *> \author Univ. of Tennessee | |||
| *> \author Univ. of California Berkeley | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date November 2011 | |||
| * | |||
| *> \ingroup complexSYcomputational | |||
| * | |||
| *> \par Further Details: | |||
| * ===================== | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> If UPLO = 'U', then A = U*D*U**T, where | |||
| *> U = P(n)*U(n)* ... *P(k)U(k)* ..., | |||
| *> i.e., U is a product of terms P(k)*U(k), where k decreases from n to | |||
| *> 1 in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1 | |||
| *> and 2-by-2 diagonal blocks D(k). P(k) is a permutation matrix as | |||
| *> defined by IPIV(k), and U(k) is a unit upper triangular matrix, such | |||
| *> that if the diagonal block D(k) is of order s (s = 1 or 2), then | |||
| *> | |||
| *> ( I v 0 ) k-s | |||
| *> U(k) = ( 0 I 0 ) s | |||
| *> ( 0 0 I ) n-k | |||
| *> k-s s n-k | |||
| *> | |||
| *> If s = 1, D(k) overwrites A(k,k), and v overwrites A(1:k-1,k). | |||
| *> If s = 2, the upper triangle of D(k) overwrites A(k-1,k-1), A(k-1,k), | |||
| *> and A(k,k), and v overwrites A(1:k-2,k-1:k). | |||
| *> | |||
| *> If UPLO = 'L', then A = L*D*L**T, where | |||
| *> L = P(1)*L(1)* ... *P(k)*L(k)* ..., | |||
| *> i.e., L is a product of terms P(k)*L(k), where k increases from 1 to | |||
| *> n in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1 | |||
| *> and 2-by-2 diagonal blocks D(k). P(k) is a permutation matrix as | |||
| *> defined by IPIV(k), and L(k) is a unit lower triangular matrix, such | |||
| *> that if the diagonal block D(k) is of order s (s = 1 or 2), then | |||
| *> | |||
| *> ( I 0 0 ) k-1 | |||
| *> L(k) = ( 0 I 0 ) s | |||
| *> ( 0 v I ) n-k-s+1 | |||
| *> k-1 s n-k-s+1 | |||
| *> | |||
| *> If s = 1, D(k) overwrites A(k,k), and v overwrites A(k+1:n,k). | |||
| *> If s = 2, the lower triangle of D(k) overwrites A(k,k), A(k+1,k), | |||
| *> and A(k+1,k+1), and v overwrites A(k+2:n,k:k+1). | |||
| *> \endverbatim | |||
| * | |||
| *> \par Contributors: | |||
| * ================== | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> November 2011, Igor Kozachenko, | |||
| *> Computer Science Division, | |||
| *> University of California, Berkeley | |||
| *> | |||
| *> September 2007, Sven Hammarling, Nicholas J. Higham, Craig Lucas, | |||
| *> School of Mathematics, | |||
| *> University of Manchester | |||
| *> | |||
| *> \endverbatim | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE CSYTRF_ROOK( UPLO, N, A, LDA, IPIV, WORK, LWORK, INFO ) | |||
| * | |||
| * -- 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 UPLO | |||
| INTEGER INFO, LDA, LWORK, N | |||
| * .. | |||
| * .. Array Arguments .. | |||
| INTEGER IPIV( * ) | |||
| COMPLEX A( LDA, * ), WORK( * ) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Local Scalars .. | |||
| LOGICAL LQUERY, UPPER | |||
| INTEGER IINFO, IWS, J, K, KB, LDWORK, LWKOPT, NB, NBMIN | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| INTEGER ILAENV | |||
| EXTERNAL LSAME, ILAENV | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL CLASYF_ROOK, CSYTF2_ROOK, XERBLA | |||
| * .. | |||
| * .. Intrinsic Functions .. | |||
| INTRINSIC MAX | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Test the input parameters. | |||
| * | |||
| INFO = 0 | |||
| UPPER = LSAME( UPLO, 'U' ) | |||
| LQUERY = ( LWORK.EQ.-1 ) | |||
| IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN | |||
| INFO = -1 | |||
| ELSE IF( N.LT.0 ) THEN | |||
| INFO = -2 | |||
| ELSE IF( LDA.LT.MAX( 1, N ) ) THEN | |||
| INFO = -4 | |||
| ELSE IF( LWORK.LT.1 .AND. .NOT.LQUERY ) THEN | |||
| INFO = -7 | |||
| END IF | |||
| * | |||
| IF( INFO.EQ.0 ) THEN | |||
| * | |||
| * Determine the block size | |||
| * | |||
| NB = ILAENV( 1, 'CSYTRF_ROOK', UPLO, N, -1, -1, -1 ) | |||
| LWKOPT = N*NB | |||
| WORK( 1 ) = LWKOPT | |||
| END IF | |||
| * | |||
| IF( INFO.NE.0 ) THEN | |||
| CALL XERBLA( 'CSYTRF_ROOK', -INFO ) | |||
| RETURN | |||
| ELSE IF( LQUERY ) THEN | |||
| RETURN | |||
| END IF | |||
| * | |||
| NBMIN = 2 | |||
| LDWORK = N | |||
| IF( NB.GT.1 .AND. NB.LT.N ) THEN | |||
| IWS = LDWORK*NB | |||
| IF( LWORK.LT.IWS ) THEN | |||
| NB = MAX( LWORK / LDWORK, 1 ) | |||
| NBMIN = MAX( 2, ILAENV( 2, 'CSYTRF_ROOK', | |||
| $ UPLO, N, -1, -1, -1 ) ) | |||
| END IF | |||
| ELSE | |||
| IWS = 1 | |||
| END IF | |||
| IF( NB.LT.NBMIN ) | |||
| $ NB = N | |||
| * | |||
| IF( UPPER ) THEN | |||
| * | |||
| * Factorize A as U*D*U**T using the upper triangle of A | |||
| * | |||
| * K is the main loop index, decreasing from N to 1 in steps of | |||
| * KB, where KB is the number of columns factorized by CLASYF_ROOK; | |||
| * KB is either NB or NB-1, or K for the last block | |||
| * | |||
| K = N | |||
| 10 CONTINUE | |||
| * | |||
| * If K < 1, exit from loop | |||
| * | |||
| IF( K.LT.1 ) | |||
| $ GO TO 40 | |||
| * | |||
| IF( K.GT.NB ) THEN | |||
| * | |||
| * Factorize columns k-kb+1:k of A and use blocked code to | |||
| * update columns 1:k-kb | |||
| * | |||
| CALL CLASYF_ROOK( UPLO, K, NB, KB, A, LDA, | |||
| $ IPIV, WORK, LDWORK, IINFO ) | |||
| ELSE | |||
| * | |||
| * Use unblocked code to factorize columns 1:k of A | |||
| * | |||
| CALL CSYTF2_ROOK( UPLO, K, A, LDA, IPIV, IINFO ) | |||
| KB = K | |||
| END IF | |||
| * | |||
| * Set INFO on the first occurrence of a zero pivot | |||
| * | |||
| IF( INFO.EQ.0 .AND. IINFO.GT.0 ) | |||
| $ INFO = IINFO | |||
| * | |||
| * No need to adjust IPIV | |||
| * | |||
| * Decrease K and return to the start of the main loop | |||
| * | |||
| K = K - KB | |||
| GO TO 10 | |||
| * | |||
| ELSE | |||
| * | |||
| * Factorize A as L*D*L**T using the lower triangle of A | |||
| * | |||
| * K is the main loop index, increasing from 1 to N in steps of | |||
| * KB, where KB is the number of columns factorized by CLASYF_ROOK; | |||
| * KB is either NB or NB-1, or N-K+1 for the last block | |||
| * | |||
| K = 1 | |||
| 20 CONTINUE | |||
| * | |||
| * If K > N, exit from loop | |||
| * | |||
| IF( K.GT.N ) | |||
| $ GO TO 40 | |||
| * | |||
| IF( K.LE.N-NB ) THEN | |||
| * | |||
| * Factorize columns k:k+kb-1 of A and use blocked code to | |||
| * update columns k+kb:n | |||
| * | |||
| CALL CLASYF_ROOK( UPLO, N-K+1, NB, KB, A( K, K ), LDA, | |||
| $ IPIV( K ), WORK, LDWORK, IINFO ) | |||
| ELSE | |||
| * | |||
| * Use unblocked code to factorize columns k:n of A | |||
| * | |||
| CALL CSYTF2_ROOK( UPLO, N-K+1, A( K, K ), LDA, IPIV( K ), | |||
| $ IINFO ) | |||
| KB = N - K + 1 | |||
| END IF | |||
| * | |||
| * Set INFO on the first occurrence of a zero pivot | |||
| * | |||
| IF( INFO.EQ.0 .AND. IINFO.GT.0 ) | |||
| $ INFO = IINFO + K - 1 | |||
| * | |||
| * Adjust IPIV | |||
| * | |||
| DO 30 J = K, K + KB - 1 | |||
| IF( IPIV( J ).GT.0 ) THEN | |||
| IPIV( J ) = IPIV( J ) + K - 1 | |||
| ELSE | |||
| IPIV( J ) = IPIV( J ) - K + 1 | |||
| END IF | |||
| 30 CONTINUE | |||
| * | |||
| * Increase K and return to the start of the main loop | |||
| * | |||
| K = K + KB | |||
| GO TO 20 | |||
| * | |||
| END IF | |||
| * | |||
| 40 CONTINUE | |||
| WORK( 1 ) = LWKOPT | |||
| RETURN | |||
| * | |||
| * End of CSYTRF_ROOK | |||
| * | |||
| END | |||
| @@ -0,0 +1,451 @@ | |||
| *> \brief \b CSYTRI_ROOK | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download CSYTRI_ROOK + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/csytri_rook.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/csytri_rook.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/csytri_rook.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE CSYTRI_ROOK( UPLO, N, A, LDA, IPIV, WORK, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * CHARACTER UPLO | |||
| * INTEGER INFO, LDA, N | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * INTEGER IPIV( * ) | |||
| * COMPLEX A( LDA, * ), WORK( * ) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| * ============= | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> CSYTRI_ROOK computes the inverse of a complex symmetric | |||
| *> matrix A using the factorization A = U*D*U**T or A = L*D*L**T | |||
| *> computed by CSYTRF_ROOK. | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] UPLO | |||
| *> \verbatim | |||
| *> UPLO is CHARACTER*1 | |||
| *> Specifies whether the details of the factorization are stored | |||
| *> as an upper or lower triangular matrix. | |||
| *> = 'U': Upper triangular, form is A = U*D*U**T; | |||
| *> = 'L': Lower triangular, form is A = L*D*L**T. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] N | |||
| *> \verbatim | |||
| *> N is INTEGER | |||
| *> The order of the matrix A. N >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] A | |||
| *> \verbatim | |||
| *> A is COMPLEX array, dimension (LDA,N) | |||
| *> On entry, the block diagonal matrix D and the multipliers | |||
| *> used to obtain the factor U or L as computed by CSYTRF_ROOK. | |||
| *> | |||
| *> On exit, if INFO = 0, the (symmetric) inverse of the original | |||
| *> matrix. If UPLO = 'U', the upper triangular part of the | |||
| *> inverse is formed and the part of A below the diagonal is not | |||
| *> referenced; if UPLO = 'L' the lower triangular part of the | |||
| *> inverse is formed and the part of A above the diagonal is | |||
| *> not referenced. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDA | |||
| *> \verbatim | |||
| *> LDA is INTEGER | |||
| *> The leading dimension of the array A. LDA >= max(1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] IPIV | |||
| *> \verbatim | |||
| *> IPIV is INTEGER array, dimension (N) | |||
| *> Details of the interchanges and the block structure of D | |||
| *> as determined by CSYTRF_ROOK. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] WORK | |||
| *> \verbatim | |||
| *> WORK is COMPLEX array, dimension (N) | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] INFO | |||
| *> \verbatim | |||
| *> INFO is INTEGER | |||
| *> = 0: successful exit | |||
| *> < 0: if INFO = -i, the i-th argument had an illegal value | |||
| *> > 0: if INFO = i, D(i,i) = 0; the matrix is singular and its | |||
| *> inverse could not be computed. | |||
| *> \endverbatim | |||
| * | |||
| * Authors: | |||
| * ======== | |||
| * | |||
| *> \author Univ. of Tennessee | |||
| *> \author Univ. of California Berkeley | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date November 2011 | |||
| * | |||
| *> \ingroup complexSYcomputational | |||
| * | |||
| *> \par Contributors: | |||
| * ================== | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> November 2011, Igor Kozachenko, | |||
| *> Computer Science Division, | |||
| *> University of California, Berkeley | |||
| *> | |||
| *> September 2007, Sven Hammarling, Nicholas J. Higham, Craig Lucas, | |||
| *> School of Mathematics, | |||
| *> University of Manchester | |||
| *> | |||
| *> \endverbatim | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE CSYTRI_ROOK( UPLO, N, A, LDA, IPIV, WORK, INFO ) | |||
| * | |||
| * -- 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 UPLO | |||
| INTEGER INFO, LDA, N | |||
| * .. | |||
| * .. Array Arguments .. | |||
| INTEGER IPIV( * ) | |||
| COMPLEX A( LDA, * ), WORK( * ) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| COMPLEX CONE, CZERO | |||
| PARAMETER ( CONE = ( 1.0E+0, 0.0E+0 ), | |||
| $ CZERO = ( 0.0E+0, 0.0E+0 ) ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| LOGICAL UPPER | |||
| INTEGER K, KP, KSTEP | |||
| COMPLEX AK, AKKP1, AKP1, D, T, TEMP | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| COMPLEX CDOTU | |||
| EXTERNAL LSAME, CDOTU | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL CCOPY, CSWAP, CSYMV, XERBLA | |||
| * .. | |||
| * .. Intrinsic Functions .. | |||
| INTRINSIC MAX | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Test the input parameters. | |||
| * | |||
| INFO = 0 | |||
| UPPER = LSAME( UPLO, 'U' ) | |||
| IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN | |||
| INFO = -1 | |||
| ELSE IF( N.LT.0 ) THEN | |||
| INFO = -2 | |||
| ELSE IF( LDA.LT.MAX( 1, N ) ) THEN | |||
| INFO = -4 | |||
| END IF | |||
| IF( INFO.NE.0 ) THEN | |||
| CALL XERBLA( 'CSYTRI_ROOK', -INFO ) | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Quick return if possible | |||
| * | |||
| IF( N.EQ.0 ) | |||
| $ RETURN | |||
| * | |||
| * Check that the diagonal matrix D is nonsingular. | |||
| * | |||
| IF( UPPER ) THEN | |||
| * | |||
| * Upper triangular storage: examine D from bottom to top | |||
| * | |||
| DO 10 INFO = N, 1, -1 | |||
| IF( IPIV( INFO ).GT.0 .AND. A( INFO, INFO ).EQ.CZERO ) | |||
| $ RETURN | |||
| 10 CONTINUE | |||
| ELSE | |||
| * | |||
| * Lower triangular storage: examine D from top to bottom. | |||
| * | |||
| DO 20 INFO = 1, N | |||
| IF( IPIV( INFO ).GT.0 .AND. A( INFO, INFO ).EQ.CZERO ) | |||
| $ RETURN | |||
| 20 CONTINUE | |||
| END IF | |||
| INFO = 0 | |||
| * | |||
| IF( UPPER ) THEN | |||
| * | |||
| * Compute inv(A) from the factorization A = U*D*U**T. | |||
| * | |||
| * K is the main loop index, increasing from 1 to N in steps of | |||
| * 1 or 2, depending on the size of the diagonal blocks. | |||
| * | |||
| K = 1 | |||
| 30 CONTINUE | |||
| * | |||
| * If K > N, exit from loop. | |||
| * | |||
| IF( K.GT.N ) | |||
| $ GO TO 40 | |||
| * | |||
| IF( IPIV( K ).GT.0 ) THEN | |||
| * | |||
| * 1 x 1 diagonal block | |||
| * | |||
| * Invert the diagonal block. | |||
| * | |||
| A( K, K ) = CONE / A( K, K ) | |||
| * | |||
| * Compute column K of the inverse. | |||
| * | |||
| IF( K.GT.1 ) THEN | |||
| CALL CCOPY( K-1, A( 1, K ), 1, WORK, 1 ) | |||
| CALL CSYMV( UPLO, K-1, -CONE, A, LDA, WORK, 1, CZERO, | |||
| $ A( 1, K ), 1 ) | |||
| A( K, K ) = A( K, K ) - CDOTU( K-1, WORK, 1, A( 1, K ), | |||
| $ 1 ) | |||
| END IF | |||
| KSTEP = 1 | |||
| ELSE | |||
| * | |||
| * 2 x 2 diagonal block | |||
| * | |||
| * Invert the diagonal block. | |||
| * | |||
| T = A( K, K+1 ) | |||
| AK = A( K, K ) / T | |||
| AKP1 = A( K+1, K+1 ) / T | |||
| AKKP1 = A( K, K+1 ) / T | |||
| D = T*( AK*AKP1-CONE ) | |||
| A( K, K ) = AKP1 / D | |||
| A( K+1, K+1 ) = AK / D | |||
| A( K, K+1 ) = -AKKP1 / D | |||
| * | |||
| * Compute columns K and K+1 of the inverse. | |||
| * | |||
| IF( K.GT.1 ) THEN | |||
| CALL CCOPY( K-1, A( 1, K ), 1, WORK, 1 ) | |||
| CALL CSYMV( UPLO, K-1, -CONE, A, LDA, WORK, 1, CZERO, | |||
| $ A( 1, K ), 1 ) | |||
| A( K, K ) = A( K, K ) - CDOTU( K-1, WORK, 1, A( 1, K ), | |||
| $ 1 ) | |||
| A( K, K+1 ) = A( K, K+1 ) - | |||
| $ CDOTU( K-1, A( 1, K ), 1, A( 1, K+1 ), 1 ) | |||
| CALL CCOPY( K-1, A( 1, K+1 ), 1, WORK, 1 ) | |||
| CALL CSYMV( UPLO, K-1, -CONE, A, LDA, WORK, 1, CZERO, | |||
| $ A( 1, K+1 ), 1 ) | |||
| A( K+1, K+1 ) = A( K+1, K+1 ) - | |||
| $ CDOTU( K-1, WORK, 1, A( 1, K+1 ), 1 ) | |||
| END IF | |||
| KSTEP = 2 | |||
| END IF | |||
| * | |||
| IF( KSTEP.EQ.1 ) THEN | |||
| * | |||
| * Interchange rows and columns K and IPIV(K) in the leading | |||
| * submatrix A(1:k+1,1:k+1) | |||
| * | |||
| KP = IPIV( K ) | |||
| IF( KP.NE.K ) THEN | |||
| IF( KP.GT.1 ) | |||
| $ CALL CSWAP( KP-1, A( 1, K ), 1, A( 1, KP ), 1 ) | |||
| CALL CSWAP( K-KP-1, A( KP+1, K ), 1, A( KP, KP+1 ), LDA ) | |||
| TEMP = A( K, K ) | |||
| A( K, K ) = A( KP, KP ) | |||
| A( KP, KP ) = TEMP | |||
| END IF | |||
| ELSE | |||
| * | |||
| * Interchange rows and columns K and K+1 with -IPIV(K) and | |||
| * -IPIV(K+1)in the leading submatrix A(1:k+1,1:k+1) | |||
| * | |||
| KP = -IPIV( K ) | |||
| IF( KP.NE.K ) THEN | |||
| IF( KP.GT.1 ) | |||
| $ CALL CSWAP( KP-1, A( 1, K ), 1, A( 1, KP ), 1 ) | |||
| CALL CSWAP( K-KP-1, A( KP+1, K ), 1, A( KP, KP+1 ), LDA ) | |||
| * | |||
| TEMP = A( K, K ) | |||
| A( K, K ) = A( KP, KP ) | |||
| A( KP, KP ) = TEMP | |||
| TEMP = A( K, K+1 ) | |||
| A( K, K+1 ) = A( KP, K+1 ) | |||
| A( KP, K+1 ) = TEMP | |||
| END IF | |||
| * | |||
| K = K + 1 | |||
| KP = -IPIV( K ) | |||
| IF( KP.NE.K ) THEN | |||
| IF( KP.GT.1 ) | |||
| $ CALL CSWAP( KP-1, A( 1, K ), 1, A( 1, KP ), 1 ) | |||
| CALL CSWAP( K-KP-1, A( KP+1, K ), 1, A( KP, KP+1 ), LDA ) | |||
| TEMP = A( K, K ) | |||
| A( K, K ) = A( KP, KP ) | |||
| A( KP, KP ) = TEMP | |||
| END IF | |||
| END IF | |||
| * | |||
| K = K + 1 | |||
| GO TO 30 | |||
| 40 CONTINUE | |||
| * | |||
| ELSE | |||
| * | |||
| * Compute inv(A) from the factorization A = L*D*L**T. | |||
| * | |||
| * K is the main loop index, increasing from 1 to N in steps of | |||
| * 1 or 2, depending on the size of the diagonal blocks. | |||
| * | |||
| K = N | |||
| 50 CONTINUE | |||
| * | |||
| * If K < 1, exit from loop. | |||
| * | |||
| IF( K.LT.1 ) | |||
| $ GO TO 60 | |||
| * | |||
| IF( IPIV( K ).GT.0 ) THEN | |||
| * | |||
| * 1 x 1 diagonal block | |||
| * | |||
| * Invert the diagonal block. | |||
| * | |||
| A( K, K ) = CONE / A( K, K ) | |||
| * | |||
| * Compute column K of the inverse. | |||
| * | |||
| IF( K.LT.N ) THEN | |||
| CALL CCOPY( N-K, A( K+1, K ), 1, WORK, 1 ) | |||
| CALL CSYMV( UPLO, N-K,-CONE, A( K+1, K+1 ), LDA, WORK, 1, | |||
| $ CZERO, A( K+1, K ), 1 ) | |||
| A( K, K ) = A( K, K ) - CDOTU( N-K, WORK, 1, A( K+1, K ), | |||
| $ 1 ) | |||
| END IF | |||
| KSTEP = 1 | |||
| ELSE | |||
| * | |||
| * 2 x 2 diagonal block | |||
| * | |||
| * Invert the diagonal block. | |||
| * | |||
| T = A( K, K-1 ) | |||
| AK = A( K-1, K-1 ) / T | |||
| AKP1 = A( K, K ) / T | |||
| AKKP1 = A( K, K-1 ) / T | |||
| D = T*( AK*AKP1-CONE ) | |||
| A( K-1, K-1 ) = AKP1 / D | |||
| A( K, K ) = AK / D | |||
| A( K, K-1 ) = -AKKP1 / D | |||
| * | |||
| * Compute columns K-1 and K of the inverse. | |||
| * | |||
| IF( K.LT.N ) THEN | |||
| CALL CCOPY( N-K, A( K+1, K ), 1, WORK, 1 ) | |||
| CALL CSYMV( UPLO, N-K,-CONE, A( K+1, K+1 ), LDA, WORK, 1, | |||
| $ CZERO, A( K+1, K ), 1 ) | |||
| A( K, K ) = A( K, K ) - CDOTU( N-K, WORK, 1, A( K+1, K ), | |||
| $ 1 ) | |||
| A( K, K-1 ) = A( K, K-1 ) - | |||
| $ CDOTU( N-K, A( K+1, K ), 1, A( K+1, K-1 ), | |||
| $ 1 ) | |||
| CALL CCOPY( N-K, A( K+1, K-1 ), 1, WORK, 1 ) | |||
| CALL CSYMV( UPLO, N-K,-CONE, A( K+1, K+1 ), LDA, WORK, 1, | |||
| $ CZERO, A( K+1, K-1 ), 1 ) | |||
| A( K-1, K-1 ) = A( K-1, K-1 ) - | |||
| $ CDOTU( N-K, WORK, 1, A( K+1, K-1 ), 1 ) | |||
| END IF | |||
| KSTEP = 2 | |||
| END IF | |||
| * | |||
| IF( KSTEP.EQ.1 ) THEN | |||
| * | |||
| * Interchange rows and columns K and IPIV(K) in the trailing | |||
| * submatrix A(k-1:n,k-1:n) | |||
| * | |||
| KP = IPIV( K ) | |||
| IF( KP.NE.K ) THEN | |||
| IF( KP.LT.N ) | |||
| $ CALL CSWAP( N-KP, A( KP+1, K ), 1, A( KP+1, KP ), 1 ) | |||
| CALL CSWAP( KP-K-1, A( K+1, K ), 1, A( KP, K+1 ), LDA ) | |||
| TEMP = A( K, K ) | |||
| A( K, K ) = A( KP, KP ) | |||
| A( KP, KP ) = TEMP | |||
| END IF | |||
| ELSE | |||
| * | |||
| * Interchange rows and columns K and K-1 with -IPIV(K) and | |||
| * -IPIV(K-1) in the trailing submatrix A(k-1:n,k-1:n) | |||
| * | |||
| KP = -IPIV( K ) | |||
| IF( KP.NE.K ) THEN | |||
| IF( KP.LT.N ) | |||
| $ CALL CSWAP( N-KP, A( KP+1, K ), 1, A( KP+1, KP ), 1 ) | |||
| CALL CSWAP( KP-K-1, A( K+1, K ), 1, A( KP, K+1 ), LDA ) | |||
| * | |||
| TEMP = A( K, K ) | |||
| A( K, K ) = A( KP, KP ) | |||
| A( KP, KP ) = TEMP | |||
| TEMP = A( K, K-1 ) | |||
| A( K, K-1 ) = A( KP, K-1 ) | |||
| A( KP, K-1 ) = TEMP | |||
| END IF | |||
| * | |||
| K = K - 1 | |||
| KP = -IPIV( K ) | |||
| IF( KP.NE.K ) THEN | |||
| IF( KP.LT.N ) | |||
| $ CALL CSWAP( N-KP, A( KP+1, K ), 1, A( KP+1, KP ), 1 ) | |||
| CALL CSWAP( KP-K-1, A( K+1, K ), 1, A( KP, K+1 ), LDA ) | |||
| TEMP = A( K, K ) | |||
| A( K, K ) = A( KP, KP ) | |||
| A( KP, KP ) = TEMP | |||
| END IF | |||
| END IF | |||
| * | |||
| K = K - 1 | |||
| GO TO 50 | |||
| 60 CONTINUE | |||
| END IF | |||
| * | |||
| RETURN | |||
| * | |||
| * End of CSYTRI_ROOK | |||
| * | |||
| END | |||
| @@ -0,0 +1,484 @@ | |||
| *> \brief \b CSYTRS_ROOK | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download CSYTRS_ROOK + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/csytrs_rook.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/csytrs_rook.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/csytrs_rook.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE CSYTRS_ROOK( UPLO, N, NRHS, A, LDA, IPIV, B, LDB, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * CHARACTER UPLO | |||
| * INTEGER INFO, LDA, LDB, N, NRHS | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * INTEGER IPIV( * ) | |||
| * COMPLEX A( LDA, * ), B( LDB, * ) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| * ============= | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> CSYTRS_ROOK solves a system of linear equations A*X = B with | |||
| *> a complex symmetric matrix A using the factorization A = U*D*U**T or | |||
| *> A = L*D*L**T computed by CSYTRF_ROOK. | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] UPLO | |||
| *> \verbatim | |||
| *> UPLO is CHARACTER*1 | |||
| *> Specifies whether the details of the factorization are stored | |||
| *> as an upper or lower triangular matrix. | |||
| *> = 'U': Upper triangular, form is A = U*D*U**T; | |||
| *> = 'L': Lower triangular, form is A = L*D*L**T. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] N | |||
| *> \verbatim | |||
| *> N is INTEGER | |||
| *> The order of the matrix A. N >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] NRHS | |||
| *> \verbatim | |||
| *> NRHS is INTEGER | |||
| *> The number of right hand sides, i.e., the number of columns | |||
| *> of the matrix B. NRHS >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] A | |||
| *> \verbatim | |||
| *> A is COMPLEX array, dimension (LDA,N) | |||
| *> The block diagonal matrix D and the multipliers used to | |||
| *> obtain the factor U or L as computed by CSYTRF_ROOK. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDA | |||
| *> \verbatim | |||
| *> LDA is INTEGER | |||
| *> The leading dimension of the array A. LDA >= max(1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] IPIV | |||
| *> \verbatim | |||
| *> IPIV is INTEGER array, dimension (N) | |||
| *> Details of the interchanges and the block structure of D | |||
| *> as determined by CSYTRF_ROOK. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] B | |||
| *> \verbatim | |||
| *> B is COMPLEX array, dimension (LDB,NRHS) | |||
| *> On entry, the right hand side matrix B. | |||
| *> On exit, the solution matrix X. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDB | |||
| *> \verbatim | |||
| *> LDB is INTEGER | |||
| *> The leading dimension of the array B. LDB >= max(1,N). | |||
| *> \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 | |||
| * | |||
| *> \ingroup complexSYcomputational | |||
| * | |||
| *> \par Contributors: | |||
| * ================== | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> November 2011, Igor Kozachenko, | |||
| *> Computer Science Division, | |||
| *> University of California, Berkeley | |||
| *> | |||
| *> September 2007, Sven Hammarling, Nicholas J. Higham, Craig Lucas, | |||
| *> School of Mathematics, | |||
| *> University of Manchester | |||
| *> | |||
| *> \endverbatim | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE CSYTRS_ROOK( UPLO, N, NRHS, A, LDA, IPIV, B, LDB, | |||
| $ INFO ) | |||
| * | |||
| * -- 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 UPLO | |||
| INTEGER INFO, LDA, LDB, N, NRHS | |||
| * .. | |||
| * .. Array Arguments .. | |||
| INTEGER IPIV( * ) | |||
| COMPLEX A( LDA, * ), B( LDB, * ) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| COMPLEX CONE | |||
| PARAMETER ( CONE = ( 1.0E+0, 0.0E+0 ) ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| LOGICAL UPPER | |||
| INTEGER J, K, KP | |||
| COMPLEX AK, AKM1, AKM1K, BK, BKM1, DENOM | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| EXTERNAL LSAME | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL CGEMV, CGERU, CSCAL, CSWAP, XERBLA | |||
| * .. | |||
| * .. Intrinsic Functions .. | |||
| INTRINSIC MAX | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| INFO = 0 | |||
| UPPER = LSAME( UPLO, 'U' ) | |||
| IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN | |||
| INFO = -1 | |||
| ELSE IF( N.LT.0 ) THEN | |||
| INFO = -2 | |||
| ELSE IF( NRHS.LT.0 ) THEN | |||
| INFO = -3 | |||
| ELSE IF( LDA.LT.MAX( 1, N ) ) THEN | |||
| INFO = -5 | |||
| ELSE IF( LDB.LT.MAX( 1, N ) ) THEN | |||
| INFO = -8 | |||
| END IF | |||
| IF( INFO.NE.0 ) THEN | |||
| CALL XERBLA( 'CSYTRS_ROOK', -INFO ) | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Quick return if possible | |||
| * | |||
| IF( N.EQ.0 .OR. NRHS.EQ.0 ) | |||
| $ RETURN | |||
| * | |||
| IF( UPPER ) THEN | |||
| * | |||
| * Solve A*X = B, where A = U*D*U**T. | |||
| * | |||
| * First solve U*D*X = B, overwriting B with X. | |||
| * | |||
| * K is the main loop index, decreasing from N to 1 in steps of | |||
| * 1 or 2, depending on the size of the diagonal blocks. | |||
| * | |||
| K = N | |||
| 10 CONTINUE | |||
| * | |||
| * If K < 1, exit from loop. | |||
| * | |||
| IF( K.LT.1 ) | |||
| $ GO TO 30 | |||
| * | |||
| IF( IPIV( K ).GT.0 ) THEN | |||
| * | |||
| * 1 x 1 diagonal block | |||
| * | |||
| * Interchange rows K and IPIV(K). | |||
| * | |||
| KP = IPIV( K ) | |||
| IF( KP.NE.K ) | |||
| $ CALL CSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| * | |||
| * Multiply by inv(U(K)), where U(K) is the transformation | |||
| * stored in column K of A. | |||
| * | |||
| CALL CGERU( K-1, NRHS, -CONE, A( 1, K ), 1, B( K, 1 ), LDB, | |||
| $ B( 1, 1 ), LDB ) | |||
| * | |||
| * Multiply by the inverse of the diagonal block. | |||
| * | |||
| CALL CSCAL( NRHS, CONE / A( K, K ), B( K, 1 ), LDB ) | |||
| K = K - 1 | |||
| ELSE | |||
| * | |||
| * 2 x 2 diagonal block | |||
| * | |||
| * Interchange rows K and -IPIV(K) THEN K-1 and -IPIV(K-1) | |||
| * | |||
| KP = -IPIV( K ) | |||
| IF( KP.NE.K ) | |||
| $ CALL CSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| * | |||
| KP = -IPIV( K-1 ) | |||
| IF( KP.NE.K-1 ) | |||
| $ CALL CSWAP( NRHS, B( K-1, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| * | |||
| * Multiply by inv(U(K)), where U(K) is the transformation | |||
| * stored in columns K-1 and K of A. | |||
| * | |||
| IF( K.GT.2 ) THEN | |||
| CALL CGERU( K-2, NRHS,-CONE, A( 1, K ), 1, B( K, 1 ), | |||
| $ LDB, B( 1, 1 ), LDB ) | |||
| CALL CGERU( K-2, NRHS,-CONE, A( 1, K-1 ), 1, B( K-1, 1 ), | |||
| $ LDB, B( 1, 1 ), LDB ) | |||
| END IF | |||
| * | |||
| * Multiply by the inverse of the diagonal block. | |||
| * | |||
| AKM1K = A( K-1, K ) | |||
| AKM1 = A( K-1, K-1 ) / AKM1K | |||
| AK = A( K, K ) / AKM1K | |||
| DENOM = AKM1*AK - CONE | |||
| DO 20 J = 1, NRHS | |||
| BKM1 = B( K-1, J ) / AKM1K | |||
| BK = B( K, J ) / AKM1K | |||
| B( K-1, J ) = ( AK*BKM1-BK ) / DENOM | |||
| B( K, J ) = ( AKM1*BK-BKM1 ) / DENOM | |||
| 20 CONTINUE | |||
| K = K - 2 | |||
| END IF | |||
| * | |||
| GO TO 10 | |||
| 30 CONTINUE | |||
| * | |||
| * Next solve U**T *X = B, overwriting B with X. | |||
| * | |||
| * K is the main loop index, increasing from 1 to N in steps of | |||
| * 1 or 2, depending on the size of the diagonal blocks. | |||
| * | |||
| K = 1 | |||
| 40 CONTINUE | |||
| * | |||
| * If K > N, exit from loop. | |||
| * | |||
| IF( K.GT.N ) | |||
| $ GO TO 50 | |||
| * | |||
| IF( IPIV( K ).GT.0 ) THEN | |||
| * | |||
| * 1 x 1 diagonal block | |||
| * | |||
| * Multiply by inv(U**T(K)), where U(K) is the transformation | |||
| * stored in column K of A. | |||
| * | |||
| IF( K.GT.1 ) | |||
| $ CALL CGEMV( 'Transpose', K-1, NRHS, -CONE, B, | |||
| $ LDB, A( 1, K ), 1, CONE, B( K, 1 ), LDB ) | |||
| * | |||
| * Interchange rows K and IPIV(K). | |||
| * | |||
| KP = IPIV( K ) | |||
| IF( KP.NE.K ) | |||
| $ CALL CSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| K = K + 1 | |||
| ELSE | |||
| * | |||
| * 2 x 2 diagonal block | |||
| * | |||
| * Multiply by inv(U**T(K+1)), where U(K+1) is the transformation | |||
| * stored in columns K and K+1 of A. | |||
| * | |||
| IF( K.GT.1 ) THEN | |||
| CALL CGEMV( 'Transpose', K-1, NRHS, -CONE, B, | |||
| $ LDB, A( 1, K ), 1, CONE, B( K, 1 ), LDB ) | |||
| CALL CGEMV( 'Transpose', K-1, NRHS, -CONE, B, | |||
| $ LDB, A( 1, K+1 ), 1, CONE, B( K+1, 1 ), LDB ) | |||
| END IF | |||
| * | |||
| * Interchange rows K and -IPIV(K) THEN K+1 and -IPIV(K+1). | |||
| * | |||
| KP = -IPIV( K ) | |||
| IF( KP.NE.K ) | |||
| $ CALL CSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| * | |||
| KP = -IPIV( K+1 ) | |||
| IF( KP.NE.K+1 ) | |||
| $ CALL CSWAP( NRHS, B( K+1, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| * | |||
| K = K + 2 | |||
| END IF | |||
| * | |||
| GO TO 40 | |||
| 50 CONTINUE | |||
| * | |||
| ELSE | |||
| * | |||
| * Solve A*X = B, where A = L*D*L**T. | |||
| * | |||
| * First solve L*D*X = B, overwriting B with X. | |||
| * | |||
| * K is the main loop index, increasing from 1 to N in steps of | |||
| * 1 or 2, depending on the size of the diagonal blocks. | |||
| * | |||
| K = 1 | |||
| 60 CONTINUE | |||
| * | |||
| * If K > N, exit from loop. | |||
| * | |||
| IF( K.GT.N ) | |||
| $ GO TO 80 | |||
| * | |||
| IF( IPIV( K ).GT.0 ) THEN | |||
| * | |||
| * 1 x 1 diagonal block | |||
| * | |||
| * Interchange rows K and IPIV(K). | |||
| * | |||
| KP = IPIV( K ) | |||
| IF( KP.NE.K ) | |||
| $ CALL CSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| * | |||
| * Multiply by inv(L(K)), where L(K) is the transformation | |||
| * stored in column K of A. | |||
| * | |||
| IF( K.LT.N ) | |||
| $ CALL CGERU( N-K, NRHS, -CONE, A( K+1, K ), 1, B( K, 1 ), | |||
| $ LDB, B( K+1, 1 ), LDB ) | |||
| * | |||
| * Multiply by the inverse of the diagonal block. | |||
| * | |||
| CALL CSCAL( NRHS, CONE / A( K, K ), B( K, 1 ), LDB ) | |||
| K = K + 1 | |||
| ELSE | |||
| * | |||
| * 2 x 2 diagonal block | |||
| * | |||
| * Interchange rows K and -IPIV(K) THEN K+1 and -IPIV(K+1) | |||
| * | |||
| KP = -IPIV( K ) | |||
| IF( KP.NE.K ) | |||
| $ CALL CSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| * | |||
| KP = -IPIV( K+1 ) | |||
| IF( KP.NE.K+1 ) | |||
| $ CALL CSWAP( NRHS, B( K+1, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| * | |||
| * Multiply by inv(L(K)), where L(K) is the transformation | |||
| * stored in columns K and K+1 of A. | |||
| * | |||
| IF( K.LT.N-1 ) THEN | |||
| CALL CGERU( N-K-1, NRHS,-CONE, A( K+2, K ), 1, B( K, 1 ), | |||
| $ LDB, B( K+2, 1 ), LDB ) | |||
| CALL CGERU( N-K-1, NRHS,-CONE, A( K+2, K+1 ), 1, | |||
| $ B( K+1, 1 ), LDB, B( K+2, 1 ), LDB ) | |||
| END IF | |||
| * | |||
| * Multiply by the inverse of the diagonal block. | |||
| * | |||
| AKM1K = A( K+1, K ) | |||
| AKM1 = A( K, K ) / AKM1K | |||
| AK = A( K+1, K+1 ) / AKM1K | |||
| DENOM = AKM1*AK - CONE | |||
| DO 70 J = 1, NRHS | |||
| BKM1 = B( K, J ) / AKM1K | |||
| BK = B( K+1, J ) / AKM1K | |||
| B( K, J ) = ( AK*BKM1-BK ) / DENOM | |||
| B( K+1, J ) = ( AKM1*BK-BKM1 ) / DENOM | |||
| 70 CONTINUE | |||
| K = K + 2 | |||
| END IF | |||
| * | |||
| GO TO 60 | |||
| 80 CONTINUE | |||
| * | |||
| * Next solve L**T *X = B, overwriting B with X. | |||
| * | |||
| * K is the main loop index, decreasing from N to 1 in steps of | |||
| * 1 or 2, depending on the size of the diagonal blocks. | |||
| * | |||
| K = N | |||
| 90 CONTINUE | |||
| * | |||
| * If K < 1, exit from loop. | |||
| * | |||
| IF( K.LT.1 ) | |||
| $ GO TO 100 | |||
| * | |||
| IF( IPIV( K ).GT.0 ) THEN | |||
| * | |||
| * 1 x 1 diagonal block | |||
| * | |||
| * Multiply by inv(L**T(K)), where L(K) is the transformation | |||
| * stored in column K of A. | |||
| * | |||
| IF( K.LT.N ) | |||
| $ CALL CGEMV( 'Transpose', N-K, NRHS, -CONE, B( K+1, 1 ), | |||
| $ LDB, A( K+1, K ), 1, CONE, B( K, 1 ), LDB ) | |||
| * | |||
| * Interchange rows K and IPIV(K). | |||
| * | |||
| KP = IPIV( K ) | |||
| IF( KP.NE.K ) | |||
| $ CALL CSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| K = K - 1 | |||
| ELSE | |||
| * | |||
| * 2 x 2 diagonal block | |||
| * | |||
| * Multiply by inv(L**T(K-1)), where L(K-1) is the transformation | |||
| * stored in columns K-1 and K of A. | |||
| * | |||
| IF( K.LT.N ) THEN | |||
| CALL CGEMV( 'Transpose', N-K, NRHS, -CONE, B( K+1, 1 ), | |||
| $ LDB, A( K+1, K ), 1, CONE, B( K, 1 ), LDB ) | |||
| CALL CGEMV( 'Transpose', N-K, NRHS, -CONE, B( K+1, 1 ), | |||
| $ LDB, A( K+1, K-1 ), 1, CONE, B( K-1, 1 ), | |||
| $ LDB ) | |||
| END IF | |||
| * | |||
| * Interchange rows K and -IPIV(K) THEN K-1 and -IPIV(K-1) | |||
| * | |||
| KP = -IPIV( K ) | |||
| IF( KP.NE.K ) | |||
| $ CALL CSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| * | |||
| KP = -IPIV( K-1 ) | |||
| IF( KP.NE.K-1 ) | |||
| $ CALL CSWAP( NRHS, B( K-1, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| * | |||
| K = K - 2 | |||
| END IF | |||
| * | |||
| GO TO 90 | |||
| 100 CONTINUE | |||
| END IF | |||
| * | |||
| RETURN | |||
| * | |||
| * End of CSYTRS_ROOK | |||
| * | |||
| END | |||
| @@ -175,7 +175,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date April 2012 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup complexOTHERcomputational | |||
| * | |||
| @@ -216,10 +216,10 @@ | |||
| SUBROUTINE CTPMQRT( SIDE, TRANS, M, N, K, L, NB, V, LDV, T, LDT, | |||
| $ A, LDA, B, LDB, WORK, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.1) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * April 2012 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER SIDE, TRANS | |||
| @@ -235,7 +235,7 @@ | |||
| * .. | |||
| * .. Local Scalars .. | |||
| LOGICAL LEFT, RIGHT, TRAN, NOTRAN | |||
| INTEGER I, IB, MB, LB, KF, Q | |||
| INTEGER I, IB, MB, LB, KF, LDAQ, LDVQ | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| @@ -257,10 +257,12 @@ | |||
| TRAN = LSAME( TRANS, 'C' ) | |||
| NOTRAN = LSAME( TRANS, 'N' ) | |||
| * | |||
| IF( LEFT ) THEN | |||
| Q = M | |||
| IF ( LEFT ) THEN | |||
| LDVQ = MAX( 1, M ) | |||
| LDAQ = MAX( 1, K ) | |||
| ELSE IF ( RIGHT ) THEN | |||
| Q = N | |||
| LDVQ = MAX( 1, N ) | |||
| LDAQ = MAX( 1, M ) | |||
| END IF | |||
| IF( .NOT.LEFT .AND. .NOT.RIGHT ) THEN | |||
| INFO = -1 | |||
| @@ -274,13 +276,13 @@ | |||
| INFO = -5 | |||
| ELSE IF( L.LT.0 .OR. L.GT.K ) THEN | |||
| INFO = -6 | |||
| ELSE IF( NB.LT.1 .OR. NB.GT.K ) THEN | |||
| ELSE IF( NB.LT.1 .OR. (NB.GT.K .AND. K.GT.0) ) THEN | |||
| INFO = -7 | |||
| ELSE IF( LDV.LT.MAX( 1, Q ) ) THEN | |||
| ELSE IF( LDV.LT.LDVQ ) THEN | |||
| INFO = -9 | |||
| ELSE IF( LDT.LT.NB ) THEN | |||
| INFO = -11 | |||
| ELSE IF( LDA.LT.MAX( 1, M ) ) THEN | |||
| ELSE IF( LDA.LT.LDAQ ) THEN | |||
| INFO = -13 | |||
| ELSE IF( LDB.LT.MAX( 1, M ) ) THEN | |||
| INFO = -15 | |||
| @@ -132,7 +132,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date April 2012 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup complexOTHERcomputational | |||
| * | |||
| @@ -189,10 +189,10 @@ | |||
| SUBROUTINE CTPQRT( M, N, L, NB, A, LDA, B, LDB, T, LDT, WORK, | |||
| $ INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.1) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * April 2012 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| INTEGER INFO, LDA, LDB, LDT, N, M, L, NB | |||
| @@ -219,9 +219,9 @@ | |||
| INFO = -1 | |||
| ELSE IF( N.LT.0 ) THEN | |||
| INFO = -2 | |||
| ELSE IF( L.LT.0 .OR. L.GT.MIN(M,N) ) THEN | |||
| ELSE IF( L.LT.0 .OR. (L.GT.MIN(M,N) .AND. MIN(M,N).GE.0)) THEN | |||
| INFO = -3 | |||
| ELSE IF( NB.LT.1 .OR. NB.GT.N ) THEN | |||
| ELSE IF( NB.LT.1 .OR. (NB.GT.N .AND. N.GT.0)) THEN | |||
| INFO = -4 | |||
| ELSE IF( LDA.LT.MAX( 1, N ) ) THEN | |||
| INFO = -6 | |||
| @@ -255,7 +255,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date November 2011 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup complexOTHERcomputational | |||
| * | |||
| @@ -287,10 +287,10 @@ | |||
| $ X21, LDX21, X22, LDX22, THETA, PHI, TAUP1, | |||
| $ TAUP2, TAUQ1, TAUQ2, WORK, LWORK, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.0) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * November 2011 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER SIGNS, TRANS | |||
| @@ -420,19 +420,33 @@ | |||
| THETA(I) = ATAN2( SCNRM2( M-P-I+1, X21(I,I), 1 ), | |||
| $ SCNRM2( P-I+1, X11(I,I), 1 ) ) | |||
| * | |||
| CALL CLARFGP( P-I+1, X11(I,I), X11(I+1,I), 1, TAUP1(I) ) | |||
| IF( P .GT. I ) THEN | |||
| CALL CLARFGP( P-I+1, X11(I,I), X11(I+1,I), 1, TAUP1(I) ) | |||
| ELSE IF ( P .EQ. I ) THEN | |||
| CALL CLARFGP( P-I+1, X11(I,I), X11(I,I), 1, TAUP1(I) ) | |||
| END IF | |||
| X11(I,I) = ONE | |||
| CALL CLARFGP( M-P-I+1, X21(I,I), X21(I+1,I), 1, TAUP2(I) ) | |||
| IF ( M-P .GT. I ) THEN | |||
| CALL CLARFGP( M-P-I+1, X21(I,I), X21(I+1,I), 1, | |||
| $ TAUP2(I) ) | |||
| ELSE IF ( M-P .EQ. I ) THEN | |||
| CALL CLARFGP( M-P-I+1, X21(I,I), X21(I,I), 1, | |||
| $ TAUP2(I) ) | |||
| END IF | |||
| X21(I,I) = ONE | |||
| * | |||
| CALL CLARF( 'L', P-I+1, Q-I, X11(I,I), 1, CONJG(TAUP1(I)), | |||
| $ X11(I,I+1), LDX11, WORK ) | |||
| CALL CLARF( 'L', P-I+1, M-Q-I+1, X11(I,I), 1, | |||
| $ CONJG(TAUP1(I)), X12(I,I), LDX12, WORK ) | |||
| CALL CLARF( 'L', M-P-I+1, Q-I, X21(I,I), 1, CONJG(TAUP2(I)), | |||
| $ X21(I,I+1), LDX21, WORK ) | |||
| CALL CLARF( 'L', M-P-I+1, M-Q-I+1, X21(I,I), 1, | |||
| $ CONJG(TAUP2(I)), X22(I,I), LDX22, WORK ) | |||
| IF ( Q .GT. I ) THEN | |||
| CALL CLARF( 'L', P-I+1, Q-I, X11(I,I), 1, | |||
| $ CONJG(TAUP1(I)), X11(I,I+1), LDX11, WORK ) | |||
| CALL CLARF( 'L', M-P-I+1, Q-I, X21(I,I), 1, | |||
| $ CONJG(TAUP2(I)), X21(I,I+1), LDX21, WORK ) | |||
| END IF | |||
| IF ( M-Q+1 .GT. I ) THEN | |||
| CALL CLARF( 'L', P-I+1, M-Q-I+1, X11(I,I), 1, | |||
| $ CONJG(TAUP1(I)), X12(I,I), LDX12, WORK ) | |||
| CALL CLARF( 'L', M-P-I+1, M-Q-I+1, X21(I,I), 1, | |||
| $ CONJG(TAUP2(I)), X22(I,I), LDX22, WORK ) | |||
| END IF | |||
| * | |||
| IF( I .LT. Q ) THEN | |||
| CALL CSCAL( Q-I, CMPLX( -Z1*Z3*SIN(THETA(I)), 0.0E0 ), | |||
| @@ -451,13 +465,25 @@ | |||
| * | |||
| IF( I .LT. Q ) THEN | |||
| CALL CLACGV( Q-I, X11(I,I+1), LDX11 ) | |||
| CALL CLARFGP( Q-I, X11(I,I+1), X11(I,I+2), LDX11, | |||
| $ TAUQ1(I) ) | |||
| IF ( I .EQ. Q-1 ) THEN | |||
| CALL CLARFGP( Q-I, X11(I,I+1), X11(I,I+1), LDX11, | |||
| $ TAUQ1(I) ) | |||
| ELSE | |||
| CALL CLARFGP( Q-I, X11(I,I+1), X11(I,I+2), LDX11, | |||
| $ TAUQ1(I) ) | |||
| END IF | |||
| X11(I,I+1) = ONE | |||
| END IF | |||
| CALL CLACGV( M-Q-I+1, X12(I,I), LDX12 ) | |||
| CALL CLARFGP( M-Q-I+1, X12(I,I), X12(I,I+1), LDX12, | |||
| $ TAUQ2(I) ) | |||
| IF ( M-Q+1 .GT. I ) THEN | |||
| CALL CLACGV( M-Q-I+1, X12(I,I), LDX12 ) | |||
| IF ( M-Q .EQ. I ) THEN | |||
| CALL CLARFGP( M-Q-I+1, X12(I,I), X12(I,I), LDX12, | |||
| $ TAUQ2(I) ) | |||
| ELSE | |||
| CALL CLARFGP( M-Q-I+1, X12(I,I), X12(I,I+1), LDX12, | |||
| $ TAUQ2(I) ) | |||
| END IF | |||
| END IF | |||
| X12(I,I) = ONE | |||
| * | |||
| IF( I .LT. Q ) THEN | |||
| @@ -466,10 +492,14 @@ | |||
| CALL CLARF( 'R', M-P-I, Q-I, X11(I,I+1), LDX11, TAUQ1(I), | |||
| $ X21(I+1,I+1), LDX21, WORK ) | |||
| END IF | |||
| CALL CLARF( 'R', P-I, M-Q-I+1, X12(I,I), LDX12, TAUQ2(I), | |||
| $ X12(I+1,I), LDX12, WORK ) | |||
| CALL CLARF( 'R', M-P-I, M-Q-I+1, X12(I,I), LDX12, TAUQ2(I), | |||
| $ X22(I+1,I), LDX22, WORK ) | |||
| IF ( P .GT. I ) THEN | |||
| CALL CLARF( 'R', P-I, M-Q-I+1, X12(I,I), LDX12, TAUQ2(I), | |||
| $ X12(I+1,I), LDX12, WORK ) | |||
| END IF | |||
| IF ( M-P .GT. I ) THEN | |||
| CALL CLARF( 'R', M-P-I, M-Q-I+1, X12(I,I), LDX12, | |||
| $ TAUQ2(I), X22(I+1,I), LDX22, WORK ) | |||
| END IF | |||
| * | |||
| IF( I .LT. Q ) | |||
| $ CALL CLACGV( Q-I, X11(I,I+1), LDX11 ) | |||
| @@ -484,12 +514,19 @@ | |||
| CALL CSCAL( M-Q-I+1, CMPLX( -Z1*Z4, 0.0E0 ), X12(I,I), | |||
| $ LDX12 ) | |||
| CALL CLACGV( M-Q-I+1, X12(I,I), LDX12 ) | |||
| CALL CLARFGP( M-Q-I+1, X12(I,I), X12(I,I+1), LDX12, | |||
| $ TAUQ2(I) ) | |||
| IF ( I .GE. M-Q ) THEN | |||
| CALL CLARFGP( M-Q-I+1, X12(I,I), X12(I,I), LDX12, | |||
| $ TAUQ2(I) ) | |||
| ELSE | |||
| CALL CLARFGP( M-Q-I+1, X12(I,I), X12(I,I+1), LDX12, | |||
| $ TAUQ2(I) ) | |||
| END IF | |||
| X12(I,I) = ONE | |||
| * | |||
| CALL CLARF( 'R', P-I, M-Q-I+1, X12(I,I), LDX12, TAUQ2(I), | |||
| $ X12(I+1,I), LDX12, WORK ) | |||
| IF ( P .GT. I ) THEN | |||
| CALL CLARF( 'R', P-I, M-Q-I+1, X12(I,I), LDX12, TAUQ2(I), | |||
| $ X12(I+1,I), LDX12, WORK ) | |||
| END IF | |||
| IF( M-P-Q .GE. 1 ) | |||
| $ CALL CLARF( 'R', M-P-Q, M-Q-I+1, X12(I,I), LDX12, | |||
| $ TAUQ2(I), X22(Q+1,I), LDX22, WORK ) | |||
| @@ -548,8 +585,13 @@ | |||
| * | |||
| CALL CLARFGP( P-I+1, X11(I,I), X11(I,I+1), LDX11, TAUP1(I) ) | |||
| X11(I,I) = ONE | |||
| CALL CLARFGP( M-P-I+1, X21(I,I), X21(I,I+1), LDX21, | |||
| $ TAUP2(I) ) | |||
| IF ( I .EQ. M-P ) THEN | |||
| CALL CLARFGP( M-P-I+1, X21(I,I), X21(I,I), LDX21, | |||
| $ TAUP2(I) ) | |||
| ELSE | |||
| CALL CLARFGP( M-P-I+1, X21(I,I), X21(I,I+1), LDX21, | |||
| $ TAUP2(I) ) | |||
| END IF | |||
| X21(I,I) = ONE | |||
| * | |||
| CALL CLARF( 'R', Q-I, P-I+1, X11(I,I), LDX11, TAUP1(I), | |||
| @@ -594,9 +636,11 @@ | |||
| END IF | |||
| CALL CLARF( 'L', M-Q-I+1, P-I, X12(I,I), 1, CONJG(TAUQ2(I)), | |||
| $ X12(I,I+1), LDX12, WORK ) | |||
| CALL CLARF( 'L', M-Q-I+1, M-P-I, X12(I,I), 1, | |||
| $ CONJG(TAUQ2(I)), X22(I,I+1), LDX22, WORK ) | |||
| * | |||
| IF ( M-P .GT. I ) THEN | |||
| CALL CLARF( 'L', M-Q-I+1, M-P-I, X12(I,I), 1, | |||
| $ CONJG(TAUQ2(I)), X22(I,I+1), LDX22, WORK ) | |||
| END IF | |||
| END DO | |||
| * | |||
| * Reduce columns Q + 1, ..., P of X12, X22 | |||
| @@ -607,8 +651,10 @@ | |||
| CALL CLARFGP( M-Q-I+1, X12(I,I), X12(I+1,I), 1, TAUQ2(I) ) | |||
| X12(I,I) = ONE | |||
| * | |||
| CALL CLARF( 'L', M-Q-I+1, P-I, X12(I,I), 1, CONJG(TAUQ2(I)), | |||
| $ X12(I,I+1), LDX12, WORK ) | |||
| IF ( P .GT. I ) THEN | |||
| CALL CLARF( 'L', M-Q-I+1, P-I, X12(I,I), 1, | |||
| $ CONJG(TAUQ2(I)), X12(I,I+1), LDX12, WORK ) | |||
| END IF | |||
| IF( M-P-Q .GE. 1 ) | |||
| $ CALL CLARF( 'L', M-Q-I+1, M-P-Q, X12(I,I), 1, | |||
| $ CONJG(TAUQ2(I)), X22(I,Q+1), LDX22, WORK ) | |||
| @@ -624,10 +670,11 @@ | |||
| CALL CLARFGP( M-P-Q-I+1, X22(P+I,Q+I), X22(P+I+1,Q+I), 1, | |||
| $ TAUQ2(P+I) ) | |||
| X22(P+I,Q+I) = ONE | |||
| * | |||
| CALL CLARF( 'L', M-P-Q-I+1, M-P-Q-I, X22(P+I,Q+I), 1, | |||
| $ CONJG(TAUQ2(P+I)), X22(P+I,Q+I+1), LDX22, WORK ) | |||
| * | |||
| IF ( M-P-Q .NE. I ) THEN | |||
| CALL CLARF( 'L', M-P-Q-I+1, M-P-Q-I, X22(P+I,Q+I), 1, | |||
| $ CONJG(TAUQ2(P+I)), X22(P+I,Q+I+1), LDX22, | |||
| $ WORK ) | |||
| END IF | |||
| END DO | |||
| * | |||
| END IF | |||
| @@ -0,0 +1,327 @@ | |||
| *> \brief \b CUNBDB1 | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download CUNBDB1 + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/cunbdb1.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/cunbdb1.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/cunbdb1.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE CUNBDB1( M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI, | |||
| * TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * INTEGER INFO, LWORK, M, P, Q, LDX11, LDX21 | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * REAL PHI(*), THETA(*) | |||
| * COMPLEX TAUP1(*), TAUP2(*), TAUQ1(*), WORK(*), | |||
| * $ X11(LDX11,*), X21(LDX21,*) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| *> ============= | |||
| *> | |||
| *>\verbatim | |||
| *> | |||
| *> CUNBDB1 simultaneously bidiagonalizes the blocks of a tall and skinny | |||
| *> matrix X with orthonomal columns: | |||
| *> | |||
| *> [ B11 ] | |||
| *> [ X11 ] [ P1 | ] [ 0 ] | |||
| *> [-----] = [---------] [-----] Q1**T . | |||
| *> [ X21 ] [ | P2 ] [ B21 ] | |||
| *> [ 0 ] | |||
| *> | |||
| *> X11 is P-by-Q, and X21 is (M-P)-by-Q. Q must be no larger than P, | |||
| *> M-P, or M-Q. Routines CUNBDB2, CUNBDB3, and CUNBDB4 handle cases in | |||
| *> which Q is not the minimum dimension. | |||
| *> | |||
| *> The unitary matrices P1, P2, and Q1 are P-by-P, (M-P)-by-(M-P), | |||
| *> and (M-Q)-by-(M-Q), respectively. They are represented implicitly by | |||
| *> Householder vectors. | |||
| *> | |||
| *> B11 and B12 are Q-by-Q bidiagonal matrices represented implicitly by | |||
| *> angles THETA, PHI. | |||
| *> | |||
| *>\endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] M | |||
| *> \verbatim | |||
| *> M is INTEGER | |||
| *> The number of rows X11 plus the number of rows in X21. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] P | |||
| *> \verbatim | |||
| *> P is INTEGER | |||
| *> The number of rows in X11. 0 <= P <= M. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] Q | |||
| *> \verbatim | |||
| *> Q is INTEGER | |||
| *> The number of columns in X11 and X21. 0 <= Q <= | |||
| *> MIN(P,M-P,M-Q). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X11 | |||
| *> \verbatim | |||
| *> X11 is COMPLEX array, dimension (LDX11,Q) | |||
| *> On entry, the top block of the matrix X to be reduced. On | |||
| *> exit, the columns of tril(X11) specify reflectors for P1 and | |||
| *> the rows of triu(X11,1) specify reflectors for Q1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDX11 | |||
| *> \verbatim | |||
| *> LDX11 is INTEGER | |||
| *> The leading dimension of X11. LDX11 >= P. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X21 | |||
| *> \verbatim | |||
| *> X21 is COMPLEX array, dimension (LDX21,Q) | |||
| *> On entry, the bottom block of the matrix X to be reduced. On | |||
| *> exit, the columns of tril(X21) specify reflectors for P2. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDX21 | |||
| *> \verbatim | |||
| *> LDX21 is INTEGER | |||
| *> The leading dimension of X21. LDX21 >= M-P. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] THETA | |||
| *> \verbatim | |||
| *> THETA is REAL array, dimension (Q) | |||
| *> The entries of the bidiagonal blocks B11, B21 are defined by | |||
| *> THETA and PHI. See Further Details. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] PHI | |||
| *> \verbatim | |||
| *> PHI is REAL array, dimension (Q-1) | |||
| *> The entries of the bidiagonal blocks B11, B21 are defined by | |||
| *> THETA and PHI. See Further Details. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] TAUP1 | |||
| *> \verbatim | |||
| *> TAUP1 is COMPLEX array, dimension (P) | |||
| *> The scalar factors of the elementary reflectors that define | |||
| *> P1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] TAUP2 | |||
| *> \verbatim | |||
| *> TAUP2 is COMPLEX array, dimension (M-P) | |||
| *> The scalar factors of the elementary reflectors that define | |||
| *> P2. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] TAUQ1 | |||
| *> \verbatim | |||
| *> TAUQ1 is COMPLEX array, dimension (Q) | |||
| *> The scalar factors of the elementary reflectors that define | |||
| *> Q1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] WORK | |||
| *> \verbatim | |||
| *> WORK is COMPLEX array, dimension (LWORK) | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LWORK | |||
| *> \verbatim | |||
| *> LWORK is INTEGER | |||
| *> The dimension of the array WORK. LWORK >= M-Q. | |||
| *> | |||
| *> 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 July 2012 | |||
| * | |||
| *> \ingroup complexOTHERcomputational | |||
| * | |||
| *> \par Further Details: | |||
| * ===================== | |||
| *> \verbatim | |||
| *> | |||
| *> The upper-bidiagonal blocks B11, B21 are represented implicitly by | |||
| *> angles THETA(1), ..., THETA(Q) and PHI(1), ..., PHI(Q-1). Every entry | |||
| *> in each bidiagonal band is a product of a sine or cosine of a THETA | |||
| *> with a sine or cosine of a PHI. See [1] or CUNCSD for details. | |||
| *> | |||
| *> P1, P2, and Q1 are represented as products of elementary reflectors. | |||
| *> See CUNCSD2BY1 for details on generating P1, P2, and Q1 using CUNGQR | |||
| *> and CUNGLQ. | |||
| *> \endverbatim | |||
| * | |||
| *> \par References: | |||
| * ================ | |||
| *> | |||
| *> [1] Brian D. Sutton. Computing the complete CS decomposition. Numer. | |||
| *> Algorithms, 50(1):33-65, 2009. | |||
| *> | |||
| * ===================================================================== | |||
| 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 is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * July 2012 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| INTEGER INFO, LWORK, M, P, Q, LDX11, LDX21 | |||
| * .. | |||
| * .. Array Arguments .. | |||
| REAL PHI(*), THETA(*) | |||
| COMPLEX TAUP1(*), TAUP2(*), TAUQ1(*), WORK(*), | |||
| $ X11(LDX11,*), X21(LDX21,*) | |||
| * .. | |||
| * | |||
| * ==================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| COMPLEX ONE | |||
| PARAMETER ( ONE = (1.0E0,0.0E0) ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| REAL C, S | |||
| INTEGER CHILDINFO, I, ILARF, IORBDB5, LLARF, LORBDB5, | |||
| $ LWORKMIN, LWORKOPT | |||
| LOGICAL LQUERY | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL CLARF, CLARFGP, CUNBDB5, CSROT, XERBLA | |||
| EXTERNAL CLACGV | |||
| * .. | |||
| * .. External Functions .. | |||
| REAL SCNRM2 | |||
| EXTERNAL SCNRM2 | |||
| * .. | |||
| * .. Intrinsic Function .. | |||
| INTRINSIC ATAN2, COS, MAX, SIN, SQRT | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Test input arguments | |||
| * | |||
| INFO = 0 | |||
| LQUERY = LWORK .EQ. -1 | |||
| * | |||
| IF( M .LT. 0 ) THEN | |||
| INFO = -1 | |||
| ELSE IF( P .LT. Q .OR. M-P .LT. Q ) THEN | |||
| INFO = -2 | |||
| ELSE IF( Q .LT. 0 .OR. M-Q .LT. Q ) THEN | |||
| INFO = -3 | |||
| ELSE IF( LDX11 .LT. MAX( 1, P ) ) THEN | |||
| INFO = -5 | |||
| ELSE IF( LDX21 .LT. MAX( 1, M-P ) ) THEN | |||
| INFO = -7 | |||
| END IF | |||
| * | |||
| * Compute workspace | |||
| * | |||
| IF( INFO .EQ. 0 ) THEN | |||
| ILARF = 2 | |||
| LLARF = MAX( P-1, M-P-1, Q-1 ) | |||
| IORBDB5 = 2 | |||
| LORBDB5 = Q-2 | |||
| LWORKOPT = MAX( ILARF+LLARF-1, IORBDB5+LORBDB5-1 ) | |||
| LWORKMIN = LWORKOPT | |||
| WORK(1) = LWORKOPT | |||
| IF( LWORK .LT. LWORKMIN .AND. .NOT.LQUERY ) THEN | |||
| INFO = -14 | |||
| END IF | |||
| END IF | |||
| IF( INFO .NE. 0 ) THEN | |||
| CALL XERBLA( 'CUNBDB1', -INFO ) | |||
| RETURN | |||
| ELSE IF( LQUERY ) THEN | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Reduce columns 1, ..., Q of X11 and X21 | |||
| * | |||
| DO I = 1, Q | |||
| * | |||
| CALL CLARFGP( P-I+1, X11(I,I), X11(I+1,I), 1, TAUP1(I) ) | |||
| CALL CLARFGP( M-P-I+1, X21(I,I), X21(I+1,I), 1, TAUP2(I) ) | |||
| THETA(I) = ATAN2( REAL( X21(I,I) ), REAL( X11(I,I) ) ) | |||
| C = COS( THETA(I) ) | |||
| S = SIN( THETA(I) ) | |||
| X11(I,I) = ONE | |||
| X21(I,I) = ONE | |||
| CALL CLARF( 'L', P-I+1, Q-I, X11(I,I), 1, CONJG(TAUP1(I)), | |||
| $ X11(I,I+1), LDX11, WORK(ILARF) ) | |||
| CALL CLARF( 'L', M-P-I+1, Q-I, X21(I,I), 1, CONJG(TAUP2(I)), | |||
| $ X21(I,I+1), LDX21, WORK(ILARF) ) | |||
| * | |||
| IF( I .LT. Q ) THEN | |||
| CALL CSROT( Q-I, X11(I,I+1), LDX11, X21(I,I+1), LDX21, C, | |||
| $ S ) | |||
| CALL CLACGV( Q-I, X21(I,I+1), LDX21 ) | |||
| CALL CLARFGP( Q-I, X21(I,I+1), X21(I,I+2), LDX21, TAUQ1(I) ) | |||
| S = REAL( X21(I,I+1) ) | |||
| X21(I,I+1) = ONE | |||
| CALL CLARF( 'R', P-I, Q-I, X21(I,I+1), LDX21, TAUQ1(I), | |||
| $ X11(I+1,I+1), LDX11, WORK(ILARF) ) | |||
| 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 ) | |||
| 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, | |||
| $ X21(I+1,I+2), LDX21, WORK(IORBDB5), LORBDB5, | |||
| $ CHILDINFO ) | |||
| END IF | |||
| * | |||
| END DO | |||
| * | |||
| RETURN | |||
| * | |||
| * End of CUNBDB1 | |||
| * | |||
| END | |||
| @@ -0,0 +1,337 @@ | |||
| *> \brief \b CUNBDB2 | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download CUNBDB2 + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/cunbdb2.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/cunbdb2.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/cunbdb2.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE CUNBDB2( M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI, | |||
| * TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * INTEGER INFO, LWORK, M, P, Q, LDX11, LDX21 | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * REAL PHI(*), THETA(*) | |||
| * COMPLEX TAUP1(*), TAUP2(*), TAUQ1(*), WORK(*), | |||
| * $ X11(LDX11,*), X21(LDX21,*) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| *> ============= | |||
| *> | |||
| *>\verbatim | |||
| *> | |||
| *> CUNBDB2 simultaneously bidiagonalizes the blocks of a tall and skinny | |||
| *> matrix X with orthonomal columns: | |||
| *> | |||
| *> [ B11 ] | |||
| *> [ X11 ] [ P1 | ] [ 0 ] | |||
| *> [-----] = [---------] [-----] Q1**T . | |||
| *> [ X21 ] [ | P2 ] [ B21 ] | |||
| *> [ 0 ] | |||
| *> | |||
| *> X11 is P-by-Q, and X21 is (M-P)-by-Q. P must be no larger than M-P, | |||
| *> Q, or M-Q. Routines CUNBDB1, CUNBDB3, and CUNBDB4 handle cases in | |||
| *> which P is not the minimum dimension. | |||
| *> | |||
| *> The unitary matrices P1, P2, and Q1 are P-by-P, (M-P)-by-(M-P), | |||
| *> and (M-Q)-by-(M-Q), respectively. They are represented implicitly by | |||
| *> Householder vectors. | |||
| *> | |||
| *> B11 and B12 are P-by-P bidiagonal matrices represented implicitly by | |||
| *> angles THETA, PHI. | |||
| *> | |||
| *>\endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] M | |||
| *> \verbatim | |||
| *> M is INTEGER | |||
| *> The number of rows X11 plus the number of rows in X21. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] P | |||
| *> \verbatim | |||
| *> P is INTEGER | |||
| *> The number of rows in X11. 0 <= P <= min(M-P,Q,M-Q). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] Q | |||
| *> \verbatim | |||
| *> Q is INTEGER | |||
| *> The number of columns in X11 and X21. 0 <= Q <= M. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X11 | |||
| *> \verbatim | |||
| *> X11 is COMPLEX array, dimension (LDX11,Q) | |||
| *> On entry, the top block of the matrix X to be reduced. On | |||
| *> exit, the columns of tril(X11) specify reflectors for P1 and | |||
| *> the rows of triu(X11,1) specify reflectors for Q1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDX11 | |||
| *> \verbatim | |||
| *> LDX11 is INTEGER | |||
| *> The leading dimension of X11. LDX11 >= P. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X21 | |||
| *> \verbatim | |||
| *> X21 is COMPLEX array, dimension (LDX21,Q) | |||
| *> On entry, the bottom block of the matrix X to be reduced. On | |||
| *> exit, the columns of tril(X21) specify reflectors for P2. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDX21 | |||
| *> \verbatim | |||
| *> LDX21 is INTEGER | |||
| *> The leading dimension of X21. LDX21 >= M-P. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] THETA | |||
| *> \verbatim | |||
| *> THETA is REAL array, dimension (Q) | |||
| *> The entries of the bidiagonal blocks B11, B21 are defined by | |||
| *> THETA and PHI. See Further Details. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] PHI | |||
| *> \verbatim | |||
| *> PHI is REAL array, dimension (Q-1) | |||
| *> The entries of the bidiagonal blocks B11, B21 are defined by | |||
| *> THETA and PHI. See Further Details. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] TAUP1 | |||
| *> \verbatim | |||
| *> TAUP1 is COMPLEX array, dimension (P) | |||
| *> The scalar factors of the elementary reflectors that define | |||
| *> P1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] TAUP2 | |||
| *> \verbatim | |||
| *> TAUP2 is COMPLEX array, dimension (M-P) | |||
| *> The scalar factors of the elementary reflectors that define | |||
| *> P2. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] TAUQ1 | |||
| *> \verbatim | |||
| *> TAUQ1 is COMPLEX array, dimension (Q) | |||
| *> The scalar factors of the elementary reflectors that define | |||
| *> Q1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] WORK | |||
| *> \verbatim | |||
| *> WORK is COMPLEX array, dimension (LWORK) | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LWORK | |||
| *> \verbatim | |||
| *> LWORK is INTEGER | |||
| *> The dimension of the array WORK. LWORK >= M-Q. | |||
| *> | |||
| *> 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 July 2012 | |||
| * | |||
| *> \ingroup complexOTHERcomputational | |||
| * | |||
| *> \par Further Details: | |||
| * ===================== | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> The upper-bidiagonal blocks B11, B21 are represented implicitly by | |||
| *> angles THETA(1), ..., THETA(Q) and PHI(1), ..., PHI(Q-1). Every entry | |||
| *> in each bidiagonal band is a product of a sine or cosine of a THETA | |||
| *> with a sine or cosine of a PHI. See [1] or CUNCSD for details. | |||
| *> | |||
| *> P1, P2, and Q1 are represented as products of elementary reflectors. | |||
| *> See CUNCSD2BY1 for details on generating P1, P2, and Q1 using CUNGQR | |||
| *> and CUNGLQ. | |||
| *> \endverbatim | |||
| * | |||
| *> \par References: | |||
| * ================ | |||
| *> | |||
| *> [1] Brian D. Sutton. Computing the complete CS decomposition. Numer. | |||
| *> Algorithms, 50(1):33-65, 2009. | |||
| *> | |||
| * ===================================================================== | |||
| 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 is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * July 2012 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| INTEGER INFO, LWORK, M, P, Q, LDX11, LDX21 | |||
| * .. | |||
| * .. Array Arguments .. | |||
| REAL PHI(*), THETA(*) | |||
| COMPLEX TAUP1(*), TAUP2(*), TAUQ1(*), WORK(*), | |||
| $ X11(LDX11,*), X21(LDX21,*) | |||
| * .. | |||
| * | |||
| * ==================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| COMPLEX NEGONE, ONE | |||
| PARAMETER ( NEGONE = (-1.0E0,0.0E0), | |||
| $ ONE = (1.0E0,0.0E0) ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| REAL C, S | |||
| INTEGER CHILDINFO, I, ILARF, IORBDB5, LLARF, LORBDB5, | |||
| $ LWORKMIN, LWORKOPT | |||
| LOGICAL LQUERY | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL CLARF, CLARFGP, CUNBDB5, CSROT, CSCAL, XERBLA | |||
| * .. | |||
| * .. External Functions .. | |||
| REAL SCNRM2 | |||
| EXTERNAL SCNRM2 | |||
| * .. | |||
| * .. Intrinsic Function .. | |||
| INTRINSIC ATAN2, COS, MAX, SIN, SQRT | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Test input arguments | |||
| * | |||
| INFO = 0 | |||
| LQUERY = LWORK .EQ. -1 | |||
| * | |||
| IF( M .LT. 0 ) THEN | |||
| INFO = -1 | |||
| ELSE IF( P .LT. 0 .OR. P .GT. M-P ) THEN | |||
| INFO = -2 | |||
| ELSE IF( Q .LT. 0 .OR. Q .LT. P .OR. M-Q .LT. P ) THEN | |||
| INFO = -3 | |||
| ELSE IF( LDX11 .LT. MAX( 1, P ) ) THEN | |||
| INFO = -5 | |||
| ELSE IF( LDX21 .LT. MAX( 1, M-P ) ) THEN | |||
| INFO = -7 | |||
| END IF | |||
| * | |||
| * Compute workspace | |||
| * | |||
| IF( INFO .EQ. 0 ) THEN | |||
| ILARF = 2 | |||
| LLARF = MAX( P-1, M-P, Q-1 ) | |||
| IORBDB5 = 2 | |||
| LORBDB5 = Q-1 | |||
| LWORKOPT = MAX( ILARF+LLARF-1, IORBDB5+LORBDB5-1 ) | |||
| LWORKMIN = LWORKOPT | |||
| WORK(1) = LWORKOPT | |||
| IF( LWORK .LT. LWORKMIN .AND. .NOT.LQUERY ) THEN | |||
| INFO = -14 | |||
| END IF | |||
| END IF | |||
| IF( INFO .NE. 0 ) THEN | |||
| CALL XERBLA( 'CUNBDB2', -INFO ) | |||
| RETURN | |||
| ELSE IF( LQUERY ) THEN | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Reduce rows 1, ..., P of X11 and X21 | |||
| * | |||
| DO I = 1, P | |||
| * | |||
| IF( I .GT. 1 ) THEN | |||
| CALL CSROT( Q-I+1, X11(I,I), LDX11, X21(I-1,I), LDX21, C, | |||
| $ S ) | |||
| END IF | |||
| CALL CLACGV( Q-I+1, X11(I,I), LDX11 ) | |||
| CALL CLARFGP( Q-I+1, X11(I,I), X11(I,I+1), LDX11, TAUQ1(I) ) | |||
| C = REAL( X11(I,I) ) | |||
| X11(I,I) = ONE | |||
| CALL CLARF( 'R', P-I, Q-I+1, X11(I,I), LDX11, TAUQ1(I), | |||
| $ X11(I+1,I), LDX11, WORK(ILARF) ) | |||
| 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 ) | |||
| THETA(I) = ATAN2( S, C ) | |||
| * | |||
| CALL CUNBDB5( P-I, M-P-I+1, Q-I, X11(I+1,I), 1, X21(I,I), 1, | |||
| $ X11(I+1,I+1), LDX11, X21(I,I+1), LDX21, | |||
| $ WORK(IORBDB5), LORBDB5, CHILDINFO ) | |||
| CALL CSCAL( P-I, NEGONE, X11(I+1,I), 1 ) | |||
| CALL CLARFGP( M-P-I+1, X21(I,I), X21(I+1,I), 1, TAUP2(I) ) | |||
| IF( I .LT. P ) THEN | |||
| CALL CLARFGP( P-I, X11(I+1,I), X11(I+2,I), 1, TAUP1(I) ) | |||
| PHI(I) = ATAN2( REAL( X11(I+1,I) ), REAL( X21(I,I) ) ) | |||
| C = COS( PHI(I) ) | |||
| S = SIN( PHI(I) ) | |||
| X11(I+1,I) = ONE | |||
| CALL CLARF( 'L', P-I, Q-I, X11(I+1,I), 1, CONJG(TAUP1(I)), | |||
| $ X11(I+1,I+1), LDX11, WORK(ILARF) ) | |||
| END IF | |||
| X21(I,I) = ONE | |||
| CALL CLARF( 'L', M-P-I+1, Q-I, X21(I,I), 1, CONJG(TAUP2(I)), | |||
| $ X21(I,I+1), LDX21, WORK(ILARF) ) | |||
| * | |||
| END DO | |||
| * | |||
| * Reduce the bottom-right portion of X21 to the identity matrix | |||
| * | |||
| DO I = P + 1, Q | |||
| CALL CLARFGP( M-P-I+1, X21(I,I), X21(I+1,I), 1, TAUP2(I) ) | |||
| X21(I,I) = ONE | |||
| CALL CLARF( 'L', M-P-I+1, Q-I, X21(I,I), 1, CONJG(TAUP2(I)), | |||
| $ X21(I,I+1), LDX21, WORK(ILARF) ) | |||
| END DO | |||
| * | |||
| RETURN | |||
| * | |||
| * End of CUNBDB2 | |||
| * | |||
| END | |||
| @@ -0,0 +1,336 @@ | |||
| *> \brief \b CUNBDB3 | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download CUNBDB3 + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/cunbdb3.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/cunbdb3.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/cunbdb3.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE CUNBDB3( M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI, | |||
| * TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * INTEGER INFO, LWORK, M, P, Q, LDX11, LDX21 | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * REAL PHI(*), THETA(*) | |||
| * COMPLEX TAUP1(*), TAUP2(*), TAUQ1(*), WORK(*), | |||
| * $ X11(LDX11,*), X21(LDX21,*) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| *> ============= | |||
| *> | |||
| *>\verbatim | |||
| *> | |||
| *> CUNBDB3 simultaneously bidiagonalizes the blocks of a tall and skinny | |||
| *> matrix X with orthonomal columns: | |||
| *> | |||
| *> [ B11 ] | |||
| *> [ X11 ] [ P1 | ] [ 0 ] | |||
| *> [-----] = [---------] [-----] Q1**T . | |||
| *> [ X21 ] [ | P2 ] [ B21 ] | |||
| *> [ 0 ] | |||
| *> | |||
| *> X11 is P-by-Q, and X21 is (M-P)-by-Q. M-P must be no larger than P, | |||
| *> Q, or M-Q. Routines CUNBDB1, CUNBDB2, and CUNBDB4 handle cases in | |||
| *> which M-P is not the minimum dimension. | |||
| *> | |||
| *> The unitary matrices P1, P2, and Q1 are P-by-P, (M-P)-by-(M-P), | |||
| *> and (M-Q)-by-(M-Q), respectively. They are represented implicitly by | |||
| *> Householder vectors. | |||
| *> | |||
| *> B11 and B12 are (M-P)-by-(M-P) bidiagonal matrices represented | |||
| *> implicitly by angles THETA, PHI. | |||
| *> | |||
| *>\endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] M | |||
| *> \verbatim | |||
| *> M is INTEGER | |||
| *> The number of rows X11 plus the number of rows in X21. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] P | |||
| *> \verbatim | |||
| *> P is INTEGER | |||
| *> The number of rows in X11. 0 <= P <= M. M-P <= min(P,Q,M-Q). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] Q | |||
| *> \verbatim | |||
| *> Q is INTEGER | |||
| *> The number of columns in X11 and X21. 0 <= Q <= M. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X11 | |||
| *> \verbatim | |||
| *> X11 is COMPLEX array, dimension (LDX11,Q) | |||
| *> On entry, the top block of the matrix X to be reduced. On | |||
| *> exit, the columns of tril(X11) specify reflectors for P1 and | |||
| *> the rows of triu(X11,1) specify reflectors for Q1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDX11 | |||
| *> \verbatim | |||
| *> LDX11 is INTEGER | |||
| *> The leading dimension of X11. LDX11 >= P. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X21 | |||
| *> \verbatim | |||
| *> X21 is COMPLEX array, dimension (LDX21,Q) | |||
| *> On entry, the bottom block of the matrix X to be reduced. On | |||
| *> exit, the columns of tril(X21) specify reflectors for P2. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDX21 | |||
| *> \verbatim | |||
| *> LDX21 is INTEGER | |||
| *> The leading dimension of X21. LDX21 >= M-P. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] THETA | |||
| *> \verbatim | |||
| *> THETA is REAL array, dimension (Q) | |||
| *> The entries of the bidiagonal blocks B11, B21 are defined by | |||
| *> THETA and PHI. See Further Details. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] PHI | |||
| *> \verbatim | |||
| *> PHI is REAL array, dimension (Q-1) | |||
| *> The entries of the bidiagonal blocks B11, B21 are defined by | |||
| *> THETA and PHI. See Further Details. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] TAUP1 | |||
| *> \verbatim | |||
| *> TAUP1 is COMPLEX array, dimension (P) | |||
| *> The scalar factors of the elementary reflectors that define | |||
| *> P1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] TAUP2 | |||
| *> \verbatim | |||
| *> TAUP2 is COMPLEX array, dimension (M-P) | |||
| *> The scalar factors of the elementary reflectors that define | |||
| *> P2. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] TAUQ1 | |||
| *> \verbatim | |||
| *> TAUQ1 is COMPLEX array, dimension (Q) | |||
| *> The scalar factors of the elementary reflectors that define | |||
| *> Q1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] WORK | |||
| *> \verbatim | |||
| *> WORK is COMPLEX array, dimension (LWORK) | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LWORK | |||
| *> \verbatim | |||
| *> LWORK is INTEGER | |||
| *> The dimension of the array WORK. LWORK >= M-Q. | |||
| *> | |||
| *> 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 July 2012 | |||
| * | |||
| *> \ingroup complexOTHERcomputational | |||
| * | |||
| *> \par Further Details: | |||
| * ===================== | |||
| *> \verbatim | |||
| *> | |||
| *> The upper-bidiagonal blocks B11, B21 are represented implicitly by | |||
| *> angles THETA(1), ..., THETA(Q) and PHI(1), ..., PHI(Q-1). Every entry | |||
| *> in each bidiagonal band is a product of a sine or cosine of a THETA | |||
| *> with a sine or cosine of a PHI. See [1] or CUNCSD for details. | |||
| *> | |||
| *> P1, P2, and Q1 are represented as products of elementary reflectors. | |||
| *> See CUNCSD2BY1 for details on generating P1, P2, and Q1 using CUNGQR | |||
| *> and CUNGLQ. | |||
| *> \endverbatim | |||
| * | |||
| *> \par References: | |||
| * ================ | |||
| *> | |||
| *> [1] Brian D. Sutton. Computing the complete CS decomposition. Numer. | |||
| *> Algorithms, 50(1):33-65, 2009. | |||
| *> | |||
| * ===================================================================== | |||
| 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 is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * July 2012 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| INTEGER INFO, LWORK, M, P, Q, LDX11, LDX21 | |||
| * .. | |||
| * .. Array Arguments .. | |||
| REAL PHI(*), THETA(*) | |||
| COMPLEX TAUP1(*), TAUP2(*), TAUQ1(*), WORK(*), | |||
| $ X11(LDX11,*), X21(LDX21,*) | |||
| * .. | |||
| * | |||
| * ==================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| COMPLEX ONE | |||
| PARAMETER ( ONE = (1.0E0,0.0E0) ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| REAL C, S | |||
| INTEGER CHILDINFO, I, ILARF, IORBDB5, LLARF, LORBDB5, | |||
| $ LWORKMIN, LWORKOPT | |||
| LOGICAL LQUERY | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL CLARF, CLARFGP, CUNBDB5, CSROT, XERBLA | |||
| * .. | |||
| * .. External Functions .. | |||
| REAL SCNRM2 | |||
| EXTERNAL SCNRM2 | |||
| * .. | |||
| * .. Intrinsic Function .. | |||
| INTRINSIC ATAN2, COS, MAX, SIN, SQRT | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Test input arguments | |||
| * | |||
| INFO = 0 | |||
| LQUERY = LWORK .EQ. -1 | |||
| * | |||
| IF( M .LT. 0 ) THEN | |||
| INFO = -1 | |||
| ELSE IF( 2*P .LT. M .OR. P .GT. M ) THEN | |||
| INFO = -2 | |||
| ELSE IF( Q .LT. M-P .OR. M-Q .LT. M-P ) THEN | |||
| INFO = -3 | |||
| ELSE IF( LDX11 .LT. MAX( 1, P ) ) THEN | |||
| INFO = -5 | |||
| ELSE IF( LDX21 .LT. MAX( 1, M-P ) ) THEN | |||
| INFO = -7 | |||
| END IF | |||
| * | |||
| * Compute workspace | |||
| * | |||
| IF( INFO .EQ. 0 ) THEN | |||
| ILARF = 2 | |||
| LLARF = MAX( P, M-P-1, Q-1 ) | |||
| IORBDB5 = 2 | |||
| LORBDB5 = Q-1 | |||
| LWORKOPT = MAX( ILARF+LLARF-1, IORBDB5+LORBDB5-1 ) | |||
| LWORKMIN = LWORKOPT | |||
| WORK(1) = LWORKOPT | |||
| IF( LWORK .LT. LWORKMIN .AND. .NOT.LQUERY ) THEN | |||
| INFO = -14 | |||
| END IF | |||
| END IF | |||
| IF( INFO .NE. 0 ) THEN | |||
| CALL XERBLA( 'CUNBDB3', -INFO ) | |||
| RETURN | |||
| ELSE IF( LQUERY ) THEN | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Reduce rows 1, ..., M-P of X11 and X21 | |||
| * | |||
| DO I = 1, M-P | |||
| * | |||
| IF( I .GT. 1 ) THEN | |||
| CALL CSROT( Q-I+1, X11(I-1,I), LDX11, X21(I,I), LDX11, C, | |||
| $ S ) | |||
| END IF | |||
| * | |||
| CALL CLACGV( Q-I+1, X21(I,I), LDX21 ) | |||
| CALL CLARFGP( Q-I+1, X21(I,I), X21(I,I+1), LDX21, TAUQ1(I) ) | |||
| S = REAL( X21(I,I) ) | |||
| X21(I,I) = ONE | |||
| CALL CLARF( 'R', P-I+1, Q-I+1, X21(I,I), LDX21, TAUQ1(I), | |||
| $ X11(I,I), LDX11, WORK(ILARF) ) | |||
| 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 ) | |||
| THETA(I) = ATAN2( S, C ) | |||
| * | |||
| CALL CUNBDB5( P-I+1, M-P-I, Q-I, X11(I,I), 1, X21(I+1,I), 1, | |||
| $ X11(I,I+1), LDX11, X21(I+1,I+1), LDX21, | |||
| $ WORK(IORBDB5), LORBDB5, CHILDINFO ) | |||
| CALL CLARFGP( P-I+1, X11(I,I), X11(I+1,I), 1, TAUP1(I) ) | |||
| IF( I .LT. M-P ) THEN | |||
| CALL CLARFGP( M-P-I, X21(I+1,I), X21(I+2,I), 1, TAUP2(I) ) | |||
| PHI(I) = ATAN2( REAL( X21(I+1,I) ), REAL( X11(I,I) ) ) | |||
| C = COS( PHI(I) ) | |||
| S = SIN( PHI(I) ) | |||
| X21(I+1,I) = ONE | |||
| CALL CLARF( 'L', M-P-I, Q-I, X21(I+1,I), 1, CONJG(TAUP2(I)), | |||
| $ X21(I+1,I+1), LDX21, WORK(ILARF) ) | |||
| END IF | |||
| X11(I,I) = ONE | |||
| CALL CLARF( 'L', P-I+1, Q-I, X11(I,I), 1, CONJG(TAUP1(I)), | |||
| $ X11(I,I+1), LDX11, WORK(ILARF) ) | |||
| * | |||
| END DO | |||
| * | |||
| * Reduce the bottom-right portion of X11 to the identity matrix | |||
| * | |||
| DO I = M-P + 1, Q | |||
| CALL CLARFGP( P-I+1, X11(I,I), X11(I+1,I), 1, TAUP1(I) ) | |||
| X11(I,I) = ONE | |||
| CALL CLARF( 'L', P-I+1, Q-I, X11(I,I), 1, CONJG(TAUP1(I)), | |||
| $ X11(I,I+1), LDX11, WORK(ILARF) ) | |||
| END DO | |||
| * | |||
| RETURN | |||
| * | |||
| * End of CUNBDB3 | |||
| * | |||
| END | |||
| @@ -0,0 +1,385 @@ | |||
| *> \brief \b CUNBDB4 | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download CUNBDB4 + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/cunbdb4.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/cunbdb4.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/cunbdb4.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE CUNBDB4( M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI, | |||
| * TAUP1, TAUP2, TAUQ1, PHANTOM, WORK, LWORK, | |||
| * INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * INTEGER INFO, LWORK, M, P, Q, LDX11, LDX21 | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * REAL PHI(*), THETA(*) | |||
| * COMPLEX PHANTOM(*), TAUP1(*), TAUP2(*), TAUQ1(*), | |||
| * $ WORK(*), X11(LDX11,*), X21(LDX21,*) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| *> ============= | |||
| *> | |||
| *>\verbatim | |||
| *> | |||
| *> CUNBDB4 simultaneously bidiagonalizes the blocks of a tall and skinny | |||
| *> matrix X with orthonomal columns: | |||
| *> | |||
| *> [ B11 ] | |||
| *> [ X11 ] [ P1 | ] [ 0 ] | |||
| *> [-----] = [---------] [-----] Q1**T . | |||
| *> [ X21 ] [ | P2 ] [ B21 ] | |||
| *> [ 0 ] | |||
| *> | |||
| *> X11 is P-by-Q, and X21 is (M-P)-by-Q. M-Q must be no larger than P, | |||
| *> M-P, or Q. Routines CUNBDB1, CUNBDB2, and CUNBDB3 handle cases in | |||
| *> which M-Q is not the minimum dimension. | |||
| *> | |||
| *> The unitary matrices P1, P2, and Q1 are P-by-P, (M-P)-by-(M-P), | |||
| *> and (M-Q)-by-(M-Q), respectively. They are represented implicitly by | |||
| *> Householder vectors. | |||
| *> | |||
| *> B11 and B12 are (M-Q)-by-(M-Q) bidiagonal matrices represented | |||
| *> implicitly by angles THETA, PHI. | |||
| *> | |||
| *>\endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] M | |||
| *> \verbatim | |||
| *> M is INTEGER | |||
| *> The number of rows X11 plus the number of rows in X21. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] P | |||
| *> \verbatim | |||
| *> P is INTEGER | |||
| *> The number of rows in X11. 0 <= P <= M. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] Q | |||
| *> \verbatim | |||
| *> Q is INTEGER | |||
| *> The number of columns in X11 and X21. 0 <= Q <= M and | |||
| *> M-Q <= min(P,M-P,Q). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X11 | |||
| *> \verbatim | |||
| *> X11 is COMPLEX array, dimension (LDX11,Q) | |||
| *> On entry, the top block of the matrix X to be reduced. On | |||
| *> exit, the columns of tril(X11) specify reflectors for P1 and | |||
| *> the rows of triu(X11,1) specify reflectors for Q1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDX11 | |||
| *> \verbatim | |||
| *> LDX11 is INTEGER | |||
| *> The leading dimension of X11. LDX11 >= P. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X21 | |||
| *> \verbatim | |||
| *> X21 is COMPLEX array, dimension (LDX21,Q) | |||
| *> On entry, the bottom block of the matrix X to be reduced. On | |||
| *> exit, the columns of tril(X21) specify reflectors for P2. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDX21 | |||
| *> \verbatim | |||
| *> LDX21 is INTEGER | |||
| *> The leading dimension of X21. LDX21 >= M-P. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] THETA | |||
| *> \verbatim | |||
| *> THETA is REAL array, dimension (Q) | |||
| *> The entries of the bidiagonal blocks B11, B21 are defined by | |||
| *> THETA and PHI. See Further Details. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] PHI | |||
| *> \verbatim | |||
| *> PHI is REAL array, dimension (Q-1) | |||
| *> The entries of the bidiagonal blocks B11, B21 are defined by | |||
| *> THETA and PHI. See Further Details. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] TAUP1 | |||
| *> \verbatim | |||
| *> TAUP1 is COMPLEX array, dimension (P) | |||
| *> The scalar factors of the elementary reflectors that define | |||
| *> P1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] TAUP2 | |||
| *> \verbatim | |||
| *> TAUP2 is COMPLEX array, dimension (M-P) | |||
| *> The scalar factors of the elementary reflectors that define | |||
| *> P2. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] TAUQ1 | |||
| *> \verbatim | |||
| *> TAUQ1 is COMPLEX array, dimension (Q) | |||
| *> The scalar factors of the elementary reflectors that define | |||
| *> Q1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] PHANTOM | |||
| *> \verbatim | |||
| *> PHANTOM is COMPLEX array, dimension (M) | |||
| *> The routine computes an M-by-1 column vector Y that is | |||
| *> orthogonal to the columns of [ X11; X21 ]. PHANTOM(1:P) and | |||
| *> PHANTOM(P+1:M) contain Householder vectors for Y(1:P) and | |||
| *> Y(P+1:M), respectively. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] WORK | |||
| *> \verbatim | |||
| *> WORK is COMPLEX array, dimension (LWORK) | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LWORK | |||
| *> \verbatim | |||
| *> LWORK is INTEGER | |||
| *> The dimension of the array WORK. LWORK >= M-Q. | |||
| *> | |||
| *> 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 July 2012 | |||
| * | |||
| *> \ingroup complexOTHERcomputational | |||
| * | |||
| *> \par Further Details: | |||
| * ===================== | |||
| *> \verbatim | |||
| *> | |||
| *> The upper-bidiagonal blocks B11, B21 are represented implicitly by | |||
| *> angles THETA(1), ..., THETA(Q) and PHI(1), ..., PHI(Q-1). Every entry | |||
| *> in each bidiagonal band is a product of a sine or cosine of a THETA | |||
| *> with a sine or cosine of a PHI. See [1] or CUNCSD for details. | |||
| *> | |||
| *> P1, P2, and Q1 are represented as products of elementary reflectors. | |||
| *> See CUNCSD2BY1 for details on generating P1, P2, and Q1 using CUNGQR | |||
| *> and CUNGLQ. | |||
| *> \endverbatim | |||
| * | |||
| *> \par References: | |||
| * ================ | |||
| *> | |||
| *> [1] Brian D. Sutton. Computing the complete CS decomposition. Numer. | |||
| *> Algorithms, 50(1):33-65, 2009. | |||
| *> | |||
| * ===================================================================== | |||
| SUBROUTINE CUNBDB4( M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI, | |||
| $ TAUP1, TAUP2, TAUQ1, PHANTOM, WORK, LWORK, | |||
| $ INFO ) | |||
| * | |||
| * -- 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..-- | |||
| * July 2012 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| INTEGER INFO, LWORK, M, P, Q, LDX11, LDX21 | |||
| * .. | |||
| * .. Array Arguments .. | |||
| REAL PHI(*), THETA(*) | |||
| COMPLEX PHANTOM(*), TAUP1(*), TAUP2(*), TAUQ1(*), | |||
| $ WORK(*), X11(LDX11,*), X21(LDX21,*) | |||
| * .. | |||
| * | |||
| * ==================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| COMPLEX NEGONE, ONE, ZERO | |||
| PARAMETER ( NEGONE = (-1.0E0,0.0E0), ONE = (1.0E0,0.0E0), | |||
| $ ZERO = (0.0E0,0.0E0) ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| REAL C, S | |||
| INTEGER CHILDINFO, I, ILARF, IORBDB5, J, LLARF, | |||
| $ LORBDB5, LWORKMIN, LWORKOPT | |||
| LOGICAL LQUERY | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL CLARF, CLARFGP, CUNBDB5, CSROT, CSCAL, XERBLA | |||
| * .. | |||
| * .. External Functions .. | |||
| REAL SCNRM2 | |||
| EXTERNAL SCNRM2 | |||
| * .. | |||
| * .. Intrinsic Function .. | |||
| INTRINSIC ATAN2, COS, MAX, SIN, SQRT | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Test input arguments | |||
| * | |||
| INFO = 0 | |||
| LQUERY = LWORK .EQ. -1 | |||
| * | |||
| IF( M .LT. 0 ) THEN | |||
| INFO = -1 | |||
| ELSE IF( P .LT. M-Q .OR. M-P .LT. M-Q ) THEN | |||
| INFO = -2 | |||
| ELSE IF( Q .LT. M-Q .OR. Q .GT. M ) THEN | |||
| INFO = -3 | |||
| ELSE IF( LDX11 .LT. MAX( 1, P ) ) THEN | |||
| INFO = -5 | |||
| ELSE IF( LDX21 .LT. MAX( 1, M-P ) ) THEN | |||
| INFO = -7 | |||
| END IF | |||
| * | |||
| * Compute workspace | |||
| * | |||
| IF( INFO .EQ. 0 ) THEN | |||
| ILARF = 2 | |||
| LLARF = MAX( Q-1, P-1, M-P-1 ) | |||
| IORBDB5 = 2 | |||
| LORBDB5 = Q | |||
| LWORKOPT = ILARF + LLARF - 1 | |||
| LWORKOPT = MAX( LWORKOPT, IORBDB5 + LORBDB5 - 1 ) | |||
| LWORKMIN = LWORKOPT | |||
| WORK(1) = LWORKOPT | |||
| IF( LWORK .LT. LWORKMIN .AND. .NOT.LQUERY ) THEN | |||
| INFO = -14 | |||
| END IF | |||
| END IF | |||
| IF( INFO .NE. 0 ) THEN | |||
| CALL XERBLA( 'CUNBDB4', -INFO ) | |||
| RETURN | |||
| ELSE IF( LQUERY ) THEN | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Reduce columns 1, ..., M-Q of X11 and X21 | |||
| * | |||
| DO I = 1, M-Q | |||
| * | |||
| IF( I .EQ. 1 ) THEN | |||
| DO J = 1, M | |||
| PHANTOM(J) = ZERO | |||
| END DO | |||
| CALL CUNBDB5( P, M-P, Q, PHANTOM(1), 1, PHANTOM(P+1), 1, | |||
| $ X11, LDX11, X21, LDX21, WORK(IORBDB5), | |||
| $ LORBDB5, CHILDINFO ) | |||
| CALL CSCAL( P, NEGONE, PHANTOM(1), 1 ) | |||
| CALL CLARFGP( P, PHANTOM(1), PHANTOM(2), 1, TAUP1(1) ) | |||
| CALL CLARFGP( M-P, PHANTOM(P+1), PHANTOM(P+2), 1, TAUP2(1) ) | |||
| THETA(I) = ATAN2( REAL( PHANTOM(1) ), REAL( PHANTOM(P+1) ) ) | |||
| C = COS( THETA(I) ) | |||
| S = SIN( THETA(I) ) | |||
| PHANTOM(1) = ONE | |||
| PHANTOM(P+1) = ONE | |||
| CALL CLARF( 'L', P, Q, PHANTOM(1), 1, CONJG(TAUP1(1)), X11, | |||
| $ LDX11, WORK(ILARF) ) | |||
| CALL CLARF( 'L', M-P, Q, PHANTOM(P+1), 1, CONJG(TAUP2(1)), | |||
| $ X21, LDX21, WORK(ILARF) ) | |||
| ELSE | |||
| CALL CUNBDB5( P-I+1, M-P-I+1, Q-I+1, X11(I,I-1), 1, | |||
| $ X21(I,I-1), 1, X11(I,I), LDX11, X21(I,I), | |||
| $ LDX21, WORK(IORBDB5), LORBDB5, CHILDINFO ) | |||
| CALL CSCAL( P-I+1, NEGONE, X11(I,I-1), 1 ) | |||
| CALL CLARFGP( P-I+1, X11(I,I-1), X11(I+1,I-1), 1, TAUP1(I) ) | |||
| CALL CLARFGP( M-P-I+1, X21(I,I-1), X21(I+1,I-1), 1, | |||
| $ TAUP2(I) ) | |||
| THETA(I) = ATAN2( REAL( X11(I,I-1) ), REAL( X21(I,I-1) ) ) | |||
| C = COS( THETA(I) ) | |||
| S = SIN( THETA(I) ) | |||
| X11(I,I-1) = ONE | |||
| X21(I,I-1) = ONE | |||
| CALL CLARF( 'L', P-I+1, Q-I+1, X11(I,I-1), 1, | |||
| $ CONJG(TAUP1(I)), X11(I,I), LDX11, WORK(ILARF) ) | |||
| CALL CLARF( 'L', M-P-I+1, Q-I+1, X21(I,I-1), 1, | |||
| $ CONJG(TAUP2(I)), X21(I,I), LDX21, WORK(ILARF) ) | |||
| END IF | |||
| * | |||
| CALL CSROT( Q-I+1, X11(I,I), LDX11, X21(I,I), LDX21, S, -C ) | |||
| CALL CLACGV( Q-I+1, X21(I,I), LDX21 ) | |||
| CALL CLARFGP( Q-I+1, X21(I,I), X21(I,I+1), LDX21, TAUQ1(I) ) | |||
| C = REAL( X21(I,I) ) | |||
| X21(I,I) = ONE | |||
| CALL CLARF( 'R', P-I, Q-I+1, X21(I,I), LDX21, TAUQ1(I), | |||
| $ X11(I+1,I), LDX11, WORK(ILARF) ) | |||
| 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 ) | |||
| 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 ) | |||
| PHI(I) = ATAN2( S, C ) | |||
| END IF | |||
| * | |||
| END DO | |||
| * | |||
| * Reduce the bottom-right portion of X11 to [ I 0 ] | |||
| * | |||
| DO I = M - Q + 1, P | |||
| CALL CLACGV( Q-I+1, X11(I,I), LDX11 ) | |||
| CALL CLARFGP( Q-I+1, X11(I,I), X11(I,I+1), LDX11, TAUQ1(I) ) | |||
| X11(I,I) = ONE | |||
| CALL CLARF( 'R', P-I, Q-I+1, X11(I,I), LDX11, TAUQ1(I), | |||
| $ X11(I+1,I), LDX11, WORK(ILARF) ) | |||
| CALL CLARF( 'R', Q-P, Q-I+1, X11(I,I), LDX11, TAUQ1(I), | |||
| $ X21(M-Q+1,I), LDX21, WORK(ILARF) ) | |||
| CALL CLACGV( Q-I+1, X11(I,I), LDX11 ) | |||
| END DO | |||
| * | |||
| * Reduce the bottom-right portion of X21 to [ 0 I ] | |||
| * | |||
| DO I = P + 1, Q | |||
| CALL CLACGV( Q-I+1, X21(M-Q+I-P,I), LDX21 ) | |||
| CALL CLARFGP( Q-I+1, X21(M-Q+I-P,I), X21(M-Q+I-P,I+1), LDX21, | |||
| $ TAUQ1(I) ) | |||
| X21(M-Q+I-P,I) = ONE | |||
| CALL CLARF( 'R', Q-I, Q-I+1, X21(M-Q+I-P,I), LDX21, TAUQ1(I), | |||
| $ X21(M-Q+I-P+1,I), LDX21, WORK(ILARF) ) | |||
| CALL CLACGV( Q-I+1, X21(M-Q+I-P,I), LDX21 ) | |||
| END DO | |||
| * | |||
| RETURN | |||
| * | |||
| * End of CUNBDB4 | |||
| * | |||
| END | |||
| @@ -0,0 +1,274 @@ | |||
| *> \brief \b CUNBDB5 | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download CUNBDB5 + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/cunbdb5.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/cunbdb5.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/cunbdb5.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE CUNBDB5( M1, M2, N, X1, INCX1, X2, INCX2, Q1, LDQ1, Q2, | |||
| * LDQ2, WORK, LWORK, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * INTEGER INCX1, INCX2, INFO, LDQ1, LDQ2, LWORK, M1, M2, | |||
| * $ N | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * COMPLEX Q1(LDQ1,*), Q2(LDQ2,*), WORK(*), X1(*), X2(*) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| *> ============= | |||
| *> | |||
| *>\verbatim | |||
| *> | |||
| *> CUNBDB5 orthogonalizes the column vector | |||
| *> X = [ X1 ] | |||
| *> [ X2 ] | |||
| *> with respect to the columns of | |||
| *> Q = [ Q1 ] . | |||
| *> [ Q2 ] | |||
| *> The columns of Q must be orthonormal. | |||
| *> | |||
| *> If the projection is zero according to Kahan's "twice is enough" | |||
| *> criterion, then some other vector from the orthogonal complement | |||
| *> is returned. This vector is chosen in an arbitrary but deterministic | |||
| *> way. | |||
| *> | |||
| *>\endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] M1 | |||
| *> \verbatim | |||
| *> M1 is INTEGER | |||
| *> The dimension of X1 and the number of rows in Q1. 0 <= M1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] M2 | |||
| *> \verbatim | |||
| *> M2 is INTEGER | |||
| *> The dimension of X2 and the number of rows in Q2. 0 <= M2. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] N | |||
| *> \verbatim | |||
| *> N is INTEGER | |||
| *> The number of columns in Q1 and Q2. 0 <= N. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X1 | |||
| *> \verbatim | |||
| *> X1 is COMPLEX array, dimension (M1) | |||
| *> On entry, the top part of the vector to be orthogonalized. | |||
| *> On exit, the top part of the projected vector. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] INCX1 | |||
| *> \verbatim | |||
| *> INCX1 is INTEGER | |||
| *> Increment for entries of X1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X2 | |||
| *> \verbatim | |||
| *> X2 is COMPLEX array, dimension (M2) | |||
| *> On entry, the bottom part of the vector to be | |||
| *> orthogonalized. On exit, the bottom part of the projected | |||
| *> vector. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] INCX2 | |||
| *> \verbatim | |||
| *> INCX2 is INTEGER | |||
| *> Increment for entries of X2. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] Q1 | |||
| *> \verbatim | |||
| *> Q1 is COMPLEX array, dimension (LDQ1, N) | |||
| *> The top part of the orthonormal basis matrix. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDQ1 | |||
| *> \verbatim | |||
| *> LDQ1 is INTEGER | |||
| *> The leading dimension of Q1. LDQ1 >= M1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] Q2 | |||
| *> \verbatim | |||
| *> Q2 is COMPLEX array, dimension (LDQ2, N) | |||
| *> The bottom part of the orthonormal basis matrix. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDQ2 | |||
| *> \verbatim | |||
| *> LDQ2 is INTEGER | |||
| *> The leading dimension of Q2. LDQ2 >= M2. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] WORK | |||
| *> \verbatim | |||
| *> WORK is COMPLEX array, dimension (LWORK) | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LWORK | |||
| *> \verbatim | |||
| *> LWORK is INTEGER | |||
| *> The dimension of the array WORK. LWORK >= N. | |||
| *> \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 July 2012 | |||
| * | |||
| *> \ingroup complexOTHERcomputational | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE CUNBDB5( M1, M2, N, X1, INCX1, X2, INCX2, Q1, LDQ1, Q2, | |||
| $ LDQ2, WORK, LWORK, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * July 2012 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| INTEGER INCX1, INCX2, INFO, LDQ1, LDQ2, LWORK, M1, M2, | |||
| $ N | |||
| * .. | |||
| * .. Array Arguments .. | |||
| COMPLEX Q1(LDQ1,*), Q2(LDQ2,*), WORK(*), X1(*), X2(*) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| COMPLEX ONE, ZERO | |||
| PARAMETER ( ONE = (1.0E0,0.0E0), ZERO = (0.0E0,0.0E0) ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| INTEGER CHILDINFO, I, J | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL CUNBDB6, XERBLA | |||
| * .. | |||
| * .. External Functions .. | |||
| REAL SCNRM2 | |||
| EXTERNAL SCNRM2 | |||
| * .. | |||
| * .. Intrinsic Function .. | |||
| INTRINSIC MAX | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Test input arguments | |||
| * | |||
| INFO = 0 | |||
| IF( M1 .LT. 0 ) THEN | |||
| INFO = -1 | |||
| ELSE IF( M2 .LT. 0 ) THEN | |||
| INFO = -2 | |||
| ELSE IF( N .LT. 0 ) THEN | |||
| INFO = -3 | |||
| ELSE IF( INCX1 .LT. 1 ) THEN | |||
| INFO = -5 | |||
| ELSE IF( INCX2 .LT. 1 ) THEN | |||
| INFO = -7 | |||
| ELSE IF( LDQ1 .LT. MAX( 1, M1 ) ) THEN | |||
| INFO = -9 | |||
| ELSE IF( LDQ2 .LT. MAX( 1, M2 ) ) THEN | |||
| INFO = -11 | |||
| ELSE IF( LWORK .LT. N ) THEN | |||
| INFO = -13 | |||
| END IF | |||
| * | |||
| IF( INFO .NE. 0 ) THEN | |||
| CALL XERBLA( 'CUNBDB5', -INFO ) | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Project X onto the orthogonal complement of Q | |||
| * | |||
| CALL CUNBDB6( M1, M2, N, X1, INCX1, X2, INCX2, Q1, LDQ1, Q2, LDQ2, | |||
| $ WORK, LWORK, CHILDINFO ) | |||
| * | |||
| * If the projection is nonzero, then return | |||
| * | |||
| IF( SCNRM2(M1,X1,INCX1) .NE. ZERO | |||
| $ .OR. SCNRM2(M2,X2,INCX2) .NE. ZERO ) THEN | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Project each standard basis vector e_1,...,e_M1 in turn, stopping | |||
| * when a nonzero projection is found | |||
| * | |||
| DO I = 1, M1 | |||
| DO J = 1, M1 | |||
| X1(J) = ZERO | |||
| END DO | |||
| X1(I) = ONE | |||
| DO J = 1, M2 | |||
| X2(J) = ZERO | |||
| END DO | |||
| CALL CUNBDB6( M1, M2, N, X1, INCX1, X2, INCX2, Q1, LDQ1, Q2, | |||
| $ LDQ2, WORK, LWORK, CHILDINFO ) | |||
| IF( SCNRM2(M1,X1,INCX1) .NE. ZERO | |||
| $ .OR. SCNRM2(M2,X2,INCX2) .NE. ZERO ) THEN | |||
| RETURN | |||
| END IF | |||
| END DO | |||
| * | |||
| * Project each standard basis vector e_(M1+1),...,e_(M1+M2) in turn, | |||
| * stopping when a nonzero projection is found | |||
| * | |||
| DO I = 1, M2 | |||
| DO J = 1, M1 | |||
| X1(J) = ZERO | |||
| END DO | |||
| DO J = 1, M2 | |||
| X2(J) = ZERO | |||
| END DO | |||
| X2(I) = ONE | |||
| CALL CUNBDB6( M1, M2, N, X1, INCX1, X2, INCX2, Q1, LDQ1, Q2, | |||
| $ LDQ2, WORK, LWORK, CHILDINFO ) | |||
| IF( SCNRM2(M1,X1,INCX1) .NE. ZERO | |||
| $ .OR. SCNRM2(M2,X2,INCX2) .NE. ZERO ) THEN | |||
| RETURN | |||
| END IF | |||
| END DO | |||
| * | |||
| RETURN | |||
| * | |||
| * End of CUNBDB5 | |||
| * | |||
| END | |||
| @@ -0,0 +1,313 @@ | |||
| *> \brief \b CUNBDB6 | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download CUNBDB6 + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/cunbdb6.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/cunbdb6.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/cunbdb6.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE CUNBDB6( M1, M2, N, X1, INCX1, X2, INCX2, Q1, LDQ1, Q2, | |||
| * LDQ2, WORK, LWORK, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * INTEGER INCX1, INCX2, INFO, LDQ1, LDQ2, LWORK, M1, M2, | |||
| * $ N | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * COMPLEX Q1(LDQ1,*), Q2(LDQ2,*), WORK(*), X1(*), X2(*) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| *> ============= | |||
| *> | |||
| *>\verbatim | |||
| *> | |||
| *> CUNBDB6 orthogonalizes the column vector | |||
| *> X = [ X1 ] | |||
| *> [ X2 ] | |||
| *> with respect to the columns of | |||
| *> Q = [ Q1 ] . | |||
| *> [ Q2 ] | |||
| *> The columns of Q must be orthonormal. | |||
| *> | |||
| *> If the projection is zero according to Kahan's "twice is enough" | |||
| *> criterion, then the zero vector is returned. | |||
| *> | |||
| *>\endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] M1 | |||
| *> \verbatim | |||
| *> M1 is INTEGER | |||
| *> The dimension of X1 and the number of rows in Q1. 0 <= M1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] M2 | |||
| *> \verbatim | |||
| *> M2 is INTEGER | |||
| *> The dimension of X2 and the number of rows in Q2. 0 <= M2. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] N | |||
| *> \verbatim | |||
| *> N is INTEGER | |||
| *> The number of columns in Q1 and Q2. 0 <= N. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X1 | |||
| *> \verbatim | |||
| *> X1 is COMPLEX array, dimension (M1) | |||
| *> On entry, the top part of the vector to be orthogonalized. | |||
| *> On exit, the top part of the projected vector. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] INCX1 | |||
| *> \verbatim | |||
| *> INCX1 is INTEGER | |||
| *> Increment for entries of X1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X2 | |||
| *> \verbatim | |||
| *> X2 is COMPLEX array, dimension (M2) | |||
| *> On entry, the bottom part of the vector to be | |||
| *> orthogonalized. On exit, the bottom part of the projected | |||
| *> vector. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] INCX2 | |||
| *> \verbatim | |||
| *> INCX2 is INTEGER | |||
| *> Increment for entries of X2. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] Q1 | |||
| *> \verbatim | |||
| *> Q1 is COMPLEX array, dimension (LDQ1, N) | |||
| *> The top part of the orthonormal basis matrix. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDQ1 | |||
| *> \verbatim | |||
| *> LDQ1 is INTEGER | |||
| *> The leading dimension of Q1. LDQ1 >= M1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] Q2 | |||
| *> \verbatim | |||
| *> Q2 is COMPLEX array, dimension (LDQ2, N) | |||
| *> The bottom part of the orthonormal basis matrix. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDQ2 | |||
| *> \verbatim | |||
| *> LDQ2 is INTEGER | |||
| *> The leading dimension of Q2. LDQ2 >= M2. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] WORK | |||
| *> \verbatim | |||
| *> WORK is COMPLEX array, dimension (LWORK) | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LWORK | |||
| *> \verbatim | |||
| *> LWORK is INTEGER | |||
| *> The dimension of the array WORK. LWORK >= N. | |||
| *> \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 July 2012 | |||
| * | |||
| *> \ingroup complexOTHERcomputational | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE CUNBDB6( M1, M2, N, X1, INCX1, X2, INCX2, Q1, LDQ1, Q2, | |||
| $ LDQ2, WORK, LWORK, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * July 2012 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| INTEGER INCX1, INCX2, INFO, LDQ1, LDQ2, LWORK, M1, M2, | |||
| $ N | |||
| * .. | |||
| * .. Array Arguments .. | |||
| COMPLEX Q1(LDQ1,*), Q2(LDQ2,*), WORK(*), X1(*), X2(*) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| REAL ALPHASQ, REALONE, REALZERO | |||
| PARAMETER ( ALPHASQ = 0.01E0, REALONE = 1.0E0, | |||
| $ REALZERO = 0.0E0 ) | |||
| COMPLEX NEGONE, ONE, ZERO | |||
| PARAMETER ( NEGONE = (-1.0E0,0.0E0), ONE = (1.0E0,0.0E0), | |||
| $ ZERO = (0.0E0,0.0E0) ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| INTEGER I | |||
| REAL NORMSQ1, NORMSQ2, SCL1, SCL2, SSQ1, SSQ2 | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL CGEMV, CLASSQ, XERBLA | |||
| * .. | |||
| * .. Intrinsic Function .. | |||
| INTRINSIC MAX | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Test input arguments | |||
| * | |||
| INFO = 0 | |||
| IF( M1 .LT. 0 ) THEN | |||
| INFO = -1 | |||
| ELSE IF( M2 .LT. 0 ) THEN | |||
| INFO = -2 | |||
| ELSE IF( N .LT. 0 ) THEN | |||
| INFO = -3 | |||
| ELSE IF( INCX1 .LT. 1 ) THEN | |||
| INFO = -5 | |||
| ELSE IF( INCX2 .LT. 1 ) THEN | |||
| INFO = -7 | |||
| ELSE IF( LDQ1 .LT. MAX( 1, M1 ) ) THEN | |||
| INFO = -9 | |||
| ELSE IF( LDQ2 .LT. MAX( 1, M2 ) ) THEN | |||
| INFO = -11 | |||
| ELSE IF( LWORK .LT. N ) THEN | |||
| INFO = -13 | |||
| END IF | |||
| * | |||
| IF( INFO .NE. 0 ) THEN | |||
| CALL XERBLA( 'CUNBDB6', -INFO ) | |||
| RETURN | |||
| END IF | |||
| * | |||
| * First, project X onto the orthogonal complement of Q's column | |||
| * space | |||
| * | |||
| SCL1 = REALZERO | |||
| SSQ1 = REALONE | |||
| CALL CLASSQ( M1, X1, INCX1, SCL1, SSQ1 ) | |||
| SCL2 = REALZERO | |||
| SSQ2 = REALONE | |||
| CALL CLASSQ( M2, X2, INCX2, SCL2, SSQ2 ) | |||
| NORMSQ1 = SCL1**2*SSQ1 + SCL2**2*SSQ2 | |||
| * | |||
| IF( M1 .EQ. 0 ) THEN | |||
| DO I = 1, N | |||
| WORK(I) = ZERO | |||
| END DO | |||
| ELSE | |||
| CALL CGEMV( 'C', M1, N, ONE, Q1, LDQ1, X1, INCX1, ZERO, WORK, | |||
| $ 1 ) | |||
| END IF | |||
| * | |||
| CALL CGEMV( 'C', M2, N, ONE, Q2, LDQ2, X2, INCX2, ONE, WORK, 1 ) | |||
| * | |||
| CALL CGEMV( 'N', M1, N, NEGONE, Q1, LDQ1, WORK, 1, ONE, X1, | |||
| $ INCX1 ) | |||
| CALL CGEMV( 'N', M2, N, NEGONE, Q2, LDQ2, WORK, 1, ONE, X2, | |||
| $ INCX2 ) | |||
| * | |||
| SCL1 = REALZERO | |||
| SSQ1 = REALONE | |||
| CALL CLASSQ( M1, X1, INCX1, SCL1, SSQ1 ) | |||
| SCL2 = REALZERO | |||
| SSQ2 = REALONE | |||
| CALL CLASSQ( M2, X2, INCX2, SCL2, SSQ2 ) | |||
| NORMSQ2 = SCL1**2*SSQ1 + SCL2**2*SSQ2 | |||
| * | |||
| * If projection is sufficiently large in norm, then stop. | |||
| * If projection is zero, then stop. | |||
| * Otherwise, project again. | |||
| * | |||
| IF( NORMSQ2 .GE. ALPHASQ*NORMSQ1 ) THEN | |||
| RETURN | |||
| END IF | |||
| * | |||
| IF( NORMSQ2 .EQ. ZERO ) THEN | |||
| RETURN | |||
| END IF | |||
| * | |||
| NORMSQ1 = NORMSQ2 | |||
| * | |||
| DO I = 1, N | |||
| WORK(I) = ZERO | |||
| END DO | |||
| * | |||
| IF( M1 .EQ. 0 ) THEN | |||
| DO I = 1, N | |||
| WORK(I) = ZERO | |||
| END DO | |||
| ELSE | |||
| CALL CGEMV( 'C', M1, N, ONE, Q1, LDQ1, X1, INCX1, ZERO, WORK, | |||
| $ 1 ) | |||
| END IF | |||
| * | |||
| CALL CGEMV( 'C', M2, N, ONE, Q2, LDQ2, X2, INCX2, ONE, WORK, 1 ) | |||
| * | |||
| CALL CGEMV( 'N', M1, N, NEGONE, Q1, LDQ1, WORK, 1, ONE, X1, | |||
| $ INCX1 ) | |||
| CALL CGEMV( 'N', M2, N, NEGONE, Q2, LDQ2, WORK, 1, ONE, X2, | |||
| $ INCX2 ) | |||
| * | |||
| SCL1 = REALZERO | |||
| SSQ1 = REALONE | |||
| CALL CLASSQ( M1, X1, INCX1, SCL1, SSQ1 ) | |||
| SCL2 = REALZERO | |||
| SSQ2 = REALONE | |||
| CALL CLASSQ( M1, X1, INCX1, SCL1, SSQ1 ) | |||
| NORMSQ2 = SCL1**2*SSQ1 + SCL2**2*SSQ2 | |||
| * | |||
| * If second projection is sufficiently large in norm, then do | |||
| * nothing more. Alternatively, if it shrunk significantly, then | |||
| * truncate it to zero. | |||
| * | |||
| IF( NORMSQ2 .LT. ALPHASQ*NORMSQ1 ) THEN | |||
| DO I = 1, M1 | |||
| X1(I) = ZERO | |||
| END DO | |||
| DO I = 1, M2 | |||
| X2(I) = ZERO | |||
| END DO | |||
| END IF | |||
| * | |||
| RETURN | |||
| * | |||
| * End of CUNBDB6 | |||
| * | |||
| END | |||
| @@ -308,7 +308,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date November 2011 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup complexOTHERcomputational | |||
| * | |||
| @@ -320,10 +320,10 @@ | |||
| $ LDV2T, WORK, LWORK, RWORK, LRWORK, | |||
| $ IWORK, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.0) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * November 2011 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER JOBU1, JOBU2, JOBV1T, JOBV2T, SIGNS, TRANS | |||
| @@ -356,7 +356,7 @@ | |||
| $ LBBCSDWORKOPT, LORBDBWORK, LORBDBWORKMIN, | |||
| $ LORBDBWORKOPT, LORGLQWORK, LORGLQWORKMIN, | |||
| $ LORGLQWORKOPT, LORGQRWORK, LORGQRWORKMIN, | |||
| $ LORGQRWORKOPT, LWORKMIN, LWORKOPT | |||
| $ LORGQRWORKOPT, LWORKMIN, LWORKOPT, P1, Q1 | |||
| LOGICAL COLMAJOR, DEFAULTSIGNS, LQUERY, WANTU1, WANTU2, | |||
| $ WANTV1T, WANTV2T | |||
| INTEGER LRWORKMIN, LRWORKOPT | |||
| @@ -392,9 +392,22 @@ | |||
| INFO = -8 | |||
| ELSE IF( Q .LT. 0 .OR. Q .GT. M ) THEN | |||
| INFO = -9 | |||
| ELSE IF( ( COLMAJOR .AND. LDX11 .LT. MAX(1,P) ) .OR. | |||
| $ ( .NOT.COLMAJOR .AND. LDX11 .LT. MAX(1,Q) ) ) THEN | |||
| INFO = -11 | |||
| ELSE IF ( COLMAJOR .AND. LDX11 .LT. MAX( 1, P ) ) THEN | |||
| INFO = -11 | |||
| ELSE IF (.NOT. COLMAJOR .AND. LDX11 .LT. MAX( 1, Q ) ) THEN | |||
| INFO = -11 | |||
| ELSE IF (COLMAJOR .AND. LDX12 .LT. MAX( 1, P ) ) THEN | |||
| INFO = -13 | |||
| ELSE IF (.NOT. COLMAJOR .AND. LDX12 .LT. MAX( 1, M-Q ) ) THEN | |||
| INFO = -13 | |||
| ELSE IF (COLMAJOR .AND. LDX21 .LT. MAX( 1, M-P ) ) THEN | |||
| INFO = -15 | |||
| ELSE IF (.NOT. COLMAJOR .AND. LDX21 .LT. MAX( 1, Q ) ) THEN | |||
| INFO = -15 | |||
| ELSE IF (COLMAJOR .AND. LDX22 .LT. MAX( 1, M-P ) ) THEN | |||
| INFO = -17 | |||
| ELSE IF (.NOT. COLMAJOR .AND. LDX22 .LT. MAX( 1, M-Q ) ) THEN | |||
| INFO = -17 | |||
| ELSE IF( WANTU1 .AND. LDU1 .LT. P ) THEN | |||
| INFO = -20 | |||
| ELSE IF( WANTU2 .AND. LDU2 .LT. M-P ) THEN | |||
| @@ -458,9 +471,10 @@ | |||
| IB22D = IB21E + MAX( 1, Q - 1 ) | |||
| IB22E = IB22D + MAX( 1, Q ) | |||
| IBBCSD = IB22E + MAX( 1, Q - 1 ) | |||
| CALL CBBCSD( JOBU1, JOBU2, JOBV1T, JOBV2T, TRANS, M, P, Q, 0, | |||
| $ 0, U1, LDU1, U2, LDU2, V1T, LDV1T, V2T, LDV2T, 0, | |||
| $ 0, 0, 0, 0, 0, 0, 0, RWORK, -1, CHILDINFO ) | |||
| CALL CBBCSD( JOBU1, JOBU2, JOBV1T, JOBV2T, TRANS, M, P, Q, | |||
| $ THETA, THETA, U1, LDU1, U2, LDU2, V1T, LDV1T, | |||
| $ V2T, LDV2T, THETA, THETA, THETA, THETA, THETA, | |||
| $ THETA, THETA, THETA, RWORK, -1, CHILDINFO ) | |||
| LBBCSDWORKOPT = INT( RWORK(1) ) | |||
| LBBCSDWORKMIN = LBBCSDWORKOPT | |||
| LRWORKOPT = IBBCSD + LBBCSDWORKOPT - 1 | |||
| @@ -474,19 +488,19 @@ | |||
| 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), 0, WORK, -1, | |||
| CALL CUNGQR( M-Q, M-Q, M-Q, 0, 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), 0, WORK, -1, | |||
| CALL CUNGLQ( M-Q, M-Q, M-Q, 0, MAX(1,M-Q), U1, WORK, -1, | |||
| $ CHILDINFO ) | |||
| LORGLQWORKOPT = INT( WORK(1) ) | |||
| LORGLQWORKMIN = MAX( 1, M - Q ) | |||
| IORBDB = ITAUQ2 + MAX( 1, M - Q ) | |||
| CALL CUNBDB( TRANS, SIGNS, M, P, Q, X11, LDX11, X12, LDX12, | |||
| $ X21, LDX21, X22, LDX22, 0, 0, 0, 0, 0, 0, WORK, | |||
| $ -1, CHILDINFO ) | |||
| $ X21, LDX21, X22, LDX22, THETA, THETA, U1, U2, | |||
| $ V1T, V2T, WORK, -1, CHILDINFO ) | |||
| LORBDBWORKOPT = INT( WORK(1) ) | |||
| LORBDBWORKMIN = LORBDBWORKOPT | |||
| LWORKOPT = MAX( IORGQR + LORGQRWORKOPT, IORGLQ + LORGLQWORKOPT, | |||
| @@ -551,10 +565,14 @@ | |||
| END IF | |||
| IF( WANTV2T .AND. M-Q .GT. 0 ) THEN | |||
| CALL CLACPY( 'U', P, M-Q, X12, LDX12, V2T, LDV2T ) | |||
| CALL CLACPY( 'U', M-P-Q, M-P-Q, X22(Q+1,P+1), LDX22, | |||
| $ V2T(P+1,P+1), LDV2T ) | |||
| CALL CUNGLQ( M-Q, M-Q, M-Q, V2T, LDV2T, WORK(ITAUQ2), | |||
| $ WORK(IORGLQ), LORGLQWORK, INFO ) | |||
| IF( M-P .GT. Q ) THEN | |||
| CALL CLACPY( 'U', M-P-Q, M-P-Q, X22(Q+1,P+1), LDX22, | |||
| $ V2T(P+1,P+1), LDV2T ) | |||
| END IF | |||
| IF( M .GT. Q ) THEN | |||
| CALL CUNGLQ( M-Q, M-Q, M-Q, V2T, LDV2T, WORK(ITAUQ2), | |||
| $ WORK(IORGLQ), LORGLQWORK, INFO ) | |||
| END IF | |||
| END IF | |||
| ELSE | |||
| IF( WANTU1 .AND. P .GT. 0 ) THEN | |||
| @@ -579,9 +597,13 @@ | |||
| $ WORK(IORGQR), LORGQRWORK, INFO ) | |||
| END IF | |||
| IF( WANTV2T .AND. M-Q .GT. 0 ) THEN | |||
| P1 = MIN( P+1, M ) | |||
| Q1 = MIN( Q+1, M ) | |||
| CALL CLACPY( 'L', M-Q, P, X12, LDX12, V2T, LDV2T ) | |||
| CALL CLACPY( 'L', M-P-Q, M-P-Q, X22(P+1,Q+1), LDX22, | |||
| $ V2T(P+1,P+1), LDV2T ) | |||
| IF ( M .GT. P+Q ) THEN | |||
| CALL CLACPY( 'L', M-P-Q, M-P-Q, X22(P1,Q1), LDX22, | |||
| $ V2T(P+1,P+1), LDV2T ) | |||
| END IF | |||
| CALL CUNGQR( M-Q, M-Q, M-Q, V2T, LDV2T, WORK(ITAUQ2), | |||
| $ WORK(IORGQR), LORGQRWORK, INFO ) | |||
| END IF | |||
| @@ -0,0 +1,757 @@ | |||
| *> \brief \b CUNCSD2BY1 | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download CUNCSD2BY1 + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/cuncsd2by1.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/cuncsd2by1.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/cuncsd2by1.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE CUNCSD2BY1( JOBU1, JOBU2, JOBV1T, M, P, Q, X11, LDX11, | |||
| * X21, LDX21, THETA, U1, LDU1, U2, LDU2, V1T, | |||
| * LDV1T, WORK, LWORK, RWORK, LRWORK, IWORK, | |||
| * INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * CHARACTER JOBU1, JOBU2, JOBV1T | |||
| * INTEGER INFO, LDU1, LDU2, LDV1T, LWORK, LDX11, LDX21, | |||
| * $ M, P, Q | |||
| * INTEGER LRWORK, LRWORKMIN, LRWORKOPT | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * REAL RWORK(*) | |||
| * REAL THETA(*) | |||
| * COMPLEX U1(LDU1,*), U2(LDU2,*), V1T(LDV1T,*), WORK(*), | |||
| * $ X11(LDX11,*), X21(LDX21,*) | |||
| * INTEGER IWORK(*) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| *> ============= | |||
| *> | |||
| *>\verbatim | |||
| *> | |||
| *> CUNCSD2BY1 computes the CS decomposition of an M-by-Q matrix X with | |||
| *> orthonormal columns that has been partitioned into a 2-by-1 block | |||
| *> structure: | |||
| *> | |||
| *> [ I 0 0 ] | |||
| *> [ 0 C 0 ] | |||
| *> [ X11 ] [ U1 | ] [ 0 0 0 ] | |||
| *> X = [-----] = [---------] [----------] V1**T . | |||
| *> [ X21 ] [ | U2 ] [ 0 0 0 ] | |||
| *> [ 0 S 0 ] | |||
| *> [ 0 0 I ] | |||
| *> | |||
| *> X11 is P-by-Q. The unitary matrices U1, U2, V1, and V2 are P-by-P, | |||
| *> (M-P)-by-(M-P), Q-by-Q, and (M-Q)-by-(M-Q), respectively. C and S are | |||
| *> R-by-R nonnegative diagonal matrices satisfying C^2 + S^2 = I, in | |||
| *> which R = MIN(P,M-P,Q,M-Q). | |||
| *> | |||
| *>\endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] JOBU1 | |||
| *> \verbatim | |||
| *> JOBU1 is CHARACTER | |||
| *> = 'Y': U1 is computed; | |||
| *> otherwise: U1 is not computed. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] JOBU2 | |||
| *> \verbatim | |||
| *> JOBU2 is CHARACTER | |||
| *> = 'Y': U2 is computed; | |||
| *> otherwise: U2 is not computed. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] JOBV1T | |||
| *> \verbatim | |||
| *> JOBV1T is CHARACTER | |||
| *> = 'Y': V1T is computed; | |||
| *> otherwise: V1T is not computed. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] M | |||
| *> \verbatim | |||
| *> M is INTEGER | |||
| *> The number of rows and columns in X. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] P | |||
| *> \verbatim | |||
| *> P is INTEGER | |||
| *> The number of rows in X11 and X12. 0 <= P <= M. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] Q | |||
| *> \verbatim | |||
| *> Q is INTEGER | |||
| *> The number of columns in X11 and X21. 0 <= Q <= M. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X11 | |||
| *> \verbatim | |||
| *> X11 is COMPLEX array, dimension (LDX11,Q) | |||
| *> On entry, part of the unitary matrix whose CSD is | |||
| *> desired. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDX11 | |||
| *> \verbatim | |||
| *> LDX11 is INTEGER | |||
| *> The leading dimension of X11. LDX11 >= MAX(1,P). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X21 | |||
| *> \verbatim | |||
| *> X21 is COMPLEX array, dimension (LDX21,Q) | |||
| *> On entry, part of the unitary matrix whose CSD is | |||
| *> desired. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDX21 | |||
| *> \verbatim | |||
| *> LDX21 is INTEGER | |||
| *> The leading dimension of X21. LDX21 >= MAX(1,M-P). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] THETA | |||
| *> \verbatim | |||
| *> THETA is COMPLEX array, dimension (R), in which R = | |||
| *> MIN(P,M-P,Q,M-Q). | |||
| *> C = DIAG( COS(THETA(1)), ... , COS(THETA(R)) ) and | |||
| *> S = DIAG( SIN(THETA(1)), ... , SIN(THETA(R)) ). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] U1 | |||
| *> \verbatim | |||
| *> U1 is COMPLEX array, dimension (P) | |||
| *> If JOBU1 = 'Y', U1 contains the P-by-P unitary matrix U1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDU1 | |||
| *> \verbatim | |||
| *> LDU1 is INTEGER | |||
| *> The leading dimension of U1. If JOBU1 = 'Y', LDU1 >= | |||
| *> MAX(1,P). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] U2 | |||
| *> \verbatim | |||
| *> U2 is COMPLEX array, dimension (M-P) | |||
| *> If JOBU2 = 'Y', U2 contains the (M-P)-by-(M-P) unitary | |||
| *> matrix U2. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDU2 | |||
| *> \verbatim | |||
| *> LDU2 is INTEGER | |||
| *> The leading dimension of U2. If JOBU2 = 'Y', LDU2 >= | |||
| *> MAX(1,M-P). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] V1T | |||
| *> \verbatim | |||
| *> V1T is COMPLEX array, dimension (Q) | |||
| *> If JOBV1T = 'Y', V1T contains the Q-by-Q matrix unitary | |||
| *> matrix V1**T. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDV1T | |||
| *> \verbatim | |||
| *> LDV1T is INTEGER | |||
| *> The leading dimension of V1T. If JOBV1T = 'Y', LDV1T >= | |||
| *> MAX(1,Q). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] WORK | |||
| *> \verbatim | |||
| *> WORK is COMPLEX array, dimension (MAX(1,LWORK)) | |||
| *> On exit, if INFO = 0, WORK(1) returns the optimal LWORK. | |||
| *> If INFO > 0 on exit, WORK(2:R) contains the values PHI(1), | |||
| *> ..., PHI(R-1) that, together with THETA(1), ..., THETA(R), | |||
| *> define the matrix in intermediate bidiagonal-block form | |||
| *> remaining after nonconvergence. INFO specifies the number | |||
| *> of nonzero PHI's. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LWORK | |||
| *> \verbatim | |||
| *> LWORK is INTEGER | |||
| *> The dimension of the array WORK. | |||
| *> \endverbatim | |||
| *> \verbatim | |||
| *> 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 (MAX(1,LRWORK)) | |||
| *> On exit, if INFO = 0, RWORK(1) returns the optimal LRWORK. | |||
| *> If INFO > 0 on exit, RWORK(2:R) contains the values PHI(1), | |||
| *> ..., PHI(R-1) that, together with THETA(1), ..., THETA(R), | |||
| *> define the matrix in intermediate bidiagonal-block form | |||
| *> remaining after nonconvergence. INFO specifies the number | |||
| *> of nonzero PHI's. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LRWORK | |||
| *> \verbatim | |||
| *> LRWORK is INTEGER | |||
| *> The dimension of the array RWORK. | |||
| *> | |||
| *> 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 work array, and no error | |||
| *> message related to LRWORK is issued by XERBLA. | |||
| *> \param[out] IWORK | |||
| *> \verbatim | |||
| *> IWORK is INTEGER array, dimension (M-MIN(P,M-P,Q,M-Q)) | |||
| *> \endverbatim | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] INFO | |||
| *> \verbatim | |||
| *> INFO is INTEGER | |||
| *> = 0: successful exit. | |||
| *> < 0: if INFO = -i, the i-th argument had an illegal value. | |||
| *> > 0: CBBCSD did not converge. See the description of WORK | |||
| *> above for details. | |||
| *> \endverbatim | |||
| * | |||
| *> \par References: | |||
| *> ================ | |||
| *> | |||
| *> [1] Brian D. Sutton. Computing the complete CS decomposition. Numer. | |||
| *> Algorithms, 50(1):33-65, 2009. | |||
| *> | |||
| * | |||
| * Authors: | |||
| * ======== | |||
| * | |||
| *> \author Univ. of Tennessee | |||
| *> \author Univ. of California Berkeley | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date July 2012 | |||
| * | |||
| *> \ingroup complexOTHERcomputational | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE CUNCSD2BY1( JOBU1, JOBU2, JOBV1T, M, P, Q, X11, LDX11, | |||
| $ X21, LDX21, THETA, U1, LDU1, U2, LDU2, V1T, | |||
| $ LDV1T, WORK, LWORK, RWORK, LRWORK, IWORK, | |||
| $ INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * July 2012 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER JOBU1, JOBU2, JOBV1T | |||
| INTEGER INFO, LDU1, LDU2, LDV1T, LWORK, LDX11, LDX21, | |||
| $ M, P, Q | |||
| INTEGER LRWORK, LRWORKMIN, LRWORKOPT | |||
| * .. | |||
| * .. Array Arguments .. | |||
| REAL RWORK(*) | |||
| REAL THETA(*) | |||
| COMPLEX U1(LDU1,*), U2(LDU2,*), V1T(LDV1T,*), WORK(*), | |||
| $ X11(LDX11,*), X21(LDX21,*) | |||
| INTEGER IWORK(*) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| COMPLEX ONE, ZERO | |||
| PARAMETER ( ONE = (1.0E0,0.0E0), ZERO = (0.0E0,0.0E0) ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| INTEGER CHILDINFO, I, IB11D, IB11E, IB12D, IB12E, | |||
| $ IB21D, IB21E, IB22D, IB22E, IBBCSD, IORBDB, | |||
| $ IORGLQ, IORGQR, IPHI, ITAUP1, ITAUP2, ITAUQ1, | |||
| $ J, LBBCSD, LORBDB, LORGLQ, LORGLQMIN, | |||
| $ LORGLQOPT, LORGQR, LORGQRMIN, LORGQROPT, | |||
| $ LWORKMIN, LWORKOPT, R | |||
| LOGICAL LQUERY, WANTU1, WANTU2, WANTV1T | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL CBBCSD, CCOPY, CLACPY, CLAPMR, CLAPMT, CUNBDB1, | |||
| $ CUNBDB2, CUNBDB3, CUNBDB4, CUNGLQ, CUNGQR, | |||
| $ XERBLA | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| EXTERNAL LSAME | |||
| * .. | |||
| * .. Intrinsic Function .. | |||
| INTRINSIC INT, MAX, MIN | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Test input arguments | |||
| * | |||
| INFO = 0 | |||
| WANTU1 = LSAME( JOBU1, 'Y' ) | |||
| WANTU2 = LSAME( JOBU2, 'Y' ) | |||
| WANTV1T = LSAME( JOBV1T, 'Y' ) | |||
| LQUERY = LWORK .EQ. -1 | |||
| * | |||
| IF( M .LT. 0 ) THEN | |||
| INFO = -4 | |||
| ELSE IF( P .LT. 0 .OR. P .GT. M ) THEN | |||
| INFO = -5 | |||
| ELSE IF( Q .LT. 0 .OR. Q .GT. M ) THEN | |||
| INFO = -6 | |||
| ELSE IF( LDX11 .LT. MAX( 1, P ) ) THEN | |||
| INFO = -8 | |||
| ELSE IF( LDX21 .LT. MAX( 1, M-P ) ) THEN | |||
| INFO = -10 | |||
| ELSE IF( WANTU1 .AND. LDU1 .LT. P ) THEN | |||
| INFO = -13 | |||
| ELSE IF( WANTU2 .AND. LDU2 .LT. M - P ) THEN | |||
| INFO = -15 | |||
| ELSE IF( WANTV1T .AND. LDV1T .LT. Q ) THEN | |||
| INFO = -17 | |||
| END IF | |||
| * | |||
| R = MIN( P, M-P, Q, M-Q ) | |||
| * | |||
| * Compute workspace | |||
| * | |||
| * WORK layout: | |||
| * |-----------------------------------------| | |||
| * | LWORKOPT (1) | | |||
| * |-----------------------------------------| | |||
| * | TAUP1 (MAX(1,P)) | | |||
| * | TAUP2 (MAX(1,M-P)) | | |||
| * | TAUQ1 (MAX(1,Q)) | | |||
| * |-----------------------------------------| | |||
| * | CUNBDB WORK | CUNGQR WORK | CUNGLQ WORK | | |||
| * | | | | | |||
| * | | | | | |||
| * | | | | | |||
| * | | | | | |||
| * |-----------------------------------------| | |||
| * RWORK layout: | |||
| * |------------------| | |||
| * | LRWORKOPT (1) | | |||
| * |------------------| | |||
| * | PHI (MAX(1,R-1)) | | |||
| * |------------------| | |||
| * | B11D (R) | | |||
| * | B11E (R-1) | | |||
| * | B12D (R) | | |||
| * | B12E (R-1) | | |||
| * | B21D (R) | | |||
| * | B21E (R-1) | | |||
| * | B22D (R) | | |||
| * | B22E (R-1) | | |||
| * | CBBCSD RWORK | | |||
| * |------------------| | |||
| * | |||
| IF( INFO .EQ. 0 ) THEN | |||
| IPHI = 2 | |||
| IB11D = IPHI + MAX( 1, R-1 ) | |||
| IB11E = IB11D + MAX( 1, R ) | |||
| IB12D = IB11E + MAX( 1, R - 1 ) | |||
| IB12E = IB12D + MAX( 1, R ) | |||
| IB21D = IB12E + MAX( 1, R - 1 ) | |||
| IB21E = IB21D + MAX( 1, R ) | |||
| IB22D = IB21E + MAX( 1, R - 1 ) | |||
| IB22E = IB22D + MAX( 1, R ) | |||
| IBBCSD = IB22E + MAX( 1, R - 1 ) | |||
| ITAUP1 = 2 | |||
| ITAUP2 = ITAUP1 + MAX( 1, P ) | |||
| ITAUQ1 = ITAUP2 + MAX( 1, M-P ) | |||
| IORBDB = ITAUQ1 + MAX( 1, Q ) | |||
| IORGQR = ITAUQ1 + MAX( 1, Q ) | |||
| IORGLQ = ITAUQ1 + MAX( 1, Q ) | |||
| IF( R .EQ. Q ) THEN | |||
| CALL CUNBDB1( M, P, Q, X11, LDX11, X21, LDX21, THETA, 0, 0, | |||
| $ 0, 0, WORK, -1, CHILDINFO ) | |||
| LORBDB = INT( WORK(1) ) | |||
| IF( P .GE. M-P ) THEN | |||
| CALL CUNGQR( P, P, Q, U1, LDU1, 0, 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, | |||
| $ CHILDINFO ) | |||
| LORGQRMIN = MAX( 1, M-P ) | |||
| LORGQROPT = 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 ) | |||
| 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 ) | |||
| 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), | |||
| $ -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, | |||
| $ CHILDINFO ) | |||
| LORGQRMIN = MAX( 1, M-P ) | |||
| LORGQROPT = 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 ) | |||
| 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 ) | |||
| LORBDB = INT( WORK(1) ) | |||
| IF( P .GE. M-P-1 ) THEN | |||
| CALL CUNGQR( P, P, Q, U1, LDU1, 0, 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, | |||
| $ WORK(1), -1, CHILDINFO ) | |||
| LORGQRMIN = MAX( 1, M-P-1 ) | |||
| LORGQROPT = 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 ) | |||
| LBBCSD = INT( RWORK(1) ) | |||
| ELSE | |||
| CALL CUNBDB4( M, P, Q, X11, LDX11, X21, LDX21, THETA, 0, 0, | |||
| $ 0, 0, 0, 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, | |||
| $ CHILDINFO ) | |||
| LORGQRMIN = MAX( 1, P ) | |||
| LORGQROPT = INT( WORK(1) ) | |||
| ELSE | |||
| CALL CUNGQR( M-P, M-P, M-Q, U2, LDU2, 0, WORK(1), -1, | |||
| $ CHILDINFO ) | |||
| LORGQRMIN = MAX( 1, M-P ) | |||
| LORGQROPT = 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 ) | |||
| LBBCSD = INT( RWORK(1) ) | |||
| END IF | |||
| LRWORKMIN = IBBCSD+LBBCSD-1 | |||
| LRWORKOPT = LRWORKMIN | |||
| RWORK(1) = LRWORKOPT | |||
| LWORKMIN = MAX( IORBDB+LORBDB-1, | |||
| $ IORGQR+LORGQRMIN-1, | |||
| $ IORGLQ+LORGLQMIN-1 ) | |||
| LWORKOPT = MAX( IORBDB+LORBDB-1, | |||
| $ IORGQR+LORGQROPT-1, | |||
| $ IORGLQ+LORGLQOPT-1 ) | |||
| WORK(1) = LWORKOPT | |||
| IF( LWORK .LT. LWORKMIN .AND. .NOT.LQUERY ) THEN | |||
| INFO = -19 | |||
| END IF | |||
| END IF | |||
| IF( INFO .NE. 0 ) THEN | |||
| CALL XERBLA( 'CUNCSD2BY1', -INFO ) | |||
| RETURN | |||
| ELSE IF( LQUERY ) THEN | |||
| RETURN | |||
| END IF | |||
| LORGQR = LWORK-IORGQR+1 | |||
| LORGLQ = LWORK-IORGLQ+1 | |||
| * | |||
| * Handle four cases separately: R = Q, R = P, R = M-P, and R = M-Q, | |||
| * in which R = MIN(P,M-P,Q,M-Q) | |||
| * | |||
| IF( R .EQ. Q ) THEN | |||
| * | |||
| * Case 1: R = Q | |||
| * | |||
| * Simultaneously bidiagonalize X11 and X21 | |||
| * | |||
| CALL CUNBDB1( M, P, Q, X11, LDX11, X21, LDX21, THETA, | |||
| $ RWORK(IPHI), WORK(ITAUP1), WORK(ITAUP2), | |||
| $ WORK(ITAUQ1), WORK(IORBDB), LORBDB, CHILDINFO ) | |||
| * | |||
| * Accumulate Householder reflectors | |||
| * | |||
| IF( WANTU1 .AND. P .GT. 0 ) THEN | |||
| CALL CLACPY( 'L', P, Q, X11, LDX11, U1, LDU1 ) | |||
| CALL CUNGQR( P, P, Q, U1, LDU1, WORK(ITAUP1), WORK(IORGQR), | |||
| $ LORGQR, CHILDINFO ) | |||
| END IF | |||
| IF( WANTU2 .AND. M-P .GT. 0 ) THEN | |||
| CALL CLACPY( 'L', M-P, Q, X21, LDX21, U2, LDU2 ) | |||
| CALL CUNGQR( M-P, M-P, Q, U2, LDU2, WORK(ITAUP2), | |||
| $ WORK(IORGQR), LORGQR, CHILDINFO ) | |||
| END IF | |||
| IF( WANTV1T .AND. Q .GT. 0 ) THEN | |||
| V1T(1,1) = ONE | |||
| DO J = 2, Q | |||
| V1T(1,J) = ZERO | |||
| V1T(J,1) = ZERO | |||
| END DO | |||
| CALL CLACPY( 'U', Q-1, Q-1, X21(1,2), LDX21, V1T(2,2), | |||
| $ LDV1T ) | |||
| CALL CUNGLQ( Q-1, Q-1, Q-1, V1T(2,2), LDV1T, WORK(ITAUQ1), | |||
| $ WORK(IORGLQ), LORGLQ, CHILDINFO ) | |||
| END IF | |||
| * | |||
| * 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(IB12E), RWORK(IB21D), RWORK(IB21E), | |||
| $ RWORK(IB22D), RWORK(IB22E), RWORK(IBBCSD), LBBCSD, | |||
| $ CHILDINFO ) | |||
| * | |||
| * Permute rows and columns to place zero submatrices in | |||
| * preferred positions | |||
| * | |||
| IF( Q .GT. 0 .AND. WANTU2 ) THEN | |||
| DO I = 1, Q | |||
| IWORK(I) = M - P - Q + I | |||
| END DO | |||
| DO I = Q + 1, M - P | |||
| IWORK(I) = I - Q | |||
| END DO | |||
| CALL CLAPMT( .FALSE., M-P, M-P, U2, LDU2, IWORK ) | |||
| END IF | |||
| ELSE IF( R .EQ. P ) THEN | |||
| * | |||
| * Case 2: R = P | |||
| * | |||
| * Simultaneously bidiagonalize X11 and X21 | |||
| * | |||
| CALL CUNBDB2( M, P, Q, X11, LDX11, X21, LDX21, THETA, | |||
| $ RWORK(IPHI), WORK(ITAUP1), WORK(ITAUP2), | |||
| $ WORK(ITAUQ1), WORK(IORBDB), LORBDB, CHILDINFO ) | |||
| * | |||
| * Accumulate Householder reflectors | |||
| * | |||
| IF( WANTU1 .AND. P .GT. 0 ) THEN | |||
| U1(1,1) = ONE | |||
| DO J = 2, P | |||
| U1(1,J) = ZERO | |||
| U1(J,1) = ZERO | |||
| END DO | |||
| CALL CLACPY( 'L', P-1, P-1, X11(2,1), LDX11, U1(2,2), LDU1 ) | |||
| CALL CUNGQR( P-1, P-1, P-1, U1(2,2), LDU1, WORK(ITAUP1), | |||
| $ WORK(IORGQR), LORGQR, CHILDINFO ) | |||
| END IF | |||
| IF( WANTU2 .AND. M-P .GT. 0 ) THEN | |||
| CALL CLACPY( 'L', M-P, Q, X21, LDX21, U2, LDU2 ) | |||
| CALL CUNGQR( M-P, M-P, Q, U2, LDU2, WORK(ITAUP2), | |||
| $ WORK(IORGQR), LORGQR, CHILDINFO ) | |||
| END IF | |||
| IF( WANTV1T .AND. Q .GT. 0 ) THEN | |||
| CALL CLACPY( 'U', P, Q, X11, LDX11, V1T, LDV1T ) | |||
| CALL CUNGLQ( Q, Q, R, V1T, LDV1T, WORK(ITAUQ1), | |||
| $ WORK(IORGLQ), LORGLQ, CHILDINFO ) | |||
| END IF | |||
| * | |||
| * 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(IB12E), RWORK(IB21D), RWORK(IB21E), | |||
| $ RWORK(IB22D), RWORK(IB22E), RWORK(IBBCSD), LBBCSD, | |||
| $ CHILDINFO ) | |||
| * | |||
| * Permute rows and columns to place identity submatrices in | |||
| * preferred positions | |||
| * | |||
| IF( Q .GT. 0 .AND. WANTU2 ) THEN | |||
| DO I = 1, Q | |||
| IWORK(I) = M - P - Q + I | |||
| END DO | |||
| DO I = Q + 1, M - P | |||
| IWORK(I) = I - Q | |||
| END DO | |||
| CALL CLAPMT( .FALSE., M-P, M-P, U2, LDU2, IWORK ) | |||
| END IF | |||
| ELSE IF( R .EQ. M-P ) THEN | |||
| * | |||
| * Case 3: R = M-P | |||
| * | |||
| * Simultaneously bidiagonalize X11 and X21 | |||
| * | |||
| CALL CUNBDB3( M, P, Q, X11, LDX11, X21, LDX21, THETA, | |||
| $ RWORK(IPHI), WORK(ITAUP1), WORK(ITAUP2), | |||
| $ WORK(ITAUQ1), WORK(IORBDB), LORBDB, CHILDINFO ) | |||
| * | |||
| * Accumulate Householder reflectors | |||
| * | |||
| IF( WANTU1 .AND. P .GT. 0 ) THEN | |||
| CALL CLACPY( 'L', P, Q, X11, LDX11, U1, LDU1 ) | |||
| CALL CUNGQR( P, P, Q, U1, LDU1, WORK(ITAUP1), WORK(IORGQR), | |||
| $ LORGQR, CHILDINFO ) | |||
| END IF | |||
| IF( WANTU2 .AND. M-P .GT. 0 ) THEN | |||
| U2(1,1) = ONE | |||
| DO J = 2, M-P | |||
| U2(1,J) = ZERO | |||
| U2(J,1) = ZERO | |||
| END DO | |||
| CALL CLACPY( 'L', M-P-1, M-P-1, X21(2,1), LDX21, U2(2,2), | |||
| $ LDU2 ) | |||
| CALL CUNGQR( M-P-1, M-P-1, M-P-1, U2(2,2), LDU2, | |||
| $ WORK(ITAUP2), WORK(IORGQR), LORGQR, CHILDINFO ) | |||
| END IF | |||
| IF( WANTV1T .AND. Q .GT. 0 ) THEN | |||
| CALL CLACPY( 'U', M-P, Q, X21, LDX21, V1T, LDV1T ) | |||
| CALL CUNGLQ( Q, Q, R, V1T, LDV1T, WORK(ITAUQ1), | |||
| $ WORK(IORGLQ), LORGLQ, CHILDINFO ) | |||
| END IF | |||
| * | |||
| * 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, | |||
| $ U1, LDU1, 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 | |||
| * | |||
| IF( Q .GT. R ) THEN | |||
| DO I = 1, R | |||
| IWORK(I) = Q - R + I | |||
| END DO | |||
| DO I = R + 1, Q | |||
| IWORK(I) = I - R | |||
| END DO | |||
| IF( WANTU1 ) THEN | |||
| CALL CLAPMT( .FALSE., P, Q, U1, LDU1, IWORK ) | |||
| END IF | |||
| IF( WANTV1T ) THEN | |||
| CALL CLAPMR( .FALSE., Q, Q, V1T, LDV1T, IWORK ) | |||
| END IF | |||
| END IF | |||
| ELSE | |||
| * | |||
| * Case 4: R = M-Q | |||
| * | |||
| * Simultaneously bidiagonalize X11 and X21 | |||
| * | |||
| CALL CUNBDB4( M, P, Q, X11, LDX11, X21, LDX21, THETA, | |||
| $ RWORK(IPHI), WORK(ITAUP1), WORK(ITAUP2), | |||
| $ WORK(ITAUQ1), WORK(IORBDB), WORK(IORBDB+M), | |||
| $ LORBDB-M, CHILDINFO ) | |||
| * | |||
| * Accumulate Householder reflectors | |||
| * | |||
| IF( WANTU1 .AND. P .GT. 0 ) THEN | |||
| CALL CCOPY( P, WORK(IORBDB), 1, U1, 1 ) | |||
| DO J = 2, P | |||
| U1(1,J) = ZERO | |||
| END DO | |||
| CALL CLACPY( 'L', P-1, M-Q-1, X11(2,1), LDX11, U1(2,2), | |||
| $ LDU1 ) | |||
| CALL CUNGQR( P, P, M-Q, U1, LDU1, WORK(ITAUP1), | |||
| $ WORK(IORGQR), LORGQR, CHILDINFO ) | |||
| END IF | |||
| IF( WANTU2 .AND. M-P .GT. 0 ) THEN | |||
| CALL CCOPY( M-P, WORK(IORBDB+P), 1, U2, 1 ) | |||
| DO J = 2, M-P | |||
| U2(1,J) = ZERO | |||
| END DO | |||
| CALL CLACPY( 'L', M-P-1, M-Q-1, X21(2,1), LDX21, U2(2,2), | |||
| $ LDU2 ) | |||
| CALL CUNGQR( M-P, M-P, M-Q, U2, LDU2, WORK(ITAUP2), | |||
| $ WORK(IORGQR), LORGQR, CHILDINFO ) | |||
| END IF | |||
| IF( WANTV1T .AND. Q .GT. 0 ) THEN | |||
| CALL CLACPY( 'U', M-Q, Q, X21, LDX21, V1T, LDV1T ) | |||
| CALL CLACPY( 'U', P-(M-Q), Q-(M-Q), X11(M-Q+1,M-Q+1), LDX11, | |||
| $ V1T(M-Q+1,M-Q+1), LDV1T ) | |||
| CALL CLACPY( 'U', -P+Q, Q-P, X21(M-Q+1,P+1), LDX21, | |||
| $ V1T(P+1,P+1), LDV1T ) | |||
| CALL CUNGLQ( Q, Q, Q, V1T, LDV1T, WORK(ITAUQ1), | |||
| $ WORK(IORGLQ), LORGLQ, CHILDINFO ) | |||
| END IF | |||
| * | |||
| * 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 ) | |||
| * | |||
| * Permute rows and columns to place identity submatrices in | |||
| * preferred positions | |||
| * | |||
| IF( P .GT. R ) THEN | |||
| DO I = 1, R | |||
| IWORK(I) = P - R + I | |||
| END DO | |||
| DO I = R + 1, P | |||
| IWORK(I) = I - R | |||
| END DO | |||
| IF( WANTU1 ) THEN | |||
| CALL CLAPMT( .FALSE., P, P, U1, LDU1, IWORK ) | |||
| END IF | |||
| IF( WANTV1T ) THEN | |||
| CALL CLAPMR( .FALSE., P, Q, V1T, LDV1T, IWORK ) | |||
| END IF | |||
| END IF | |||
| END IF | |||
| * | |||
| RETURN | |||
| * | |||
| * End of CUNCSD2BY1 | |||
| * | |||
| END | |||
| @@ -322,7 +322,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date November 2011 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup doubleOTHERcomputational | |||
| * | |||
| @@ -332,10 +332,10 @@ | |||
| $ V2T, LDV2T, B11D, B11E, B12D, B12E, B21D, B21E, | |||
| $ B22D, B22E, WORK, LWORK, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.0) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * November 2011 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER JOBU1, JOBU2, JOBV1T, JOBV2T, TRANS | |||
| @@ -358,8 +358,8 @@ | |||
| PARAMETER ( HUNDRED = 100.0D0, MEIGHTH = -0.125D0, | |||
| $ ONE = 1.0D0, PIOVER2 = 1.57079632679489662D0, | |||
| $ TEN = 10.0D0, ZERO = 0.0D0 ) | |||
| DOUBLE PRECISION NEGONECOMPLEX | |||
| PARAMETER ( NEGONECOMPLEX = -1.0D0 ) | |||
| DOUBLE PRECISION NEGONE | |||
| PARAMETER ( NEGONE = -1.0D0 ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| LOGICAL COLMAJOR, LQUERY, RESTART11, RESTART12, | |||
| @@ -477,7 +477,10 @@ | |||
| * Initial deflation | |||
| * | |||
| IMAX = Q | |||
| DO WHILE( ( IMAX .GT. 1 ) .AND. ( PHI(IMAX-1) .EQ. ZERO ) ) | |||
| DO WHILE( IMAX .GT. 1 ) | |||
| IF( PHI(IMAX-1) .NE. ZERO ) THEN | |||
| EXIT | |||
| END IF | |||
| IMAX = IMAX - 1 | |||
| END DO | |||
| IMIN = IMAX - 1 | |||
| @@ -939,9 +942,9 @@ | |||
| B21D(IMAX) = -B21D(IMAX) | |||
| IF( WANTV1T ) THEN | |||
| IF( COLMAJOR ) THEN | |||
| CALL DSCAL( Q, NEGONECOMPLEX, V1T(IMAX,1), LDV1T ) | |||
| CALL DSCAL( Q, NEGONE, V1T(IMAX,1), LDV1T ) | |||
| ELSE | |||
| CALL DSCAL( Q, NEGONECOMPLEX, V1T(1,IMAX), 1 ) | |||
| CALL DSCAL( Q, NEGONE, V1T(1,IMAX), 1 ) | |||
| END IF | |||
| END IF | |||
| END IF | |||
| @@ -962,9 +965,9 @@ | |||
| B12D(IMAX) = -B12D(IMAX) | |||
| IF( WANTU1 ) THEN | |||
| IF( COLMAJOR ) THEN | |||
| CALL DSCAL( P, NEGONECOMPLEX, U1(1,IMAX), 1 ) | |||
| CALL DSCAL( P, NEGONE, U1(1,IMAX), 1 ) | |||
| ELSE | |||
| CALL DSCAL( P, NEGONECOMPLEX, U1(IMAX,1), LDU1 ) | |||
| CALL DSCAL( P, NEGONE, U1(IMAX,1), LDU1 ) | |||
| END IF | |||
| END IF | |||
| END IF | |||
| @@ -972,9 +975,9 @@ | |||
| B22D(IMAX) = -B22D(IMAX) | |||
| IF( WANTU2 ) THEN | |||
| IF( COLMAJOR ) THEN | |||
| CALL DSCAL( M-P, NEGONECOMPLEX, U2(1,IMAX), 1 ) | |||
| CALL DSCAL( M-P, NEGONE, U2(1,IMAX), 1 ) | |||
| ELSE | |||
| CALL DSCAL( M-P, NEGONECOMPLEX, U2(IMAX,1), LDU2 ) | |||
| CALL DSCAL( M-P, NEGONE, U2(IMAX,1), LDU2 ) | |||
| END IF | |||
| END IF | |||
| END IF | |||
| @@ -984,9 +987,9 @@ | |||
| IF( B12D(IMAX)+B22D(IMAX) .LT. 0 ) THEN | |||
| IF( WANTV2T ) THEN | |||
| IF( COLMAJOR ) THEN | |||
| CALL DSCAL( M-Q, NEGONECOMPLEX, V2T(IMAX,1), LDV2T ) | |||
| CALL DSCAL( M-Q, NEGONE, V2T(IMAX,1), LDV2T ) | |||
| ELSE | |||
| CALL DSCAL( M-Q, NEGONECOMPLEX, V2T(1,IMAX), 1 ) | |||
| CALL DSCAL( M-Q, NEGONE, V2T(1,IMAX), 1 ) | |||
| END IF | |||
| END IF | |||
| END IF | |||
| @@ -121,7 +121,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date November 2011 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup doubleGEcomputational | |||
| * | |||
| @@ -160,10 +160,10 @@ | |||
| * ===================================================================== | |||
| SUBROUTINE DGEBAL( JOB, N, A, LDA, ILO, IHI, SCALE, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.0) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * November 2011 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER JOB | |||
| @@ -192,8 +192,8 @@ | |||
| * .. External Functions .. | |||
| LOGICAL DISNAN, LSAME | |||
| INTEGER IDAMAX | |||
| DOUBLE PRECISION DLAMCH | |||
| EXTERNAL DISNAN, LSAME, IDAMAX, DLAMCH | |||
| DOUBLE PRECISION DLAMCH, DNRM2 | |||
| EXTERNAL DISNAN, LSAME, IDAMAX, DLAMCH, DNRM2 | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL DSCAL, DSWAP, XERBLA | |||
| @@ -312,19 +312,14 @@ | |||
| SFMAX1 = ONE / SFMIN1 | |||
| SFMIN2 = SFMIN1*SCLFAC | |||
| SFMAX2 = ONE / SFMIN2 | |||
| * | |||
| 140 CONTINUE | |||
| NOCONV = .FALSE. | |||
| * | |||
| DO 200 I = K, L | |||
| C = ZERO | |||
| R = ZERO | |||
| * | |||
| DO 150 J = K, L | |||
| IF( J.EQ.I ) | |||
| $ GO TO 150 | |||
| C = C + ABS( A( J, I ) ) | |||
| R = R + ABS( A( I, J ) ) | |||
| 150 CONTINUE | |||
| * | |||
| C = DNRM2( L-K+1, A( K, I ), 1 ) | |||
| R = DNRM2( L-K+1, A( I, K ), LDA ) | |||
| ICA = IDAMAX( L, A( 1, I ), 1 ) | |||
| CA = ABS( A( ICA, I ) ) | |||
| IRA = IDAMAX( N-K+1, A( I, K ), LDA ) | |||
| @@ -160,7 +160,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date November 2011 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup doubleGEcomputational | |||
| * | |||
| @@ -168,10 +168,10 @@ | |||
| SUBROUTINE DGEMQRT( SIDE, TRANS, M, N, K, NB, V, LDV, T, LDT, | |||
| $ C, LDC, WORK, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.0) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * November 2011 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER SIDE, TRANS | |||
| @@ -225,7 +225,7 @@ | |||
| INFO = -4 | |||
| ELSE IF( K.LT.0 .OR. K.GT.Q ) THEN | |||
| INFO = -5 | |||
| ELSE IF( NB.LT.1 .OR. NB.GT.K ) THEN | |||
| ELSE IF( NB.LT.1 .OR. (NB.GT.K .AND. K.GT.0)) THEN | |||
| INFO = -6 | |||
| ELSE IF( LDV.LT.MAX( 1, Q ) ) THEN | |||
| INFO = -8 | |||
| @@ -108,7 +108,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date November 2011 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup doubleGEcomputational | |||
| * | |||
| @@ -141,10 +141,10 @@ | |||
| * ===================================================================== | |||
| SUBROUTINE DGEQRT( M, N, NB, A, LDA, T, LDT, WORK, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.0) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * November 2011 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| INTEGER INFO, LDA, LDT, M, N, NB | |||
| @@ -173,7 +173,7 @@ | |||
| INFO = -1 | |||
| ELSE IF( N.LT.0 ) THEN | |||
| INFO = -2 | |||
| ELSE IF( NB.LT.1 .OR. NB.GT.MIN(M,N) ) THEN | |||
| ELSE IF( NB.LT.1 .OR. ( NB.GT.MIN(M,N) .AND. MIN(M,N).GT.0 ) )THEN | |||
| INFO = -3 | |||
| ELSE IF( LDA.LT.MAX( 1, M ) ) THEN | |||
| INFO = -5 | |||
| @@ -175,8 +175,7 @@ | |||
| *> 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 >= 3*min(M,N) + | |||
| *> max(max(M,N),4*min(M,N)*min(M,N)+3*min(M,N)+max(M,N)). | |||
| *> LWORK >= min(M,N)*(6+4*min(M,N))+max(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. | |||
| @@ -203,7 +202,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date September 2012 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup doubleGEsing | |||
| * | |||
| @@ -217,10 +216,10 @@ | |||
| SUBROUTINE DGESDD( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK, | |||
| $ LWORK, IWORK, INFO ) | |||
| * | |||
| * -- LAPACK driver routine (version 3.4.2) -- | |||
| * -- LAPACK driver routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * September 2012 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER JOBZ | |||
| @@ -98,7 +98,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date September 2012 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup doubleGEauxiliary | |||
| * | |||
| @@ -111,10 +111,10 @@ | |||
| * ===================================================================== | |||
| SUBROUTINE DGETC2( N, A, LDA, IPIV, JPIV, INFO ) | |||
| * | |||
| * -- LAPACK auxiliary routine (version 3.4.2) -- | |||
| * -- LAPACK auxiliary routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * September 2012 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| INTEGER INFO, LDA, N | |||
| @@ -203,6 +203,11 @@ | |||
| INFO = N | |||
| A( N, N ) = SMIN | |||
| END IF | |||
| * | |||
| * Set last pivots to N | |||
| * | |||
| IPIV( N ) = N | |||
| JPIV( N ) = N | |||
| * | |||
| RETURN | |||
| * | |||
| @@ -282,7 +282,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date April 2012 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup doubleGEcomputational | |||
| * | |||
| @@ -304,10 +304,10 @@ | |||
| $ ALPHAR, ALPHAI, BETA, Q, LDQ, Z, LDZ, WORK, | |||
| $ LWORK, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.1) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * April 2012 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER COMPQ, COMPZ, JOB | |||
| @@ -739,9 +739,9 @@ | |||
| * Exceptional shift. Chosen for no particularly good reason. | |||
| * (Single shift only.) | |||
| * | |||
| IF( ( DBLE( MAXIT )*SAFMIN )*ABS( H( ILAST-1, ILAST ) ).LT. | |||
| IF( ( DBLE( MAXIT )*SAFMIN )*ABS( H( ILAST, ILAST-1 ) ).LT. | |||
| $ ABS( T( ILAST-1, ILAST-1 ) ) ) THEN | |||
| ESHIFT = ESHIFT + H( ILAST, ILAST-1 ) / | |||
| ESHIFT = H( ILAST, ILAST-1 ) / | |||
| $ T( ILAST-1, ILAST-1 ) | |||
| ELSE | |||
| ESHIFT = ESHIFT + ONE / ( SAFMIN*DBLE( MAXIT ) ) | |||
| @@ -759,6 +759,16 @@ | |||
| $ T( ILAST-1, ILAST-1 ), LDT, SAFMIN*SAFETY, S1, | |||
| $ S2, WR, WR2, WI ) | |||
| * | |||
| IF ( ABS( (WR/S1)*T( ILAST, ILAST ) - H( ILAST, ILAST ) ) | |||
| $ .GT. ABS( (WR2/S2)*T( ILAST, ILAST ) | |||
| $ - H( ILAST, ILAST ) ) ) THEN | |||
| TEMP = WR | |||
| WR = WR2 | |||
| WR2 = TEMP | |||
| TEMP = S1 | |||
| S1 = S2 | |||
| S2 = TEMP | |||
| END IF | |||
| TEMP = MAX( S1, SAFMIN*MAX( ONE, ABS( WR ), ABS( WI ) ) ) | |||
| IF( WI.NE.ZERO ) | |||
| $ GO TO 200 | |||
| @@ -108,6 +108,7 @@ | |||
| *> \verbatim | |||
| *> H is DOUBLE PRECISION array, dimension (LDH,N) | |||
| *> The upper Hessenberg matrix H. | |||
| *> If a NaN is detected in H, the routine will return with INFO=-6. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDH | |||
| @@ -243,7 +244,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date November 2011 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup doubleOTHERcomputational | |||
| * | |||
| @@ -262,10 +263,10 @@ | |||
| $ VL, LDVL, VR, LDVR, MM, M, WORK, IFAILL, | |||
| $ IFAILR, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.0) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * November 2011 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER EIGSRC, INITV, SIDE | |||
| @@ -291,9 +292,9 @@ | |||
| $ WKR | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| LOGICAL LSAME, DISNAN | |||
| DOUBLE PRECISION DLAMCH, DLANHS | |||
| EXTERNAL LSAME, DLAMCH, DLANHS | |||
| EXTERNAL LSAME, DLAMCH, DLANHS, DISNAN | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL DLAEIN, XERBLA | |||
| @@ -423,7 +424,10 @@ | |||
| * has not ben computed before. | |||
| * | |||
| HNORM = DLANHS( 'I', KR-KL+1, H( KL, KL ), LDH, WORK ) | |||
| IF( HNORM.GT.ZERO ) THEN | |||
| IF( DISNAN( HNORM ) ) THEN | |||
| INFO = -6 | |||
| RETURN | |||
| ELSE IF( HNORM.GT.ZERO ) THEN | |||
| EPS3 = HNORM*ULP | |||
| ELSE | |||
| EPS3 = SMLNUM | |||
| @@ -36,8 +36,9 @@ | |||
| *> p + i*q = --------- | |||
| *> c + i*d | |||
| *> | |||
| *> The algorithm is due to Robert L. Smith and can be found | |||
| *> in D. Knuth, The art of Computer Programming, Vol.2, p.195 | |||
| *> The algorithm is due to Michael Baudin and Robert L. Smith | |||
| *> and can be found in the paper | |||
| *> "A Robust Complex Division in Scilab" | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| @@ -83,17 +84,17 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date September 2012 | |||
| *> \date January 2013 | |||
| * | |||
| *> \ingroup auxOTHERauxiliary | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE DLADIV( A, B, C, D, P, Q ) | |||
| * | |||
| * -- LAPACK auxiliary routine (version 3.4.2) -- | |||
| * -- LAPACK auxiliary routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * September 2012 | |||
| * January 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| DOUBLE PRECISION A, B, C, D, P, Q | |||
| @@ -101,28 +102,152 @@ | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| DOUBLE PRECISION BS | |||
| PARAMETER ( BS = 2.0D0 ) | |||
| DOUBLE PRECISION HALF | |||
| PARAMETER ( HALF = 0.5D0 ) | |||
| DOUBLE PRECISION TWO | |||
| PARAMETER ( TWO = 2.0D0 ) | |||
| * | |||
| * .. Local Scalars .. | |||
| DOUBLE PRECISION E, F | |||
| DOUBLE PRECISION AA, BB, CC, DD, AB, CD, S, OV, UN, BE, EPS | |||
| * .. | |||
| * .. External Functions .. | |||
| DOUBLE PRECISION DLAMCH | |||
| EXTERNAL DLAMCH | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL DLADIV1 | |||
| * .. | |||
| * .. Intrinsic Functions .. | |||
| INTRINSIC ABS | |||
| INTRINSIC ABS, MAX | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| IF( ABS( D ).LT.ABS( C ) ) THEN | |||
| E = D / C | |||
| F = C + D*E | |||
| P = ( A+B*E ) / F | |||
| Q = ( B-A*E ) / F | |||
| AA = A | |||
| BB = B | |||
| CC = C | |||
| DD = D | |||
| AB = MAX( ABS(A), ABS(B) ) | |||
| CD = MAX( ABS(C), ABS(D) ) | |||
| S = 1.0D0 | |||
| OV = DLAMCH( 'Overflow threshold' ) | |||
| UN = DLAMCH( 'Safe minimum' ) | |||
| EPS = DLAMCH( 'Epsilon' ) | |||
| BE = BS / (EPS*EPS) | |||
| IF( AB >= HALF*OV ) THEN | |||
| AA = HALF * AA | |||
| BB = HALF * BB | |||
| S = TWO * S | |||
| END IF | |||
| IF( CD >= HALF*OV ) THEN | |||
| CC = HALF * CC | |||
| DD = HALF * DD | |||
| S = HALF * S | |||
| END IF | |||
| IF( AB <= UN*BS/EPS ) THEN | |||
| AA = AA * BE | |||
| BB = BB * BE | |||
| S = S / BE | |||
| END IF | |||
| IF( CD <= UN*BS/EPS ) THEN | |||
| CC = CC * BE | |||
| DD = DD * BE | |||
| S = S * BE | |||
| END IF | |||
| IF( ABS( D ).LE.ABS( C ) ) THEN | |||
| CALL DLADIV1(AA, BB, CC, DD, P, Q) | |||
| ELSE | |||
| E = C / D | |||
| F = D + C*E | |||
| P = ( B+A*E ) / F | |||
| Q = ( -A+B*E ) / F | |||
| CALL DLADIV1(BB, AA, DD, CC, P, Q) | |||
| Q = -Q | |||
| END IF | |||
| P = P * S | |||
| Q = Q * S | |||
| * | |||
| RETURN | |||
| * | |||
| * End of DLADIV | |||
| * | |||
| END | |||
| SUBROUTINE DLADIV1( A, B, C, D, P, Q ) | |||
| * | |||
| * -- LAPACK auxiliary routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * January 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| DOUBLE PRECISION A, B, C, D, P, Q | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| DOUBLE PRECISION ONE | |||
| PARAMETER ( ONE = 1.0D0 ) | |||
| * | |||
| * .. Local Scalars .. | |||
| DOUBLE PRECISION R, T | |||
| * .. | |||
| * .. External Functions .. | |||
| DOUBLE PRECISION DLADIV2 | |||
| EXTERNAL DLADIV2 | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| R = D / C | |||
| T = ONE / (C + D * R) | |||
| P = DLADIV2(A, B, C, D, R, T) | |||
| A = -A | |||
| Q = DLADIV2(B, A, C, D, R, T) | |||
| * | |||
| RETURN | |||
| * | |||
| * End of DLADIV1 | |||
| * | |||
| END | |||
| DOUBLE PRECISION FUNCTION DLADIV2( A, B, C, D, R, T ) | |||
| * | |||
| * -- LAPACK auxiliary routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * January 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| DOUBLE PRECISION A, B, C, D, R, T | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| DOUBLE PRECISION ZERO | |||
| PARAMETER ( ZERO = 0.0D0 ) | |||
| * | |||
| * .. Local Scalars .. | |||
| DOUBLE PRECISION BR | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| IF( R.NE.ZERO ) THEN | |||
| BR = B * R | |||
| if( BR.NE.ZERO ) THEN | |||
| DLADIV2 = (A + BR) * T | |||
| ELSE | |||
| DLADIV2 = A * T + (B * T) * R | |||
| END IF | |||
| ELSE | |||
| DLADIV2 = (A + D * (B / C)) * T | |||
| END IF | |||
| * | |||
| RETURN | |||
| * | |||
| * End of DLADIV12 | |||
| * | |||
| END | |||
| @@ -122,7 +122,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date September 2012 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup doubleOTHERauxiliary | |||
| * | |||
| @@ -149,10 +149,10 @@ | |||
| SUBROUTINE DLAQP2( M, N, OFFSET, A, LDA, JPVT, TAU, VN1, VN2, | |||
| $ WORK ) | |||
| * | |||
| * -- LAPACK auxiliary routine (version 3.4.2) -- | |||
| * -- LAPACK auxiliary routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * September 2012 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| INTEGER LDA, M, N, OFFSET | |||
| @@ -217,7 +217,7 @@ | |||
| CALL DLARFG( 1, A( M, I ), A( M, I ), 1, TAU( I ) ) | |||
| END IF | |||
| * | |||
| IF( I.LE.N ) THEN | |||
| IF( I.LT.N ) THEN | |||
| * | |||
| * Apply H(i)**T to A(offset+i:m,i+1:n) from the left. | |||
| * | |||
| @@ -159,7 +159,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date September 2012 | |||
| *> \date June 2013 | |||
| * | |||
| *> \ingroup doubleOTHERauxiliary | |||
| * | |||
| @@ -195,10 +195,10 @@ | |||
| SUBROUTINE DLARFB( SIDE, TRANS, DIRECT, STOREV, M, N, K, V, LDV, | |||
| $ T, LDT, C, LDC, WORK, LDWORK ) | |||
| * | |||
| * -- LAPACK auxiliary routine (version 3.4.2) -- | |||
| * -- LAPACK auxiliary routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * September 2012 | |||
| * June 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER DIRECT, SIDE, STOREV, TRANS | |||
| @@ -217,12 +217,11 @@ | |||
| * .. | |||
| * .. Local Scalars .. | |||
| CHARACTER TRANST | |||
| INTEGER I, J, LASTV, LASTC, lastv2 | |||
| INTEGER I, J | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| INTEGER ILADLR, ILADLC | |||
| EXTERNAL LSAME, ILADLR, ILADLC | |||
| EXTERNAL LSAME | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL DCOPY, DGEMM, DTRMM | |||
| @@ -252,58 +251,53 @@ | |||
| * | |||
| * Form H * C or H**T * C where C = ( C1 ) | |||
| * ( C2 ) | |||
| * | |||
| LASTV = MAX( K, ILADLR( M, K, V, LDV ) ) | |||
| LASTC = ILADLC( LASTV, N, C, LDC ) | |||
| * | |||
| * W := C**T * V = (C1**T * V1 + C2**T * V2) (stored in WORK) | |||
| * | |||
| * W := C1**T | |||
| * | |||
| DO 10 J = 1, K | |||
| CALL DCOPY( LASTC, C( J, 1 ), LDC, WORK( 1, J ), 1 ) | |||
| CALL DCOPY( N, C( J, 1 ), LDC, WORK( 1, J ), 1 ) | |||
| 10 CONTINUE | |||
| * | |||
| * W := W * V1 | |||
| * | |||
| CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit', | |||
| $ LASTC, K, ONE, V, LDV, WORK, LDWORK ) | |||
| IF( LASTV.GT.K ) THEN | |||
| CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit', N, | |||
| $ K, ONE, V, LDV, WORK, LDWORK ) | |||
| IF( M.GT.K ) THEN | |||
| * | |||
| * W := W + C2**T *V2 | |||
| * W := W + C2**T * V2 | |||
| * | |||
| CALL DGEMM( 'Transpose', 'No transpose', | |||
| $ LASTC, K, LASTV-K, | |||
| $ ONE, C( K+1, 1 ), LDC, V( K+1, 1 ), LDV, | |||
| $ ONE, WORK, LDWORK ) | |||
| CALL DGEMM( 'Transpose', 'No transpose', N, K, M-K, | |||
| $ ONE, C( K+1, 1 ), LDC, V( K+1, 1 ), LDV, | |||
| $ ONE, WORK, LDWORK ) | |||
| END IF | |||
| * | |||
| * W := W * T**T or W * T | |||
| * | |||
| CALL DTRMM( 'Right', 'Upper', TRANST, 'Non-unit', | |||
| $ LASTC, K, ONE, T, LDT, WORK, LDWORK ) | |||
| CALL DTRMM( 'Right', 'Upper', TRANST, 'Non-unit', N, K, | |||
| $ ONE, T, LDT, WORK, LDWORK ) | |||
| * | |||
| * C := C - V * W**T | |||
| * | |||
| IF( LASTV.GT.K ) THEN | |||
| IF( M.GT.K ) THEN | |||
| * | |||
| * C2 := C2 - V2 * W**T | |||
| * | |||
| CALL DGEMM( 'No transpose', 'Transpose', | |||
| $ LASTV-K, LASTC, K, | |||
| $ -ONE, V( K+1, 1 ), LDV, WORK, LDWORK, ONE, | |||
| $ C( K+1, 1 ), LDC ) | |||
| CALL DGEMM( 'No transpose', 'Transpose', M-K, N, K, | |||
| $ -ONE, V( K+1, 1 ), LDV, WORK, LDWORK, ONE, | |||
| $ C( K+1, 1 ), LDC ) | |||
| END IF | |||
| * | |||
| * W := W * V1**T | |||
| * | |||
| CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit', | |||
| $ LASTC, K, ONE, V, LDV, WORK, LDWORK ) | |||
| CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit', N, K, | |||
| $ ONE, V, LDV, WORK, LDWORK ) | |||
| * | |||
| * C1 := C1 - W**T | |||
| * | |||
| DO 30 J = 1, K | |||
| DO 20 I = 1, LASTC | |||
| DO 20 I = 1, N | |||
| C( J, I ) = C( J, I ) - WORK( I, J ) | |||
| 20 CONTINUE | |||
| 30 CONTINUE | |||
| @@ -311,58 +305,53 @@ | |||
| ELSE IF( LSAME( SIDE, 'R' ) ) THEN | |||
| * | |||
| * Form C * H or C * H**T where C = ( C1 C2 ) | |||
| * | |||
| LASTV = MAX( K, ILADLR( N, K, V, LDV ) ) | |||
| LASTC = ILADLR( M, LASTV, C, LDC ) | |||
| * | |||
| * W := C * V = (C1*V1 + C2*V2) (stored in WORK) | |||
| * | |||
| * W := C1 | |||
| * | |||
| DO 40 J = 1, K | |||
| CALL DCOPY( LASTC, C( 1, J ), 1, WORK( 1, J ), 1 ) | |||
| CALL DCOPY( M, C( 1, J ), 1, WORK( 1, J ), 1 ) | |||
| 40 CONTINUE | |||
| * | |||
| * W := W * V1 | |||
| * | |||
| CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit', | |||
| $ LASTC, K, ONE, V, LDV, WORK, LDWORK ) | |||
| IF( LASTV.GT.K ) THEN | |||
| CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit', M, | |||
| $ K, ONE, V, LDV, WORK, LDWORK ) | |||
| IF( N.GT.K ) THEN | |||
| * | |||
| * W := W + C2 * V2 | |||
| * | |||
| CALL DGEMM( 'No transpose', 'No transpose', | |||
| $ LASTC, K, LASTV-K, | |||
| $ ONE, C( 1, K+1 ), LDC, V( K+1, 1 ), LDV, | |||
| $ ONE, WORK, LDWORK ) | |||
| CALL DGEMM( 'No transpose', 'No transpose', M, K, N-K, | |||
| $ ONE, C( 1, K+1 ), LDC, V( K+1, 1 ), LDV, | |||
| $ ONE, WORK, LDWORK ) | |||
| END IF | |||
| * | |||
| * W := W * T or W * T**T | |||
| * | |||
| CALL DTRMM( 'Right', 'Upper', TRANS, 'Non-unit', | |||
| $ LASTC, K, ONE, T, LDT, WORK, LDWORK ) | |||
| CALL DTRMM( 'Right', 'Upper', TRANS, 'Non-unit', M, K, | |||
| $ ONE, T, LDT, WORK, LDWORK ) | |||
| * | |||
| * C := C - W * V**T | |||
| * | |||
| IF( LASTV.GT.K ) THEN | |||
| IF( N.GT.K ) THEN | |||
| * | |||
| * C2 := C2 - W * V2**T | |||
| * | |||
| CALL DGEMM( 'No transpose', 'Transpose', | |||
| $ LASTC, LASTV-K, K, | |||
| $ -ONE, WORK, LDWORK, V( K+1, 1 ), LDV, ONE, | |||
| $ C( 1, K+1 ), LDC ) | |||
| CALL DGEMM( 'No transpose', 'Transpose', M, N-K, K, | |||
| $ -ONE, WORK, LDWORK, V( K+1, 1 ), LDV, ONE, | |||
| $ C( 1, K+1 ), LDC ) | |||
| END IF | |||
| * | |||
| * W := W * V1**T | |||
| * | |||
| CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit', | |||
| $ LASTC, K, ONE, V, LDV, WORK, LDWORK ) | |||
| CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit', M, K, | |||
| $ ONE, V, LDV, WORK, LDWORK ) | |||
| * | |||
| * C1 := C1 - W | |||
| * | |||
| DO 60 J = 1, K | |||
| DO 50 I = 1, LASTC | |||
| DO 50 I = 1, M | |||
| C( I, J ) = C( I, J ) - WORK( I, J ) | |||
| 50 CONTINUE | |||
| 60 CONTINUE | |||
| @@ -378,36 +367,31 @@ | |||
| * | |||
| * Form H * C or H**T * C where C = ( C1 ) | |||
| * ( C2 ) | |||
| * | |||
| LASTC = ILADLC( M, N, C, LDC ) | |||
| * | |||
| * W := C**T * V = (C1**T * V1 + C2**T * V2) (stored in WORK) | |||
| * | |||
| * W := C2**T | |||
| * | |||
| DO 70 J = 1, K | |||
| CALL DCOPY( LASTC, C( M-K+J, 1 ), LDC, | |||
| $ WORK( 1, J ), 1 ) | |||
| CALL DCOPY( N, C( M-K+J, 1 ), LDC, WORK( 1, J ), 1 ) | |||
| 70 CONTINUE | |||
| * | |||
| * W := W * V2 | |||
| * | |||
| CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit', | |||
| $ LASTC, K, ONE, V( M-K+1, 1 ), LDV, | |||
| $ WORK, LDWORK ) | |||
| CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit', N, | |||
| $ K, ONE, V( M-K+1, 1 ), LDV, WORK, LDWORK ) | |||
| IF( M.GT.K ) THEN | |||
| * | |||
| * W := W + C1**T*V1 | |||
| * W := W + C1**T * V1 | |||
| * | |||
| CALL DGEMM( 'Transpose', 'No transpose', | |||
| $ LASTC, K, M-K, ONE, C, LDC, V, LDV, | |||
| $ ONE, WORK, LDWORK ) | |||
| CALL DGEMM( 'Transpose', 'No transpose', N, K, M-K, | |||
| $ ONE, C, LDC, V, LDV, ONE, WORK, LDWORK ) | |||
| END IF | |||
| * | |||
| * W := W * T**T or W * T | |||
| * | |||
| CALL DTRMM( 'Right', 'Lower', TRANST, 'Non-unit', | |||
| $ LASTC, K, ONE, T, LDT, WORK, LDWORK ) | |||
| CALL DTRMM( 'Right', 'Lower', TRANST, 'Non-unit', N, K, | |||
| $ ONE, T, LDT, WORK, LDWORK ) | |||
| * | |||
| * C := C - V * W**T | |||
| * | |||
| @@ -415,57 +399,51 @@ | |||
| * | |||
| * C1 := C1 - V1 * W**T | |||
| * | |||
| CALL DGEMM( 'No transpose', 'Transpose', | |||
| $ M-K, LASTC, K, -ONE, V, LDV, WORK, LDWORK, | |||
| $ ONE, C, LDC ) | |||
| CALL DGEMM( 'No transpose', 'Transpose', M-K, N, K, | |||
| $ -ONE, V, LDV, WORK, LDWORK, ONE, C, LDC ) | |||
| END IF | |||
| * | |||
| * W := W * V2**T | |||
| * | |||
| CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit', | |||
| $ LASTC, K, ONE, V( M-K+1, 1 ), LDV, | |||
| $ WORK, LDWORK ) | |||
| CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit', N, K, | |||
| $ ONE, V( M-K+1, 1 ), LDV, WORK, LDWORK ) | |||
| * | |||
| * C2 := C2 - W**T | |||
| * | |||
| DO 90 J = 1, K | |||
| DO 80 I = 1, LASTC | |||
| C( M-K+J, I ) = C( M-K+J, I ) - WORK(I, J) | |||
| DO 80 I = 1, N | |||
| C( M-K+J, I ) = C( M-K+J, I ) - WORK( I, J ) | |||
| 80 CONTINUE | |||
| 90 CONTINUE | |||
| * | |||
| ELSE IF( LSAME( SIDE, 'R' ) ) THEN | |||
| * | |||
| * Form C * H or C * H**T where C = ( C1 C2 ) | |||
| * | |||
| LASTC = ILADLR( M, N, C, LDC ) | |||
| * | |||
| * W := C * V = (C1*V1 + C2*V2) (stored in WORK) | |||
| * | |||
| * W := C2 | |||
| * | |||
| DO 100 J = 1, K | |||
| CALL DCOPY( LASTC, C( 1, N-K+J ), 1, WORK( 1, J ), 1 ) | |||
| CALL DCOPY( M, C( 1, N-K+J ), 1, WORK( 1, J ), 1 ) | |||
| 100 CONTINUE | |||
| * | |||
| * W := W * V2 | |||
| * | |||
| CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit', | |||
| $ LASTC, K, ONE, V( N-K+1, 1 ), LDV, | |||
| $ WORK, LDWORK ) | |||
| CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit', M, | |||
| $ K, ONE, V( N-K+1, 1 ), LDV, WORK, LDWORK ) | |||
| IF( N.GT.K ) THEN | |||
| * | |||
| * W := W + C1 * V1 | |||
| * | |||
| CALL DGEMM( 'No transpose', 'No transpose', | |||
| $ LASTC, K, N-K, ONE, C, LDC, V, LDV, | |||
| $ ONE, WORK, LDWORK ) | |||
| CALL DGEMM( 'No transpose', 'No transpose', M, K, N-K, | |||
| $ ONE, C, LDC, V, LDV, ONE, WORK, LDWORK ) | |||
| END IF | |||
| * | |||
| * W := W * T or W * T**T | |||
| * | |||
| CALL DTRMM( 'Right', 'Lower', TRANS, 'Non-unit', | |||
| $ LASTC, K, ONE, T, LDT, WORK, LDWORK ) | |||
| CALL DTRMM( 'Right', 'Lower', TRANS, 'Non-unit', M, K, | |||
| $ ONE, T, LDT, WORK, LDWORK ) | |||
| * | |||
| * C := C - W * V**T | |||
| * | |||
| @@ -473,22 +451,20 @@ | |||
| * | |||
| * C1 := C1 - W * V1**T | |||
| * | |||
| CALL DGEMM( 'No transpose', 'Transpose', | |||
| $ LASTC, N-K, K, -ONE, WORK, LDWORK, V, LDV, | |||
| $ ONE, C, LDC ) | |||
| CALL DGEMM( 'No transpose', 'Transpose', M, N-K, K, | |||
| $ -ONE, WORK, LDWORK, V, LDV, ONE, C, LDC ) | |||
| END IF | |||
| * | |||
| * W := W * V2**T | |||
| * | |||
| CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit', | |||
| $ LASTC, K, ONE, V( N-K+1, 1 ), LDV, | |||
| $ WORK, LDWORK ) | |||
| CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit', M, K, | |||
| $ ONE, V( N-K+1, 1 ), LDV, WORK, LDWORK ) | |||
| * | |||
| * C2 := C2 - W | |||
| * | |||
| DO 120 J = 1, K | |||
| DO 110 I = 1, LASTC | |||
| C( I, N-K+J ) = C( I, N-K+J ) - WORK(I, J) | |||
| DO 110 I = 1, M | |||
| C( I, N-K+J ) = C( I, N-K+J ) - WORK( I, J ) | |||
| 110 CONTINUE | |||
| 120 CONTINUE | |||
| END IF | |||
| @@ -505,58 +481,53 @@ | |||
| * | |||
| * Form H * C or H**T * C where C = ( C1 ) | |||
| * ( C2 ) | |||
| * | |||
| LASTV = MAX( K, ILADLC( K, M, V, LDV ) ) | |||
| LASTC = ILADLC( LASTV, N, C, LDC ) | |||
| * | |||
| * W := C**T * V**T = (C1**T * V1**T + C2**T * V2**T) (stored in WORK) | |||
| * | |||
| * W := C1**T | |||
| * | |||
| DO 130 J = 1, K | |||
| CALL DCOPY( LASTC, C( J, 1 ), LDC, WORK( 1, J ), 1 ) | |||
| CALL DCOPY( N, C( J, 1 ), LDC, WORK( 1, J ), 1 ) | |||
| 130 CONTINUE | |||
| * | |||
| * W := W * V1**T | |||
| * | |||
| CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit', | |||
| $ LASTC, K, ONE, V, LDV, WORK, LDWORK ) | |||
| IF( LASTV.GT.K ) THEN | |||
| CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit', N, K, | |||
| $ ONE, V, LDV, WORK, LDWORK ) | |||
| IF( M.GT.K ) THEN | |||
| * | |||
| * W := W + C2**T*V2**T | |||
| * W := W + C2**T * V2**T | |||
| * | |||
| CALL DGEMM( 'Transpose', 'Transpose', | |||
| $ LASTC, K, LASTV-K, | |||
| $ ONE, C( K+1, 1 ), LDC, V( 1, K+1 ), LDV, | |||
| $ ONE, WORK, LDWORK ) | |||
| CALL DGEMM( 'Transpose', 'Transpose', N, K, M-K, ONE, | |||
| $ C( K+1, 1 ), LDC, V( 1, K+1 ), LDV, ONE, | |||
| $ WORK, LDWORK ) | |||
| END IF | |||
| * | |||
| * W := W * T**T or W * T | |||
| * | |||
| CALL DTRMM( 'Right', 'Upper', TRANST, 'Non-unit', | |||
| $ LASTC, K, ONE, T, LDT, WORK, LDWORK ) | |||
| CALL DTRMM( 'Right', 'Upper', TRANST, 'Non-unit', N, K, | |||
| $ ONE, T, LDT, WORK, LDWORK ) | |||
| * | |||
| * C := C - V**T * W**T | |||
| * | |||
| IF( LASTV.GT.K ) THEN | |||
| IF( M.GT.K ) THEN | |||
| * | |||
| * C2 := C2 - V2**T * W**T | |||
| * | |||
| CALL DGEMM( 'Transpose', 'Transpose', | |||
| $ LASTV-K, LASTC, K, | |||
| $ -ONE, V( 1, K+1 ), LDV, WORK, LDWORK, | |||
| $ ONE, C( K+1, 1 ), LDC ) | |||
| CALL DGEMM( 'Transpose', 'Transpose', M-K, N, K, -ONE, | |||
| $ V( 1, K+1 ), LDV, WORK, LDWORK, ONE, | |||
| $ C( K+1, 1 ), LDC ) | |||
| END IF | |||
| * | |||
| * W := W * V1 | |||
| * | |||
| CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit', | |||
| $ LASTC, K, ONE, V, LDV, WORK, LDWORK ) | |||
| CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit', N, | |||
| $ K, ONE, V, LDV, WORK, LDWORK ) | |||
| * | |||
| * C1 := C1 - W**T | |||
| * | |||
| DO 150 J = 1, K | |||
| DO 140 I = 1, LASTC | |||
| DO 140 I = 1, N | |||
| C( J, I ) = C( J, I ) - WORK( I, J ) | |||
| 140 CONTINUE | |||
| 150 CONTINUE | |||
| @@ -564,58 +535,53 @@ | |||
| ELSE IF( LSAME( SIDE, 'R' ) ) THEN | |||
| * | |||
| * Form C * H or C * H**T where C = ( C1 C2 ) | |||
| * | |||
| LASTV = MAX( K, ILADLC( K, N, V, LDV ) ) | |||
| LASTC = ILADLR( M, LASTV, C, LDC ) | |||
| * | |||
| * W := C * V**T = (C1*V1**T + C2*V2**T) (stored in WORK) | |||
| * | |||
| * W := C1 | |||
| * | |||
| DO 160 J = 1, K | |||
| CALL DCOPY( LASTC, C( 1, J ), 1, WORK( 1, J ), 1 ) | |||
| CALL DCOPY( M, C( 1, J ), 1, WORK( 1, J ), 1 ) | |||
| 160 CONTINUE | |||
| * | |||
| * W := W * V1**T | |||
| * | |||
| CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit', | |||
| $ LASTC, K, ONE, V, LDV, WORK, LDWORK ) | |||
| IF( LASTV.GT.K ) THEN | |||
| CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit', M, K, | |||
| $ ONE, V, LDV, WORK, LDWORK ) | |||
| IF( N.GT.K ) THEN | |||
| * | |||
| * W := W + C2 * V2**T | |||
| * | |||
| CALL DGEMM( 'No transpose', 'Transpose', | |||
| $ LASTC, K, LASTV-K, | |||
| $ ONE, C( 1, K+1 ), LDC, V( 1, K+1 ), LDV, | |||
| $ ONE, WORK, LDWORK ) | |||
| CALL DGEMM( 'No transpose', 'Transpose', M, K, N-K, | |||
| $ ONE, C( 1, K+1 ), LDC, V( 1, K+1 ), LDV, | |||
| $ ONE, WORK, LDWORK ) | |||
| END IF | |||
| * | |||
| * W := W * T or W * T**T | |||
| * | |||
| CALL DTRMM( 'Right', 'Upper', TRANS, 'Non-unit', | |||
| $ LASTC, K, ONE, T, LDT, WORK, LDWORK ) | |||
| CALL DTRMM( 'Right', 'Upper', TRANS, 'Non-unit', M, K, | |||
| $ ONE, T, LDT, WORK, LDWORK ) | |||
| * | |||
| * C := C - W * V | |||
| * | |||
| IF( LASTV.GT.K ) THEN | |||
| IF( N.GT.K ) THEN | |||
| * | |||
| * C2 := C2 - W * V2 | |||
| * | |||
| CALL DGEMM( 'No transpose', 'No transpose', | |||
| $ LASTC, LASTV-K, K, | |||
| $ -ONE, WORK, LDWORK, V( 1, K+1 ), LDV, | |||
| $ ONE, C( 1, K+1 ), LDC ) | |||
| CALL DGEMM( 'No transpose', 'No transpose', M, N-K, K, | |||
| $ -ONE, WORK, LDWORK, V( 1, K+1 ), LDV, ONE, | |||
| $ C( 1, K+1 ), LDC ) | |||
| END IF | |||
| * | |||
| * W := W * V1 | |||
| * | |||
| CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit', | |||
| $ LASTC, K, ONE, V, LDV, WORK, LDWORK ) | |||
| CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit', M, | |||
| $ K, ONE, V, LDV, WORK, LDWORK ) | |||
| * | |||
| * C1 := C1 - W | |||
| * | |||
| DO 180 J = 1, K | |||
| DO 170 I = 1, LASTC | |||
| DO 170 I = 1, M | |||
| C( I, J ) = C( I, J ) - WORK( I, J ) | |||
| 170 CONTINUE | |||
| 180 CONTINUE | |||
| @@ -631,36 +597,31 @@ | |||
| * | |||
| * Form H * C or H**T * C where C = ( C1 ) | |||
| * ( C2 ) | |||
| * | |||
| LASTC = ILADLC( M, N, C, LDC ) | |||
| * | |||
| * W := C**T * V**T = (C1**T * V1**T + C2**T * V2**T) (stored in WORK) | |||
| * | |||
| * W := C2**T | |||
| * | |||
| DO 190 J = 1, K | |||
| CALL DCOPY( LASTC, C( M-K+J, 1 ), LDC, | |||
| $ WORK( 1, J ), 1 ) | |||
| CALL DCOPY( N, C( M-K+J, 1 ), LDC, WORK( 1, J ), 1 ) | |||
| 190 CONTINUE | |||
| * | |||
| * W := W * V2**T | |||
| * | |||
| CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit', | |||
| $ LASTC, K, ONE, V( 1, M-K+1 ), LDV, | |||
| $ WORK, LDWORK ) | |||
| CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit', N, K, | |||
| $ ONE, V( 1, M-K+1 ), LDV, WORK, LDWORK ) | |||
| IF( M.GT.K ) THEN | |||
| * | |||
| * W := W + C1**T * V1**T | |||
| * | |||
| CALL DGEMM( 'Transpose', 'Transpose', | |||
| $ LASTC, K, M-K, ONE, C, LDC, V, LDV, | |||
| $ ONE, WORK, LDWORK ) | |||
| CALL DGEMM( 'Transpose', 'Transpose', N, K, M-K, ONE, | |||
| $ C, LDC, V, LDV, ONE, WORK, LDWORK ) | |||
| END IF | |||
| * | |||
| * W := W * T**T or W * T | |||
| * | |||
| CALL DTRMM( 'Right', 'Lower', TRANST, 'Non-unit', | |||
| $ LASTC, K, ONE, T, LDT, WORK, LDWORK ) | |||
| CALL DTRMM( 'Right', 'Lower', TRANST, 'Non-unit', N, K, | |||
| $ ONE, T, LDT, WORK, LDWORK ) | |||
| * | |||
| * C := C - V**T * W**T | |||
| * | |||
| @@ -668,58 +629,51 @@ | |||
| * | |||
| * C1 := C1 - V1**T * W**T | |||
| * | |||
| CALL DGEMM( 'Transpose', 'Transpose', | |||
| $ M-K, LASTC, K, -ONE, V, LDV, WORK, LDWORK, | |||
| $ ONE, C, LDC ) | |||
| CALL DGEMM( 'Transpose', 'Transpose', M-K, N, K, -ONE, | |||
| $ V, LDV, WORK, LDWORK, ONE, C, LDC ) | |||
| END IF | |||
| * | |||
| * W := W * V2 | |||
| * | |||
| CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit', | |||
| $ LASTC, K, ONE, V( 1, M-K+1 ), LDV, | |||
| $ WORK, LDWORK ) | |||
| CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit', N, | |||
| $ K, ONE, V( 1, M-K+1 ), LDV, WORK, LDWORK ) | |||
| * | |||
| * C2 := C2 - W**T | |||
| * | |||
| DO 210 J = 1, K | |||
| DO 200 I = 1, LASTC | |||
| C( M-K+J, I ) = C( M-K+J, I ) - WORK(I, J) | |||
| DO 200 I = 1, N | |||
| C( M-K+J, I ) = C( M-K+J, I ) - WORK( I, J ) | |||
| 200 CONTINUE | |||
| 210 CONTINUE | |||
| * | |||
| ELSE IF( LSAME( SIDE, 'R' ) ) THEN | |||
| * | |||
| * Form C * H or C * H**T where C = ( C1 C2 ) | |||
| * | |||
| LASTC = ILADLR( M, N, C, LDC ) | |||
| * Form C * H or C * H' where C = ( C1 C2 ) | |||
| * | |||
| * W := C * V**T = (C1*V1**T + C2*V2**T) (stored in WORK) | |||
| * | |||
| * W := C2 | |||
| * | |||
| DO 220 J = 1, K | |||
| CALL DCOPY( LASTC, C( 1, N-K+J ), 1, | |||
| $ WORK( 1, J ), 1 ) | |||
| CALL DCOPY( M, C( 1, N-K+J ), 1, WORK( 1, J ), 1 ) | |||
| 220 CONTINUE | |||
| * | |||
| * W := W * V2**T | |||
| * | |||
| CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit', | |||
| $ LASTC, K, ONE, V( 1, N-K+1 ), LDV, | |||
| $ WORK, LDWORK ) | |||
| CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit', M, K, | |||
| $ ONE, V( 1, N-K+1 ), LDV, WORK, LDWORK ) | |||
| IF( N.GT.K ) THEN | |||
| * | |||
| * W := W + C1 * V1**T | |||
| * | |||
| CALL DGEMM( 'No transpose', 'Transpose', | |||
| $ LASTC, K, N-K, ONE, C, LDC, V, LDV, | |||
| $ ONE, WORK, LDWORK ) | |||
| CALL DGEMM( 'No transpose', 'Transpose', M, K, N-K, | |||
| $ ONE, C, LDC, V, LDV, ONE, WORK, LDWORK ) | |||
| END IF | |||
| * | |||
| * W := W * T or W * T**T | |||
| * | |||
| CALL DTRMM( 'Right', 'Lower', TRANS, 'Non-unit', | |||
| $ LASTC, K, ONE, T, LDT, WORK, LDWORK ) | |||
| CALL DTRMM( 'Right', 'Lower', TRANS, 'Non-unit', M, K, | |||
| $ ONE, T, LDT, WORK, LDWORK ) | |||
| * | |||
| * C := C - W * V | |||
| * | |||
| @@ -727,22 +681,20 @@ | |||
| * | |||
| * C1 := C1 - W * V1 | |||
| * | |||
| CALL DGEMM( 'No transpose', 'No transpose', | |||
| $ LASTC, N-K, K, -ONE, WORK, LDWORK, V, LDV, | |||
| $ ONE, C, LDC ) | |||
| CALL DGEMM( 'No transpose', 'No transpose', M, N-K, K, | |||
| $ -ONE, WORK, LDWORK, V, LDV, ONE, C, LDC ) | |||
| END IF | |||
| * | |||
| * W := W * V2 | |||
| * | |||
| CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit', | |||
| $ LASTC, K, ONE, V( 1, N-K+1 ), LDV, | |||
| $ WORK, LDWORK ) | |||
| CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit', M, | |||
| $ K, ONE, V( 1, N-K+1 ), LDV, WORK, LDWORK ) | |||
| * | |||
| * C1 := C1 - W | |||
| * | |||
| DO 240 J = 1, K | |||
| DO 230 I = 1, LASTC | |||
| C( I, N-K+J ) = C( I, N-K+J ) - WORK(I, J) | |||
| DO 230 I = 1, M | |||
| C( I, N-K+J ) = C( I, N-K+J ) - WORK( I, J ) | |||
| 230 CONTINUE | |||
| 240 CONTINUE | |||
| * | |||
| @@ -140,7 +140,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date September 2012 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup auxOTHERauxiliary | |||
| * | |||
| @@ -153,10 +153,10 @@ | |||
| * ===================================================================== | |||
| SUBROUTINE DLASD4( N, I, D, Z, DELTA, RHO, SIGMA, WORK, INFO ) | |||
| * | |||
| * -- LAPACK auxiliary routine (version 3.4.2) -- | |||
| * -- LAPACK auxiliary routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * September 2012 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| INTEGER I, INFO, N | |||
| @@ -1,25 +1,25 @@ | |||
| *> \brief \b DLASYF computes a partial factorization of a real symmetric matrix, using the diagonal pivoting method. | |||
| *> \brief \b DLASYF computes a partial factorization of a real symmetric matrix using the Bunch-Kaufman diagonal pivoting method. | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download DLASYF + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasyf.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasyf.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasyf.f"> | |||
| *> Download DLASYF + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasyf.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasyf.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasyf.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE DLASYF( UPLO, N, NB, KB, A, LDA, IPIV, W, LDW, INFO ) | |||
| * | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * CHARACTER UPLO | |||
| * INTEGER INFO, KB, LDA, LDW, N, NB | |||
| @@ -28,7 +28,7 @@ | |||
| * INTEGER IPIV( * ) | |||
| * DOUBLE PRECISION A( LDA, * ), W( LDW, * ) | |||
| * .. | |||
| * | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| * ============= | |||
| @@ -109,16 +109,26 @@ | |||
| *> \verbatim | |||
| *> IPIV is INTEGER array, dimension (N) | |||
| *> Details of the interchanges and the block structure of D. | |||
| *> If UPLO = 'U', only the last KB elements of IPIV are set; | |||
| *> if UPLO = 'L', only the first KB elements are set. | |||
| *> | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) were | |||
| *> interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> If UPLO = 'U' and IPIV(k) = IPIV(k-1) < 0, then rows and | |||
| *> columns k-1 and -IPIV(k) were interchanged and D(k-1:k,k-1:k) | |||
| *> is a 2-by-2 diagonal block. If UPLO = 'L' and IPIV(k) = | |||
| *> IPIV(k+1) < 0, then rows and columns k+1 and -IPIV(k) were | |||
| *> interchanged and D(k:k+1,k:k+1) is a 2-by-2 diagonal block. | |||
| *> If UPLO = 'U': | |||
| *> Only the last KB elements of IPIV are set. | |||
| *> | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) were | |||
| *> interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) = IPIV(k-1) < 0, then rows and columns | |||
| *> k-1 and -IPIV(k) were interchanged and D(k-1:k,k-1:k) | |||
| *> is a 2-by-2 diagonal block. | |||
| *> | |||
| *> If UPLO = 'L': | |||
| *> Only the first KB elements of IPIV are set. | |||
| *> | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) were | |||
| *> interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) = IPIV(k+1) < 0, then rows and columns | |||
| *> k+1 and -IPIV(k) were interchanged and D(k:k+1,k:k+1) | |||
| *> is a 2-by-2 diagonal block. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] W | |||
| @@ -144,22 +154,32 @@ | |||
| * Authors: | |||
| * ======== | |||
| * | |||
| *> \author Univ. of Tennessee | |||
| *> \author Univ. of California Berkeley | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| *> \author Univ. of Tennessee | |||
| *> \author Univ. of California Berkeley | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date September 2012 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup doubleSYcomputational | |||
| * | |||
| *> \par Contributors: | |||
| * ================== | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> November 2013, Igor Kozachenko, | |||
| *> Computer Science Division, | |||
| *> University of California, Berkeley | |||
| *> \endverbatim | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE DLASYF( UPLO, N, NB, KB, A, LDA, IPIV, W, LDW, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.2) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * September 2012 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER UPLO | |||
| @@ -237,7 +257,8 @@ | |||
| ABSAKK = ABS( W( K, KW ) ) | |||
| * | |||
| * IMAX is the row-index of the largest off-diagonal element in | |||
| * column K, and COLMAX is its absolute value | |||
| * column K, and COLMAX is its absolute value. | |||
| * Determine both COLMAX and IMAX. | |||
| * | |||
| IF( K.GT.1 ) THEN | |||
| IMAX = IDAMAX( K-1, W( 1, KW ), 1 ) | |||
| @@ -248,7 +269,7 @@ | |||
| * | |||
| IF( MAX( ABSAKK, COLMAX ).EQ.ZERO ) THEN | |||
| * | |||
| * Column K is zero: set INFO and continue | |||
| * Column K is zero or underflow: set INFO and continue | |||
| * | |||
| IF( INFO.EQ.0 ) | |||
| $ INFO = K | |||
| @@ -293,7 +314,7 @@ | |||
| * | |||
| KP = IMAX | |||
| * | |||
| * copy column KW-1 of W to column KW | |||
| * copy column KW-1 of W to column KW of W | |||
| * | |||
| CALL DCOPY( K, W( 1, KW-1 ), 1, W( 1, KW ), 1 ) | |||
| ELSE | |||
| @@ -305,60 +326,118 @@ | |||
| KSTEP = 2 | |||
| END IF | |||
| END IF | |||
| * | |||
| * ============================================================ | |||
| * | |||
| * KK is the column of A where pivoting step stopped | |||
| * | |||
| KK = K - KSTEP + 1 | |||
| * | |||
| * KKW is the column of W which corresponds to column KK of A | |||
| * | |||
| KKW = NB + KK - N | |||
| * | |||
| * Updated column KP is already stored in column KKW of W | |||
| * Interchange rows and columns KP and KK. | |||
| * Updated column KP is already stored in column KKW of W. | |||
| * | |||
| IF( KP.NE.KK ) THEN | |||
| * | |||
| * Copy non-updated column KK to column KP | |||
| * Copy non-updated column KK to column KP of submatrix A | |||
| * at step K. No need to copy element into column K | |||
| * (or K and K-1 for 2-by-2 pivot) of A, since these columns | |||
| * will be later overwritten. | |||
| * | |||
| A( KP, K ) = A( KK, K ) | |||
| CALL DCOPY( K-1-KP, A( KP+1, KK ), 1, A( KP, KP+1 ), | |||
| A( KP, KP ) = A( KK, KK ) | |||
| CALL DCOPY( KK-1-KP, A( KP+1, KK ), 1, A( KP, KP+1 ), | |||
| $ LDA ) | |||
| CALL DCOPY( KP, A( 1, KK ), 1, A( 1, KP ), 1 ) | |||
| IF( KP.GT.1 ) | |||
| $ CALL DCOPY( KP-1, A( 1, KK ), 1, A( 1, KP ), 1 ) | |||
| * | |||
| * Interchange rows KK and KP in last KK columns of A and W | |||
| * Interchange rows KK and KP in last K+1 to N columns of A | |||
| * (columns K (or K and K-1 for 2-by-2 pivot) of A will be | |||
| * later overwritten). Interchange rows KK and KP | |||
| * in last KKW to NB columns of W. | |||
| * | |||
| CALL DSWAP( N-KK+1, A( KK, KK ), LDA, A( KP, KK ), LDA ) | |||
| IF( K.LT.N ) | |||
| $ CALL DSWAP( N-K, A( KK, K+1 ), LDA, A( KP, K+1 ), | |||
| $ LDA ) | |||
| CALL DSWAP( N-KK+1, W( KK, KKW ), LDW, W( KP, KKW ), | |||
| $ LDW ) | |||
| END IF | |||
| * | |||
| IF( KSTEP.EQ.1 ) THEN | |||
| * | |||
| * 1-by-1 pivot block D(k): column KW of W now holds | |||
| * 1-by-1 pivot block D(k): column kw of W now holds | |||
| * | |||
| * W(k) = U(k)*D(k) | |||
| * W(kw) = U(k)*D(k), | |||
| * | |||
| * where U(k) is the k-th column of U | |||
| * | |||
| * Store U(k) in column k of A | |||
| * Store subdiag. elements of column U(k) | |||
| * and 1-by-1 block D(k) in column k of A. | |||
| * NOTE: Diagonal element U(k,k) is a UNIT element | |||
| * and not stored. | |||
| * A(k,k) := D(k,k) = W(k,kw) | |||
| * A(1:k-1,k) := U(1:k-1,k) = W(1:k-1,kw)/D(k,k) | |||
| * | |||
| CALL DCOPY( K, W( 1, KW ), 1, A( 1, K ), 1 ) | |||
| R1 = ONE / A( K, K ) | |||
| CALL DSCAL( K-1, R1, A( 1, K ), 1 ) | |||
| * | |||
| ELSE | |||
| * | |||
| * 2-by-2 pivot block D(k): columns KW and KW-1 of W now | |||
| * hold | |||
| * 2-by-2 pivot block D(k): columns kw and kw-1 of W now hold | |||
| * | |||
| * ( W(k-1) W(k) ) = ( U(k-1) U(k) )*D(k) | |||
| * ( W(kw-1) W(kw) ) = ( U(k-1) U(k) )*D(k) | |||
| * | |||
| * where U(k) and U(k-1) are the k-th and (k-1)-th columns | |||
| * of U | |||
| * | |||
| * Store U(1:k-2,k-1) and U(1:k-2,k) and 2-by-2 | |||
| * block D(k-1:k,k-1:k) in columns k-1 and k of A. | |||
| * NOTE: 2-by-2 diagonal block U(k-1:k,k-1:k) is a UNIT | |||
| * block and not stored. | |||
| * A(k-1:k,k-1:k) := D(k-1:k,k-1:k) = W(k-1:k,kw-1:kw) | |||
| * A(1:k-2,k-1:k) := U(1:k-2,k:k-1:k) = | |||
| * = W(1:k-2,kw-1:kw) * ( D(k-1:k,k-1:k)**(-1) ) | |||
| * | |||
| IF( K.GT.2 ) THEN | |||
| * | |||
| * Store U(k) and U(k-1) in columns k and k-1 of A | |||
| * Compose the columns of the inverse of 2-by-2 pivot | |||
| * block D in the following way to reduce the number | |||
| * of FLOPS when we myltiply panel ( W(kw-1) W(kw) ) by | |||
| * this inverse | |||
| * | |||
| * D**(-1) = ( d11 d21 )**(-1) = | |||
| * ( d21 d22 ) | |||
| * | |||
| * = 1/(d11*d22-d21**2) * ( ( d22 ) (-d21 ) ) = | |||
| * ( (-d21 ) ( d11 ) ) | |||
| * | |||
| * = 1/d21 * 1/((d11/d21)*(d22/d21)-1) * | |||
| * | |||
| * * ( ( d22/d21 ) ( -1 ) ) = | |||
| * ( ( -1 ) ( d11/d21 ) ) | |||
| * | |||
| * = 1/d21 * 1/(D22*D11-1) * ( ( D11 ) ( -1 ) ) = | |||
| * ( ( -1 ) ( D22 ) ) | |||
| * | |||
| * = 1/d21 * T * ( ( D11 ) ( -1 ) ) | |||
| * ( ( -1 ) ( D22 ) ) | |||
| * | |||
| * = D21 * ( ( D11 ) ( -1 ) ) | |||
| * ( ( -1 ) ( D22 ) ) | |||
| * | |||
| D21 = W( K-1, KW ) | |||
| D11 = W( K, KW ) / D21 | |||
| D22 = W( K-1, KW-1 ) / D21 | |||
| T = ONE / ( D11*D22-ONE ) | |||
| D21 = T / D21 | |||
| * | |||
| * Update elements in columns A(k-1) and A(k) as | |||
| * dot products of rows of ( W(kw-1) W(kw) ) and columns | |||
| * of D**(-1) | |||
| * | |||
| DO 20 J = 1, K - 2 | |||
| A( J, K-1 ) = D21*( D11*W( J, KW-1 )-W( J, KW ) ) | |||
| A( J, K ) = D21*( D22*W( J, KW )-W( J, KW-1 ) ) | |||
| @@ -370,7 +449,9 @@ | |||
| A( K-1, K-1 ) = W( K-1, KW-1 ) | |||
| A( K-1, K ) = W( K-1, KW ) | |||
| A( K, K ) = W( K, KW ) | |||
| * | |||
| END IF | |||
| * | |||
| END IF | |||
| * | |||
| * Store details of the interchanges in IPIV | |||
| @@ -414,20 +495,28 @@ | |||
| 50 CONTINUE | |||
| * | |||
| * Put U12 in standard form by partially undoing the interchanges | |||
| * in columns k+1:n | |||
| * in columns k+1:n looping backwards from k+1 to n | |||
| * | |||
| J = K + 1 | |||
| 60 CONTINUE | |||
| JJ = J | |||
| JP = IPIV( J ) | |||
| IF( JP.LT.0 ) THEN | |||
| JP = -JP | |||
| * | |||
| * Undo the interchanges (if any) of rows JJ and JP at each | |||
| * step J | |||
| * | |||
| * (Here, J is a diagonal index) | |||
| JJ = J | |||
| JP = IPIV( J ) | |||
| IF( JP.LT.0 ) THEN | |||
| JP = -JP | |||
| * (Here, J is a diagonal index) | |||
| J = J + 1 | |||
| END IF | |||
| * (NOTE: Here, J is used to determine row length. Length N-J+1 | |||
| * of the rows to swap back doesn't include diagonal element) | |||
| J = J + 1 | |||
| END IF | |||
| J = J + 1 | |||
| IF( JP.NE.JJ .AND. J.LE.N ) | |||
| $ CALL DSWAP( N-J+1, A( JP, J ), LDA, A( JJ, J ), LDA ) | |||
| IF( J.LE.N ) | |||
| IF( JP.NE.JJ .AND. J.LE.N ) | |||
| $ CALL DSWAP( N-J+1, A( JP, J ), LDA, A( JJ, J ), LDA ) | |||
| IF( J.LT.N ) | |||
| $ GO TO 60 | |||
| * | |||
| * Set KB to the number of columns factorized | |||
| @@ -464,7 +553,8 @@ | |||
| ABSAKK = ABS( W( K, K ) ) | |||
| * | |||
| * IMAX is the row-index of the largest off-diagonal element in | |||
| * column K, and COLMAX is its absolute value | |||
| * column K, and COLMAX is its absolute value. | |||
| * Determine both COLMAX and IMAX. | |||
| * | |||
| IF( K.LT.N ) THEN | |||
| IMAX = K + IDAMAX( N-K, W( K+1, K ), 1 ) | |||
| @@ -475,7 +565,7 @@ | |||
| * | |||
| IF( MAX( ABSAKK, COLMAX ).EQ.ZERO ) THEN | |||
| * | |||
| * Column K is zero: set INFO and continue | |||
| * Column K is zero or underflow: set INFO and continue | |||
| * | |||
| IF( INFO.EQ.0 ) | |||
| $ INFO = K | |||
| @@ -518,7 +608,7 @@ | |||
| * | |||
| KP = IMAX | |||
| * | |||
| * copy column K+1 of W to column K | |||
| * copy column K+1 of W to column K of W | |||
| * | |||
| CALL DCOPY( N-K+1, W( K, K+1 ), 1, W( K, K ), 1 ) | |||
| ELSE | |||
| @@ -530,22 +620,36 @@ | |||
| KSTEP = 2 | |||
| END IF | |||
| END IF | |||
| * | |||
| * ============================================================ | |||
| * | |||
| * KK is the column of A where pivoting step stopped | |||
| * | |||
| KK = K + KSTEP - 1 | |||
| * | |||
| * Updated column KP is already stored in column KK of W | |||
| * Interchange rows and columns KP and KK. | |||
| * Updated column KP is already stored in column KK of W. | |||
| * | |||
| IF( KP.NE.KK ) THEN | |||
| * | |||
| * Copy non-updated column KK to column KP | |||
| * Copy non-updated column KK to column KP of submatrix A | |||
| * at step K. No need to copy element into column K | |||
| * (or K and K+1 for 2-by-2 pivot) of A, since these columns | |||
| * will be later overwritten. | |||
| * | |||
| A( KP, K ) = A( KK, K ) | |||
| CALL DCOPY( KP-K-1, A( K+1, KK ), 1, A( KP, K+1 ), LDA ) | |||
| CALL DCOPY( N-KP+1, A( KP, KK ), 1, A( KP, KP ), 1 ) | |||
| A( KP, KP ) = A( KK, KK ) | |||
| CALL DCOPY( KP-KK-1, A( KK+1, KK ), 1, A( KP, KK+1 ), | |||
| $ LDA ) | |||
| IF( KP.LT.N ) | |||
| $ CALL DCOPY( N-KP, A( KP+1, KK ), 1, A( KP+1, KP ), 1 ) | |||
| * | |||
| * Interchange rows KK and KP in first KK columns of A and W | |||
| * Interchange rows KK and KP in first K-1 columns of A | |||
| * (columns K (or K and K+1 for 2-by-2 pivot) of A will be | |||
| * later overwritten). Interchange rows KK and KP | |||
| * in first KK columns of W. | |||
| * | |||
| CALL DSWAP( KK, A( KK, 1 ), LDA, A( KP, 1 ), LDA ) | |||
| IF( K.GT.1 ) | |||
| $ CALL DSWAP( K-1, A( KK, 1 ), LDA, A( KP, 1 ), LDA ) | |||
| CALL DSWAP( KK, W( KK, 1 ), LDW, W( KP, 1 ), LDW ) | |||
| END IF | |||
| * | |||
| @@ -553,17 +657,23 @@ | |||
| * | |||
| * 1-by-1 pivot block D(k): column k of W now holds | |||
| * | |||
| * W(k) = L(k)*D(k) | |||
| * W(k) = L(k)*D(k), | |||
| * | |||
| * where L(k) is the k-th column of L | |||
| * | |||
| * Store L(k) in column k of A | |||
| * Store subdiag. elements of column L(k) | |||
| * and 1-by-1 block D(k) in column k of A. | |||
| * (NOTE: Diagonal element L(k,k) is a UNIT element | |||
| * and not stored) | |||
| * A(k,k) := D(k,k) = W(k,k) | |||
| * A(k+1:N,k) := L(k+1:N,k) = W(k+1:N,k)/D(k,k) | |||
| * | |||
| CALL DCOPY( N-K+1, W( K, K ), 1, A( K, K ), 1 ) | |||
| IF( K.LT.N ) THEN | |||
| R1 = ONE / A( K, K ) | |||
| CALL DSCAL( N-K, R1, A( K+1, K ), 1 ) | |||
| END IF | |||
| * | |||
| ELSE | |||
| * | |||
| * 2-by-2 pivot block D(k): columns k and k+1 of W now hold | |||
| @@ -572,16 +682,52 @@ | |||
| * | |||
| * where L(k) and L(k+1) are the k-th and (k+1)-th columns | |||
| * of L | |||
| * | |||
| * Store L(k+2:N,k) and L(k+2:N,k+1) and 2-by-2 | |||
| * block D(k:k+1,k:k+1) in columns k and k+1 of A. | |||
| * (NOTE: 2-by-2 diagonal block L(k:k+1,k:k+1) is a UNIT | |||
| * block and not stored) | |||
| * A(k:k+1,k:k+1) := D(k:k+1,k:k+1) = W(k:k+1,k:k+1) | |||
| * A(k+2:N,k:k+1) := L(k+2:N,k:k+1) = | |||
| * = W(k+2:N,k:k+1) * ( D(k:k+1,k:k+1)**(-1) ) | |||
| * | |||
| IF( K.LT.N-1 ) THEN | |||
| * | |||
| * Store L(k) and L(k+1) in columns k and k+1 of A | |||
| * Compose the columns of the inverse of 2-by-2 pivot | |||
| * block D in the following way to reduce the number | |||
| * of FLOPS when we myltiply panel ( W(k) W(k+1) ) by | |||
| * this inverse | |||
| * | |||
| * D**(-1) = ( d11 d21 )**(-1) = | |||
| * ( d21 d22 ) | |||
| * | |||
| * = 1/(d11*d22-d21**2) * ( ( d22 ) (-d21 ) ) = | |||
| * ( (-d21 ) ( d11 ) ) | |||
| * | |||
| * = 1/d21 * 1/((d11/d21)*(d22/d21)-1) * | |||
| * | |||
| * * ( ( d22/d21 ) ( -1 ) ) = | |||
| * ( ( -1 ) ( d11/d21 ) ) | |||
| * | |||
| * = 1/d21 * 1/(D22*D11-1) * ( ( D11 ) ( -1 ) ) = | |||
| * ( ( -1 ) ( D22 ) ) | |||
| * | |||
| * = 1/d21 * T * ( ( D11 ) ( -1 ) ) | |||
| * ( ( -1 ) ( D22 ) ) | |||
| * | |||
| * = D21 * ( ( D11 ) ( -1 ) ) | |||
| * ( ( -1 ) ( D22 ) ) | |||
| * | |||
| D21 = W( K+1, K ) | |||
| D11 = W( K+1, K+1 ) / D21 | |||
| D22 = W( K, K ) / D21 | |||
| T = ONE / ( D11*D22-ONE ) | |||
| D21 = T / D21 | |||
| * | |||
| * Update elements in columns A(k) and A(k+1) as | |||
| * dot products of rows of ( W(k) W(k+1) ) and columns | |||
| * of D**(-1) | |||
| * | |||
| DO 80 J = K + 2, N | |||
| A( J, K ) = D21*( D11*W( J, K )-W( J, K+1 ) ) | |||
| A( J, K+1 ) = D21*( D22*W( J, K+1 )-W( J, K ) ) | |||
| @@ -593,7 +739,9 @@ | |||
| A( K, K ) = W( K, K ) | |||
| A( K+1, K ) = W( K+1, K ) | |||
| A( K+1, K+1 ) = W( K+1, K+1 ) | |||
| * | |||
| END IF | |||
| * | |||
| END IF | |||
| * | |||
| * Store details of the interchanges in IPIV | |||
| @@ -638,20 +786,28 @@ | |||
| 110 CONTINUE | |||
| * | |||
| * Put L21 in standard form by partially undoing the interchanges | |||
| * in columns 1:k-1 | |||
| * of rows in columns 1:k-1 looping backwards from k-1 to 1 | |||
| * | |||
| J = K - 1 | |||
| 120 CONTINUE | |||
| JJ = J | |||
| JP = IPIV( J ) | |||
| IF( JP.LT.0 ) THEN | |||
| JP = -JP | |||
| * | |||
| * Undo the interchanges (if any) of rows JJ and JP at each | |||
| * step J | |||
| * | |||
| * (Here, J is a diagonal index) | |||
| JJ = J | |||
| JP = IPIV( J ) | |||
| IF( JP.LT.0 ) THEN | |||
| JP = -JP | |||
| * (Here, J is a diagonal index) | |||
| J = J - 1 | |||
| END IF | |||
| * (NOTE: Here, J is used to determine row length. Length J | |||
| * of the rows to swap back doesn't include diagonal element) | |||
| J = J - 1 | |||
| END IF | |||
| J = J - 1 | |||
| IF( JP.NE.JJ .AND. J.GE.1 ) | |||
| $ CALL DSWAP( J, A( JP, 1 ), LDA, A( JJ, 1 ), LDA ) | |||
| IF( J.GE.1 ) | |||
| IF( JP.NE.JJ .AND. J.GE.1 ) | |||
| $ CALL DSWAP( J, A( JP, 1 ), LDA, A( JJ, 1 ), LDA ) | |||
| IF( J.GT.1 ) | |||
| $ GO TO 120 | |||
| * | |||
| * Set KB to the number of columns factorized | |||
| @@ -0,0 +1,892 @@ | |||
| *> \brief \b DLASYF_ROOK *> DLASYF_ROOK computes a partial factorization of a real symmetric matrix using the bounded Bunch-Kaufman ("rook") diagonal pivoting method. | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download DLASYF_ROOK + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasyf_rook.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasyf_rook.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasyf_rook.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE DLASYF_ROOK( UPLO, N, NB, KB, A, LDA, IPIV, W, LDW, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * CHARADLATER UPLO | |||
| * INTEGER INFO, KB, LDA, LDW, N, NB | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * INTEGER IPIV( * ) | |||
| * DOUBLE PRECISION A( LDA, * ), W( LDW, * ) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| * ============= | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> DLASYF_ROOK computes a partial factorization of a real symmetric | |||
| *> matrix A using the bounded Bunch-Kaufman ("rook") diagonal | |||
| *> pivoting method. The partial factorization has the form: | |||
| *> | |||
| *> A = ( I U12 ) ( A11 0 ) ( I 0 ) if UPLO = 'U', or: | |||
| *> ( 0 U22 ) ( 0 D ) ( U12**T U22**T ) | |||
| *> | |||
| *> A = ( L11 0 ) ( D 0 ) ( L11**T L21**T ) if UPLO = 'L' | |||
| *> ( L21 I ) ( 0 A22 ) ( 0 I ) | |||
| *> | |||
| *> where the order of D is at most NB. The actual order is returned in | |||
| *> the argument KB, and is either NB or NB-1, or N if N <= NB. | |||
| *> | |||
| *> DLASYF_ROOK is an auxiliary routine called by DSYTRF_ROOK. It uses | |||
| *> blocked code (calling Level 3 BLAS) to update the submatrix | |||
| *> A11 (if UPLO = 'U') or A22 (if UPLO = 'L'). | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] UPLO | |||
| *> \verbatim | |||
| *> UPLO is CHARACTER*1 | |||
| *> Specifies whether the upper or lower triangular part of the | |||
| *> symmetric matrix A is stored: | |||
| *> = 'U': Upper triangular | |||
| *> = 'L': Lower triangular | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] N | |||
| *> \verbatim | |||
| *> N is INTEGER | |||
| *> The order of the matrix A. N >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] NB | |||
| *> \verbatim | |||
| *> NB is INTEGER | |||
| *> The maximum number of columns of the matrix A that should be | |||
| *> factored. NB should be at least 2 to allow for 2-by-2 pivot | |||
| *> blocks. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] KB | |||
| *> \verbatim | |||
| *> KB is INTEGER | |||
| *> The number of columns of A that were actually factored. | |||
| *> KB is either NB-1 or NB, or N if N <= NB. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] A | |||
| *> \verbatim | |||
| *> A is DOUBLE PRECISION 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 | |||
| *> triangular part of A is not referenced. If UPLO = 'L', the | |||
| *> leading n-by-n lower triangular part of A contains the lower | |||
| *> triangular part of the matrix A, and the strictly upper | |||
| *> triangular part of A is not referenced. | |||
| *> On exit, A contains details of the partial factorization. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDA | |||
| *> \verbatim | |||
| *> LDA is INTEGER | |||
| *> The leading dimension of the array A. LDA >= max(1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] IPIV | |||
| *> \verbatim | |||
| *> IPIV is INTEGER array, dimension (N) | |||
| *> Details of the interchanges and the block structure of D. | |||
| *> | |||
| *> If UPLO = 'U': | |||
| *> Only the last KB elements of IPIV are set. | |||
| *> | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) were | |||
| *> interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) < 0 and IPIV(k-1) < 0, then rows and | |||
| *> columns k and -IPIV(k) were interchanged and rows and | |||
| *> columns k-1 and -IPIV(k-1) were inerchaged, | |||
| *> D(k-1:k,k-1:k) is a 2-by-2 diagonal block. | |||
| *> | |||
| *> If UPLO = 'L': | |||
| *> Only the first KB elements of IPIV are set. | |||
| *> | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) | |||
| *> were interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) < 0 and IPIV(k+1) < 0, then rows and | |||
| *> columns k and -IPIV(k) were interchanged and rows and | |||
| *> columns k+1 and -IPIV(k+1) were inerchaged, | |||
| *> D(k:k+1,k:k+1) is a 2-by-2 diagonal block. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] W | |||
| *> \verbatim | |||
| *> W is DOUBLE PRECISION array, dimension (LDW,NB) | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDW | |||
| *> \verbatim | |||
| *> LDW is INTEGER | |||
| *> The leading dimension of the array W. LDW >= max(1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] INFO | |||
| *> \verbatim | |||
| *> INFO is INTEGER | |||
| *> = 0: successful exit | |||
| *> > 0: if INFO = k, D(k,k) is exactly zero. The factorization | |||
| *> has been completed, but the block diagonal matrix D is | |||
| *> exactly singular. | |||
| *> \endverbatim | |||
| * | |||
| * Authors: | |||
| * ======== | |||
| * | |||
| *> \author Univ. of Tennessee | |||
| *> \author Univ. of California Berkeley | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup doubleSYcomputational | |||
| * | |||
| *> \par Contributors: | |||
| * ================== | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> November 2013, Igor Kozachenko, | |||
| *> Computer Science Division, | |||
| *> University of California, Berkeley | |||
| *> | |||
| *> September 2007, Sven Hammarling, Nicholas J. Higham, Craig Lucas, | |||
| *> School of Mathematics, | |||
| *> University of Manchester | |||
| *> | |||
| *> \endverbatim | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE DLASYF_ROOK( UPLO, N, NB, KB, A, LDA, IPIV, W, LDW, | |||
| $ INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER UPLO | |||
| INTEGER INFO, KB, LDA, LDW, N, NB | |||
| * .. | |||
| * .. Array Arguments .. | |||
| INTEGER IPIV( * ) | |||
| DOUBLE PRECISION A( LDA, * ), W( LDW, * ) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| DOUBLE PRECISION ZERO, ONE | |||
| PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 ) | |||
| DOUBLE PRECISION EIGHT, SEVTEN | |||
| PARAMETER ( EIGHT = 8.0D+0, SEVTEN = 17.0D+0 ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| LOGICAL DONE | |||
| INTEGER IMAX, ITEMP, J, JB, JJ, JMAX, JP1, JP2, K, KK, | |||
| $ KW, KKW, KP, KSTEP, P, II | |||
| DOUBLE PRECISION ABSAKK, ALPHA, COLMAX, D11, D12, D21, D22, | |||
| $ DTEMP, R1, ROWMAX, T, SFMIN | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| INTEGER IDAMAX | |||
| DOUBLE PRECISION DLAMCH | |||
| EXTERNAL LSAME, IDAMAX, DLAMCH | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL DCOPY, DGEMM, DGEMV, DSCAL, DSWAP | |||
| * .. | |||
| * .. Intrinsic Functions .. | |||
| INTRINSIC ABS, MAX, MIN, SQRT | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| INFO = 0 | |||
| * | |||
| * Initialize ALPHA for use in choosing pivot block size. | |||
| * | |||
| ALPHA = ( ONE+SQRT( SEVTEN ) ) / EIGHT | |||
| * | |||
| * Compute machine safe minimum | |||
| * | |||
| SFMIN = DLAMCH( 'S' ) | |||
| * | |||
| IF( LSAME( UPLO, 'U' ) ) THEN | |||
| * | |||
| * Factorize the trailing columns of A using the upper triangle | |||
| * of A and working backwards, and compute the matrix W = U12*D | |||
| * for use in updating A11 | |||
| * | |||
| * K is the main loop index, decreasing from N in steps of 1 or 2 | |||
| * | |||
| K = N | |||
| 10 CONTINUE | |||
| * | |||
| * KW is the column of W which corresponds to column K of A | |||
| * | |||
| KW = NB + K - N | |||
| * | |||
| * Exit from loop | |||
| * | |||
| IF( ( K.LE.N-NB+1 .AND. NB.LT.N ) .OR. K.LT.1 ) | |||
| $ GO TO 30 | |||
| * | |||
| KSTEP = 1 | |||
| P = K | |||
| * | |||
| * Copy column K of A to column KW of W and update it | |||
| * | |||
| CALL DCOPY( K, A( 1, K ), 1, W( 1, KW ), 1 ) | |||
| IF( K.LT.N ) | |||
| $ CALL DGEMV( 'No transpose', K, N-K, -ONE, A( 1, K+1 ), | |||
| $ LDA, W( K, KW+1 ), LDW, ONE, W( 1, KW ), 1 ) | |||
| * | |||
| * Determine rows and columns to be interchanged and whether | |||
| * a 1-by-1 or 2-by-2 pivot block will be used | |||
| * | |||
| ABSAKK = ABS( W( K, KW ) ) | |||
| * | |||
| * IMAX is the row-index of the largest off-diagonal element in | |||
| * column K, and COLMAX is its absolute value. | |||
| * Determine both COLMAX and IMAX. | |||
| * | |||
| IF( K.GT.1 ) THEN | |||
| IMAX = IDAMAX( K-1, W( 1, KW ), 1 ) | |||
| COLMAX = ABS( W( IMAX, KW ) ) | |||
| ELSE | |||
| COLMAX = ZERO | |||
| END IF | |||
| * | |||
| IF( MAX( ABSAKK, COLMAX ).EQ.ZERO ) THEN | |||
| * | |||
| * Column K is zero or underflow: set INFO and continue | |||
| * | |||
| IF( INFO.EQ.0 ) | |||
| $ INFO = K | |||
| KP = K | |||
| CALL DCOPY( K, W( 1, KW ), 1, A( 1, K ), 1 ) | |||
| ELSE | |||
| * | |||
| * ============================================================ | |||
| * | |||
| * Test for interchange | |||
| * | |||
| * Equivalent to testing for ABSAKK.GE.ALPHA*COLMAX | |||
| * (used to handle NaN and Inf) | |||
| * | |||
| IF( .NOT.( ABSAKK.LT.ALPHA*COLMAX ) ) THEN | |||
| * | |||
| * no interchange, use 1-by-1 pivot block | |||
| * | |||
| KP = K | |||
| * | |||
| ELSE | |||
| * | |||
| DONE = .FALSE. | |||
| * | |||
| * Loop until pivot found | |||
| * | |||
| 12 CONTINUE | |||
| * | |||
| * Begin pivot search loop body | |||
| * | |||
| * | |||
| * Copy column IMAX to column KW-1 of W and update it | |||
| * | |||
| CALL DCOPY( IMAX, A( 1, IMAX ), 1, W( 1, KW-1 ), 1 ) | |||
| CALL DCOPY( K-IMAX, A( IMAX, IMAX+1 ), LDA, | |||
| $ W( IMAX+1, KW-1 ), 1 ) | |||
| * | |||
| IF( K.LT.N ) | |||
| $ CALL DGEMV( 'No transpose', K, N-K, -ONE, | |||
| $ A( 1, K+1 ), LDA, W( IMAX, KW+1 ), LDW, | |||
| $ ONE, W( 1, KW-1 ), 1 ) | |||
| * | |||
| * JMAX is the column-index of the largest off-diagonal | |||
| * element in row IMAX, and ROWMAX is its absolute value. | |||
| * Determine both ROWMAX and JMAX. | |||
| * | |||
| IF( IMAX.NE.K ) THEN | |||
| JMAX = IMAX + IDAMAX( K-IMAX, W( IMAX+1, KW-1 ), | |||
| $ 1 ) | |||
| ROWMAX = ABS( W( JMAX, KW-1 ) ) | |||
| ELSE | |||
| ROWMAX = ZERO | |||
| END IF | |||
| * | |||
| IF( IMAX.GT.1 ) THEN | |||
| ITEMP = IDAMAX( IMAX-1, W( 1, KW-1 ), 1 ) | |||
| DTEMP = ABS( W( ITEMP, KW-1 ) ) | |||
| IF( DTEMP.GT.ROWMAX ) THEN | |||
| ROWMAX = DTEMP | |||
| JMAX = ITEMP | |||
| END IF | |||
| END IF | |||
| * | |||
| * Equivalent to testing for | |||
| * ABS( W( IMAX, KW-1 ) ).GE.ALPHA*ROWMAX | |||
| * (used to handle NaN and Inf) | |||
| * | |||
| IF( .NOT.(ABS( W( IMAX, KW-1 ) ).LT.ALPHA*ROWMAX ) ) | |||
| $ THEN | |||
| * | |||
| * interchange rows and columns K and IMAX, | |||
| * use 1-by-1 pivot block | |||
| * | |||
| KP = IMAX | |||
| * | |||
| * copy column KW-1 of W to column KW of W | |||
| * | |||
| CALL DCOPY( K, W( 1, KW-1 ), 1, W( 1, KW ), 1 ) | |||
| * | |||
| DONE = .TRUE. | |||
| * | |||
| * Equivalent to testing for ROWMAX.EQ.COLMAX, | |||
| * (used to handle NaN and Inf) | |||
| * | |||
| ELSE IF( ( P.EQ.JMAX ) .OR. ( ROWMAX.LE.COLMAX ) ) | |||
| $ THEN | |||
| * | |||
| * interchange rows and columns K-1 and IMAX, | |||
| * use 2-by-2 pivot block | |||
| * | |||
| KP = IMAX | |||
| KSTEP = 2 | |||
| DONE = .TRUE. | |||
| ELSE | |||
| * | |||
| * Pivot not found: set params and repeat | |||
| * | |||
| P = IMAX | |||
| COLMAX = ROWMAX | |||
| IMAX = JMAX | |||
| * | |||
| * Copy updated JMAXth (next IMAXth) column to Kth of W | |||
| * | |||
| CALL DCOPY( K, W( 1, KW-1 ), 1, W( 1, KW ), 1 ) | |||
| * | |||
| END IF | |||
| * | |||
| * End pivot search loop body | |||
| * | |||
| IF( .NOT. DONE ) GOTO 12 | |||
| * | |||
| END IF | |||
| * | |||
| * ============================================================ | |||
| * | |||
| KK = K - KSTEP + 1 | |||
| * | |||
| * KKW is the column of W which corresponds to column KK of A | |||
| * | |||
| KKW = NB + KK - N | |||
| * | |||
| IF( ( KSTEP.EQ.2 ) .AND. ( P.NE.K ) ) THEN | |||
| * | |||
| * Copy non-updated column K to column P | |||
| * | |||
| CALL DCOPY( K-P, A( P+1, K ), 1, A( P, P+1 ), LDA ) | |||
| CALL DCOPY( P, A( 1, K ), 1, A( 1, P ), 1 ) | |||
| * | |||
| * Interchange rows K and P in last N-K+1 columns of A | |||
| * and last N-K+2 columns of W | |||
| * | |||
| CALL DSWAP( N-K+1, A( K, K ), LDA, A( P, K ), LDA ) | |||
| CALL DSWAP( N-KK+1, W( K, KKW ), LDW, W( P, KKW ), LDW ) | |||
| END IF | |||
| * | |||
| * Updated column KP is already stored in column KKW of W | |||
| * | |||
| IF( KP.NE.KK ) THEN | |||
| * | |||
| * Copy non-updated column KK to column KP | |||
| * | |||
| A( KP, K ) = A( KK, K ) | |||
| CALL DCOPY( K-1-KP, A( KP+1, KK ), 1, A( KP, KP+1 ), | |||
| $ LDA ) | |||
| CALL DCOPY( KP, A( 1, KK ), 1, A( 1, KP ), 1 ) | |||
| * | |||
| * Interchange rows KK and KP in last N-KK+1 columns | |||
| * of A and W | |||
| * | |||
| CALL DSWAP( N-KK+1, A( KK, KK ), LDA, A( KP, KK ), LDA ) | |||
| CALL DSWAP( N-KK+1, W( KK, KKW ), LDW, W( KP, KKW ), | |||
| $ LDW ) | |||
| END IF | |||
| * | |||
| IF( KSTEP.EQ.1 ) THEN | |||
| * | |||
| * 1-by-1 pivot block D(k): column KW of W now holds | |||
| * | |||
| * W(k) = U(k)*D(k) | |||
| * | |||
| * where U(k) is the k-th column of U | |||
| * | |||
| * Store U(k) in column k of A | |||
| * | |||
| CALL DCOPY( K, W( 1, KW ), 1, A( 1, K ), 1 ) | |||
| IF( K.GT.1 ) THEN | |||
| IF( ABS( A( K, K ) ).GE.SFMIN ) THEN | |||
| R1 = ONE / A( K, K ) | |||
| CALL DSCAL( K-1, R1, A( 1, K ), 1 ) | |||
| ELSE IF( A( K, K ).NE.ZERO ) THEN | |||
| DO 14 II = 1, K - 1 | |||
| A( II, K ) = A( II, K ) / A( K, K ) | |||
| 14 CONTINUE | |||
| END IF | |||
| END IF | |||
| * | |||
| ELSE | |||
| * | |||
| * 2-by-2 pivot block D(k): columns KW and KW-1 of W now | |||
| * hold | |||
| * | |||
| * ( W(k-1) W(k) ) = ( U(k-1) U(k) )*D(k) | |||
| * | |||
| * where U(k) and U(k-1) are the k-th and (k-1)-th columns | |||
| * of U | |||
| * | |||
| IF( K.GT.2 ) THEN | |||
| * | |||
| * Store U(k) and U(k-1) in columns k and k-1 of A | |||
| * | |||
| D12 = W( K-1, KW ) | |||
| D11 = W( K, KW ) / D12 | |||
| D22 = W( K-1, KW-1 ) / D12 | |||
| T = ONE / ( D11*D22-ONE ) | |||
| DO 20 J = 1, K - 2 | |||
| A( J, K-1 ) = T*( (D11*W( J, KW-1 )-W( J, KW ) ) / | |||
| $ D12 ) | |||
| A( J, K ) = T*( ( D22*W( J, KW )-W( J, KW-1 ) ) / | |||
| $ D12 ) | |||
| 20 CONTINUE | |||
| END IF | |||
| * | |||
| * Copy D(k) to A | |||
| * | |||
| A( K-1, K-1 ) = W( K-1, KW-1 ) | |||
| A( K-1, K ) = W( K-1, KW ) | |||
| A( K, K ) = W( K, KW ) | |||
| END IF | |||
| END IF | |||
| * | |||
| * Store details of the interchanges in IPIV | |||
| * | |||
| IF( KSTEP.EQ.1 ) THEN | |||
| IPIV( K ) = KP | |||
| ELSE | |||
| IPIV( K ) = -P | |||
| IPIV( K-1 ) = -KP | |||
| END IF | |||
| * | |||
| * Decrease K and return to the start of the main loop | |||
| * | |||
| K = K - KSTEP | |||
| GO TO 10 | |||
| * | |||
| 30 CONTINUE | |||
| * | |||
| * Update the upper triangle of A11 (= A(1:k,1:k)) as | |||
| * | |||
| * A11 := A11 - U12*D*U12**T = A11 - U12*W**T | |||
| * | |||
| * computing blocks of NB columns at a time | |||
| * | |||
| DO 50 J = ( ( K-1 ) / NB )*NB + 1, 1, -NB | |||
| JB = MIN( NB, K-J+1 ) | |||
| * | |||
| * Update the upper triangle of the diagonal block | |||
| * | |||
| DO 40 JJ = J, J + JB - 1 | |||
| CALL DGEMV( 'No transpose', JJ-J+1, N-K, -ONE, | |||
| $ A( J, K+1 ), LDA, W( JJ, KW+1 ), LDW, ONE, | |||
| $ A( J, JJ ), 1 ) | |||
| 40 CONTINUE | |||
| * | |||
| * Update the rectangular superdiagonal block | |||
| * | |||
| IF( J.GE.2 ) | |||
| $ CALL DGEMM( 'No transpose', 'Transpose', J-1, JB, | |||
| $ N-K, -ONE, A( 1, K+1 ), LDA, W( J, KW+1 ), LDW, | |||
| $ ONE, A( 1, J ), LDA ) | |||
| 50 CONTINUE | |||
| * | |||
| * Put U12 in standard form by partially undoing the interchanges | |||
| * in columns k+1:n | |||
| * | |||
| J = K + 1 | |||
| 60 CONTINUE | |||
| * | |||
| KSTEP = 1 | |||
| JP1 = 1 | |||
| JJ = J | |||
| JP2 = IPIV( J ) | |||
| IF( JP2.LT.0 ) THEN | |||
| JP2 = -JP2 | |||
| J = J + 1 | |||
| JP1 = -IPIV( J ) | |||
| KSTEP = 2 | |||
| END IF | |||
| * | |||
| J = J + 1 | |||
| IF( JP2.NE.JJ .AND. J.LE.N ) | |||
| $ CALL DSWAP( N-J+1, A( JP2, J ), LDA, A( JJ, J ), LDA ) | |||
| JJ = J - 1 | |||
| IF( JP1.NE.JJ .AND. KSTEP.EQ.2 ) | |||
| $ CALL DSWAP( N-J+1, A( JP1, J ), LDA, A( JJ, J ), LDA ) | |||
| IF( J.LE.N ) | |||
| $ GO TO 60 | |||
| * | |||
| * Set KB to the number of columns factorized | |||
| * | |||
| KB = N - K | |||
| * | |||
| ELSE | |||
| * | |||
| * Factorize the leading columns of A using the lower triangle | |||
| * of A and working forwards, and compute the matrix W = L21*D | |||
| * for use in updating A22 | |||
| * | |||
| * K is the main loop index, increasing from 1 in steps of 1 or 2 | |||
| * | |||
| K = 1 | |||
| 70 CONTINUE | |||
| * | |||
| * Exit from loop | |||
| * | |||
| IF( ( K.GE.NB .AND. NB.LT.N ) .OR. K.GT.N ) | |||
| $ GO TO 90 | |||
| * | |||
| KSTEP = 1 | |||
| P = K | |||
| * | |||
| * Copy column K of A to column K of W and update it | |||
| * | |||
| CALL DCOPY( N-K+1, A( K, K ), 1, W( K, K ), 1 ) | |||
| IF( K.GT.1 ) | |||
| $ CALL DGEMV( 'No transpose', N-K+1, K-1, -ONE, A( K, 1 ), | |||
| $ LDA, W( K, 1 ), LDW, ONE, W( K, K ), 1 ) | |||
| * | |||
| * Determine rows and columns to be interchanged and whether | |||
| * a 1-by-1 or 2-by-2 pivot block will be used | |||
| * | |||
| ABSAKK = ABS( W( K, K ) ) | |||
| * | |||
| * IMAX is the row-index of the largest off-diagonal element in | |||
| * column K, and COLMAX is its absolute value. | |||
| * Determine both COLMAX and IMAX. | |||
| * | |||
| IF( K.LT.N ) THEN | |||
| IMAX = K + IDAMAX( N-K, W( K+1, K ), 1 ) | |||
| COLMAX = ABS( W( IMAX, K ) ) | |||
| ELSE | |||
| COLMAX = ZERO | |||
| END IF | |||
| * | |||
| IF( MAX( ABSAKK, COLMAX ).EQ.ZERO ) THEN | |||
| * | |||
| * Column K is zero or underflow: set INFO and continue | |||
| * | |||
| IF( INFO.EQ.0 ) | |||
| $ INFO = K | |||
| KP = K | |||
| CALL DCOPY( N-K+1, W( K, K ), 1, A( K, K ), 1 ) | |||
| ELSE | |||
| * | |||
| * ============================================================ | |||
| * | |||
| * Test for interchange | |||
| * | |||
| * Equivalent to testing for ABSAKK.GE.ALPHA*COLMAX | |||
| * (used to handle NaN and Inf) | |||
| * | |||
| IF( .NOT.( ABSAKK.LT.ALPHA*COLMAX ) ) THEN | |||
| * | |||
| * no interchange, use 1-by-1 pivot block | |||
| * | |||
| KP = K | |||
| * | |||
| ELSE | |||
| * | |||
| DONE = .FALSE. | |||
| * | |||
| * Loop until pivot found | |||
| * | |||
| 72 CONTINUE | |||
| * | |||
| * Begin pivot search loop body | |||
| * | |||
| * | |||
| * Copy column IMAX to column K+1 of W and update it | |||
| * | |||
| CALL DCOPY( IMAX-K, A( IMAX, K ), LDA, W( K, K+1 ), 1) | |||
| CALL DCOPY( N-IMAX+1, A( IMAX, IMAX ), 1, | |||
| $ W( IMAX, K+1 ), 1 ) | |||
| IF( K.GT.1 ) | |||
| $ CALL DGEMV( 'No transpose', N-K+1, K-1, -ONE, | |||
| $ A( K, 1 ), LDA, W( IMAX, 1 ), LDW, | |||
| $ ONE, W( K, K+1 ), 1 ) | |||
| * | |||
| * JMAX is the column-index of the largest off-diagonal | |||
| * element in row IMAX, and ROWMAX is its absolute value. | |||
| * Determine both ROWMAX and JMAX. | |||
| * | |||
| IF( IMAX.NE.K ) THEN | |||
| JMAX = K - 1 + IDAMAX( IMAX-K, W( K, K+1 ), 1 ) | |||
| ROWMAX = ABS( W( JMAX, K+1 ) ) | |||
| ELSE | |||
| ROWMAX = ZERO | |||
| END IF | |||
| * | |||
| IF( IMAX.LT.N ) THEN | |||
| ITEMP = IMAX + IDAMAX( N-IMAX, W( IMAX+1, K+1 ), 1) | |||
| DTEMP = ABS( W( ITEMP, K+1 ) ) | |||
| IF( DTEMP.GT.ROWMAX ) THEN | |||
| ROWMAX = DTEMP | |||
| JMAX = ITEMP | |||
| END IF | |||
| END IF | |||
| * | |||
| * Equivalent to testing for | |||
| * ABS( W( IMAX, K+1 ) ).GE.ALPHA*ROWMAX | |||
| * (used to handle NaN and Inf) | |||
| * | |||
| IF( .NOT.( ABS( W( IMAX, K+1 ) ).LT.ALPHA*ROWMAX ) ) | |||
| $ THEN | |||
| * | |||
| * interchange rows and columns K and IMAX, | |||
| * use 1-by-1 pivot block | |||
| * | |||
| KP = IMAX | |||
| * | |||
| * copy column K+1 of W to column K of W | |||
| * | |||
| CALL DCOPY( N-K+1, W( K, K+1 ), 1, W( K, K ), 1 ) | |||
| * | |||
| DONE = .TRUE. | |||
| * | |||
| * Equivalent to testing for ROWMAX.EQ.COLMAX, | |||
| * (used to handle NaN and Inf) | |||
| * | |||
| ELSE IF( ( P.EQ.JMAX ) .OR. ( ROWMAX.LE.COLMAX ) ) | |||
| $ THEN | |||
| * | |||
| * interchange rows and columns K+1 and IMAX, | |||
| * use 2-by-2 pivot block | |||
| * | |||
| KP = IMAX | |||
| KSTEP = 2 | |||
| DONE = .TRUE. | |||
| ELSE | |||
| * | |||
| * Pivot not found: set params and repeat | |||
| * | |||
| P = IMAX | |||
| COLMAX = ROWMAX | |||
| IMAX = JMAX | |||
| * | |||
| * Copy updated JMAXth (next IMAXth) column to Kth of W | |||
| * | |||
| CALL DCOPY( N-K+1, W( K, K+1 ), 1, W( K, K ), 1 ) | |||
| * | |||
| END IF | |||
| * | |||
| * End pivot search loop body | |||
| * | |||
| IF( .NOT. DONE ) GOTO 72 | |||
| * | |||
| END IF | |||
| * | |||
| * ============================================================ | |||
| * | |||
| KK = K + KSTEP - 1 | |||
| * | |||
| IF( ( KSTEP.EQ.2 ) .AND. ( P.NE.K ) ) THEN | |||
| * | |||
| * Copy non-updated column K to column P | |||
| * | |||
| CALL DCOPY( P-K, A( K, K ), 1, A( P, K ), LDA ) | |||
| CALL DCOPY( N-P+1, A( P, K ), 1, A( P, P ), 1 ) | |||
| * | |||
| * Interchange rows K and P in first K columns of A | |||
| * and first K+1 columns of W | |||
| * | |||
| CALL DSWAP( K, A( K, 1 ), LDA, A( P, 1 ), LDA ) | |||
| CALL DSWAP( KK, W( K, 1 ), LDW, W( P, 1 ), LDW ) | |||
| END IF | |||
| * | |||
| * Updated column KP is already stored in column KK of W | |||
| * | |||
| IF( KP.NE.KK ) THEN | |||
| * | |||
| * Copy non-updated column KK to column KP | |||
| * | |||
| A( KP, K ) = A( KK, K ) | |||
| CALL DCOPY( KP-K-1, A( K+1, KK ), 1, A( KP, K+1 ), LDA ) | |||
| CALL DCOPY( N-KP+1, A( KP, KK ), 1, A( KP, KP ), 1 ) | |||
| * | |||
| * Interchange rows KK and KP in first KK columns of A and W | |||
| * | |||
| CALL DSWAP( KK, A( KK, 1 ), LDA, A( KP, 1 ), LDA ) | |||
| CALL DSWAP( KK, W( KK, 1 ), LDW, W( KP, 1 ), LDW ) | |||
| END IF | |||
| * | |||
| IF( KSTEP.EQ.1 ) THEN | |||
| * | |||
| * 1-by-1 pivot block D(k): column k of W now holds | |||
| * | |||
| * W(k) = L(k)*D(k) | |||
| * | |||
| * where L(k) is the k-th column of L | |||
| * | |||
| * Store L(k) in column k of A | |||
| * | |||
| CALL DCOPY( N-K+1, W( K, K ), 1, A( K, K ), 1 ) | |||
| IF( K.LT.N ) THEN | |||
| IF( ABS( A( K, K ) ).GE.SFMIN ) THEN | |||
| R1 = ONE / A( K, K ) | |||
| CALL DSCAL( N-K, R1, A( K+1, K ), 1 ) | |||
| ELSE IF( A( K, K ).NE.ZERO ) THEN | |||
| DO 74 II = K + 1, N | |||
| A( II, K ) = A( II, K ) / A( K, K ) | |||
| 74 CONTINUE | |||
| END IF | |||
| END IF | |||
| * | |||
| ELSE | |||
| * | |||
| * 2-by-2 pivot block D(k): columns k and k+1 of W now hold | |||
| * | |||
| * ( W(k) W(k+1) ) = ( L(k) L(k+1) )*D(k) | |||
| * | |||
| * where L(k) and L(k+1) are the k-th and (k+1)-th columns | |||
| * of L | |||
| * | |||
| IF( K.LT.N-1 ) THEN | |||
| * | |||
| * Store L(k) and L(k+1) in columns k and k+1 of A | |||
| * | |||
| D21 = W( K+1, K ) | |||
| D11 = W( K+1, K+1 ) / D21 | |||
| D22 = W( K, K ) / D21 | |||
| T = ONE / ( D11*D22-ONE ) | |||
| DO 80 J = K + 2, N | |||
| A( J, K ) = T*( ( D11*W( J, K )-W( J, K+1 ) ) / | |||
| $ D21 ) | |||
| A( J, K+1 ) = T*( ( D22*W( J, K+1 )-W( J, K ) ) / | |||
| $ D21 ) | |||
| 80 CONTINUE | |||
| END IF | |||
| * | |||
| * Copy D(k) to A | |||
| * | |||
| A( K, K ) = W( K, K ) | |||
| A( K+1, K ) = W( K+1, K ) | |||
| A( K+1, K+1 ) = W( K+1, K+1 ) | |||
| END IF | |||
| END IF | |||
| * | |||
| * Store details of the interchanges in IPIV | |||
| * | |||
| IF( KSTEP.EQ.1 ) THEN | |||
| IPIV( K ) = KP | |||
| ELSE | |||
| IPIV( K ) = -P | |||
| IPIV( K+1 ) = -KP | |||
| END IF | |||
| * | |||
| * Increase K and return to the start of the main loop | |||
| * | |||
| K = K + KSTEP | |||
| GO TO 70 | |||
| * | |||
| 90 CONTINUE | |||
| * | |||
| * Update the lower triangle of A22 (= A(k:n,k:n)) as | |||
| * | |||
| * A22 := A22 - L21*D*L21**T = A22 - L21*W**T | |||
| * | |||
| * computing blocks of NB columns at a time | |||
| * | |||
| DO 110 J = K, N, NB | |||
| JB = MIN( NB, N-J+1 ) | |||
| * | |||
| * Update the lower triangle of the diagonal block | |||
| * | |||
| DO 100 JJ = J, J + JB - 1 | |||
| CALL DGEMV( 'No transpose', J+JB-JJ, K-1, -ONE, | |||
| $ A( JJ, 1 ), LDA, W( JJ, 1 ), LDW, ONE, | |||
| $ A( JJ, JJ ), 1 ) | |||
| 100 CONTINUE | |||
| * | |||
| * Update the rectangular subdiagonal block | |||
| * | |||
| IF( J+JB.LE.N ) | |||
| $ CALL DGEMM( 'No transpose', 'Transpose', N-J-JB+1, JB, | |||
| $ K-1, -ONE, A( J+JB, 1 ), LDA, W( J, 1 ), LDW, | |||
| $ ONE, A( J+JB, J ), LDA ) | |||
| 110 CONTINUE | |||
| * | |||
| * Put L21 in standard form by partially undoing the interchanges | |||
| * in columns 1:k-1 | |||
| * | |||
| J = K - 1 | |||
| 120 CONTINUE | |||
| * | |||
| KSTEP = 1 | |||
| JP1 = 1 | |||
| JJ = J | |||
| JP2 = IPIV( J ) | |||
| IF( JP2.LT.0 ) THEN | |||
| JP2 = -JP2 | |||
| J = J - 1 | |||
| JP1 = -IPIV( J ) | |||
| KSTEP = 2 | |||
| END IF | |||
| * | |||
| J = J - 1 | |||
| IF( JP2.NE.JJ .AND. J.GE.1 ) | |||
| $ CALL DSWAP( J, A( JP2, 1 ), LDA, A( JJ, 1 ), LDA ) | |||
| JJ = J + 1 | |||
| IF( JP1.NE.JJ .AND. KSTEP.EQ.2 ) | |||
| $ CALL DSWAP( J, A( JP1, 1 ), LDA, A( JJ, 1 ), LDA ) | |||
| IF( J.GE.1 ) | |||
| $ GO TO 120 | |||
| * | |||
| * Set KB to the number of columns factorized | |||
| * | |||
| KB = K - 1 | |||
| * | |||
| END IF | |||
| RETURN | |||
| * | |||
| * End of DLASYF_ROOK | |||
| * | |||
| END | |||
| @@ -255,7 +255,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date November 2011 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup doubleOTHERcomputational | |||
| * | |||
| @@ -287,10 +287,10 @@ | |||
| $ X21, LDX21, X22, LDX22, THETA, PHI, TAUP1, | |||
| $ TAUP2, TAUQ1, TAUQ2, WORK, LWORK, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.0) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * November 2011 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER SIGNS, TRANS | |||
| @@ -415,19 +415,36 @@ | |||
| THETA(I) = ATAN2( DNRM2( M-P-I+1, X21(I,I), 1 ), | |||
| $ DNRM2( P-I+1, X11(I,I), 1 ) ) | |||
| * | |||
| CALL DLARFGP( P-I+1, X11(I,I), X11(I+1,I), 1, TAUP1(I) ) | |||
| IF( P .GT. I ) THEN | |||
| CALL DLARFGP( P-I+1, X11(I,I), X11(I+1,I), 1, TAUP1(I) ) | |||
| ELSE IF( P .EQ. I ) THEN | |||
| CALL DLARFGP( P-I+1, X11(I,I), X11(I,I), 1, TAUP1(I) ) | |||
| END IF | |||
| X11(I,I) = ONE | |||
| CALL DLARFGP( M-P-I+1, X21(I,I), X21(I+1,I), 1, TAUP2(I) ) | |||
| IF ( M-P .GT. I ) THEN | |||
| CALL DLARFGP( M-P-I+1, X21(I,I), X21(I+1,I), 1, | |||
| $ TAUP2(I) ) | |||
| ELSE IF ( M-P .EQ. I ) THEN | |||
| CALL DLARFGP( M-P-I+1, X21(I,I), X21(I,I), 1, TAUP2(I) ) | |||
| END IF | |||
| X21(I,I) = ONE | |||
| * | |||
| CALL DLARF( 'L', P-I+1, Q-I, X11(I,I), 1, TAUP1(I), | |||
| $ X11(I,I+1), LDX11, WORK ) | |||
| CALL DLARF( 'L', P-I+1, M-Q-I+1, X11(I,I), 1, TAUP1(I), | |||
| $ X12(I,I), LDX12, WORK ) | |||
| CALL DLARF( 'L', M-P-I+1, Q-I, X21(I,I), 1, TAUP2(I), | |||
| $ X21(I,I+1), LDX21, WORK ) | |||
| CALL DLARF( 'L', M-P-I+1, M-Q-I+1, X21(I,I), 1, TAUP2(I), | |||
| $ X22(I,I), LDX22, WORK ) | |||
| IF ( Q .GT. I ) THEN | |||
| CALL DLARF( 'L', P-I+1, Q-I, X11(I,I), 1, TAUP1(I), | |||
| $ X11(I,I+1), LDX11, WORK ) | |||
| END IF | |||
| IF ( M-Q+1 .GT. I ) THEN | |||
| CALL DLARF( 'L', P-I+1, M-Q-I+1, X11(I,I), 1, TAUP1(I), | |||
| $ X12(I,I), LDX12, WORK ) | |||
| END IF | |||
| IF ( Q .GT. I ) THEN | |||
| CALL DLARF( 'L', M-P-I+1, Q-I, X21(I,I), 1, TAUP2(I), | |||
| $ X21(I,I+1), LDX21, WORK ) | |||
| END IF | |||
| IF ( M-Q+1 .GT. I ) THEN | |||
| CALL DLARF( 'L', M-P-I+1, M-Q-I+1, X21(I,I), 1, TAUP2(I), | |||
| $ X22(I,I), LDX22, WORK ) | |||
| END IF | |||
| * | |||
| IF( I .LT. Q ) THEN | |||
| CALL DSCAL( Q-I, -Z1*Z3*SIN(THETA(I)), X11(I,I+1), | |||
| @@ -444,12 +461,24 @@ | |||
| $ DNRM2( M-Q-I+1, X12(I,I), LDX12 ) ) | |||
| * | |||
| IF( I .LT. Q ) THEN | |||
| CALL DLARFGP( Q-I, X11(I,I+1), X11(I,I+2), LDX11, | |||
| $ TAUQ1(I) ) | |||
| IF ( Q-I .EQ. 1 ) THEN | |||
| CALL DLARFGP( Q-I, X11(I,I+1), X11(I,I+1), LDX11, | |||
| $ TAUQ1(I) ) | |||
| ELSE | |||
| CALL DLARFGP( Q-I, X11(I,I+1), X11(I,I+2), LDX11, | |||
| $ TAUQ1(I) ) | |||
| END IF | |||
| X11(I,I+1) = ONE | |||
| END IF | |||
| CALL DLARFGP( M-Q-I+1, X12(I,I), X12(I,I+1), LDX12, | |||
| $ TAUQ2(I) ) | |||
| IF ( Q+I-1 .LT. M ) THEN | |||
| IF ( M-Q .EQ. I ) THEN | |||
| CALL DLARFGP( M-Q-I+1, X12(I,I), X12(I,I), LDX12, | |||
| $ TAUQ2(I) ) | |||
| ELSE | |||
| CALL DLARFGP( M-Q-I+1, X12(I,I), X12(I,I+1), LDX12, | |||
| $ TAUQ2(I) ) | |||
| END IF | |||
| END IF | |||
| X12(I,I) = ONE | |||
| * | |||
| IF( I .LT. Q ) THEN | |||
| @@ -458,10 +487,14 @@ | |||
| CALL DLARF( 'R', M-P-I, Q-I, X11(I,I+1), LDX11, TAUQ1(I), | |||
| $ X21(I+1,I+1), LDX21, WORK ) | |||
| END IF | |||
| CALL DLARF( 'R', P-I, M-Q-I+1, X12(I,I), LDX12, TAUQ2(I), | |||
| $ X12(I+1,I), LDX12, WORK ) | |||
| CALL DLARF( 'R', M-P-I, M-Q-I+1, X12(I,I), LDX12, TAUQ2(I), | |||
| $ X22(I+1,I), LDX22, WORK ) | |||
| IF ( P .GT. I ) THEN | |||
| CALL DLARF( 'R', P-I, M-Q-I+1, X12(I,I), LDX12, TAUQ2(I), | |||
| $ X12(I+1,I), LDX12, WORK ) | |||
| END IF | |||
| IF ( M-P .GT. I ) THEN | |||
| CALL DLARF( 'R', M-P-I, M-Q-I+1, X12(I,I), LDX12, | |||
| $ TAUQ2(I), X22(I+1,I), LDX22, WORK ) | |||
| END IF | |||
| * | |||
| END DO | |||
| * | |||
| @@ -470,12 +503,19 @@ | |||
| DO I = Q + 1, P | |||
| * | |||
| CALL DSCAL( M-Q-I+1, -Z1*Z4, X12(I,I), LDX12 ) | |||
| CALL DLARFGP( M-Q-I+1, X12(I,I), X12(I,I+1), LDX12, | |||
| $ TAUQ2(I) ) | |||
| IF ( I .GE. M-Q ) THEN | |||
| CALL DLARFGP( M-Q-I+1, X12(I,I), X12(I,I), LDX12, | |||
| $ TAUQ2(I) ) | |||
| ELSE | |||
| CALL DLARFGP( M-Q-I+1, X12(I,I), X12(I,I+1), LDX12, | |||
| $ TAUQ2(I) ) | |||
| END IF | |||
| X12(I,I) = ONE | |||
| * | |||
| CALL DLARF( 'R', P-I, M-Q-I+1, X12(I,I), LDX12, TAUQ2(I), | |||
| $ X12(I+1,I), LDX12, WORK ) | |||
| IF ( P. GT. I ) THEN | |||
| CALL DLARF( 'R', P-I, M-Q-I+1, X12(I,I), LDX12, TAUQ2(I), | |||
| $ X12(I+1,I), LDX12, WORK ) | |||
| END IF | |||
| IF( M-P-Q .GE. 1 ) | |||
| $ CALL DLARF( 'R', M-P-Q, M-Q-I+1, X12(I,I), LDX12, | |||
| $ TAUQ2(I), X22(Q+1,I), LDX22, WORK ) | |||
| @@ -487,11 +527,18 @@ | |||
| DO I = 1, M - P - Q | |||
| * | |||
| CALL DSCAL( M-P-Q-I+1, Z2*Z4, X22(Q+I,P+I), LDX22 ) | |||
| CALL DLARFGP( M-P-Q-I+1, X22(Q+I,P+I), X22(Q+I,P+I+1), | |||
| $ LDX22, TAUQ2(P+I) ) | |||
| IF ( I .EQ. M-P-Q ) THEN | |||
| CALL DLARFGP( M-P-Q-I+1, X22(Q+I,P+I), X22(Q+I,P+I), | |||
| $ LDX22, TAUQ2(P+I) ) | |||
| ELSE | |||
| CALL DLARFGP( M-P-Q-I+1, X22(Q+I,P+I), X22(Q+I,P+I+1), | |||
| $ LDX22, TAUQ2(P+I) ) | |||
| END IF | |||
| X22(Q+I,P+I) = ONE | |||
| CALL DLARF( 'R', M-P-Q-I, M-P-Q-I+1, X22(Q+I,P+I), LDX22, | |||
| $ TAUQ2(P+I), X22(Q+I+1,P+I), LDX22, WORK ) | |||
| IF ( I .LT. M-P-Q ) THEN | |||
| CALL DLARF( 'R', M-P-Q-I, M-P-Q-I+1, X22(Q+I,P+I), LDX22, | |||
| $ TAUQ2(P+I), X22(Q+I+1,P+I), LDX22, WORK ) | |||
| END IF | |||
| * | |||
| END DO | |||
| * | |||
| @@ -521,18 +568,31 @@ | |||
| * | |||
| CALL DLARFGP( P-I+1, X11(I,I), X11(I,I+1), LDX11, TAUP1(I) ) | |||
| X11(I,I) = ONE | |||
| CALL DLARFGP( M-P-I+1, X21(I,I), X21(I,I+1), LDX21, | |||
| IF ( I .EQ. M-P ) THEN | |||
| CALL DLARFGP( M-P-I+1, X21(I,I), X21(I,I), LDX21, | |||
| $ TAUP2(I) ) | |||
| ELSE | |||
| CALL DLARFGP( M-P-I+1, X21(I,I), X21(I,I+1), LDX21, | |||
| $ TAUP2(I) ) | |||
| END IF | |||
| X21(I,I) = ONE | |||
| * | |||
| CALL DLARF( 'R', Q-I, P-I+1, X11(I,I), LDX11, TAUP1(I), | |||
| $ X11(I+1,I), LDX11, WORK ) | |||
| CALL DLARF( 'R', M-Q-I+1, P-I+1, X11(I,I), LDX11, TAUP1(I), | |||
| $ X12(I,I), LDX12, WORK ) | |||
| CALL DLARF( 'R', Q-I, M-P-I+1, X21(I,I), LDX21, TAUP2(I), | |||
| $ X21(I+1,I), LDX21, WORK ) | |||
| CALL DLARF( 'R', M-Q-I+1, M-P-I+1, X21(I,I), LDX21, | |||
| $ TAUP2(I), X22(I,I), LDX22, WORK ) | |||
| IF ( Q .GT. I ) THEN | |||
| CALL DLARF( 'R', Q-I, P-I+1, X11(I,I), LDX11, TAUP1(I), | |||
| $ X11(I+1,I), LDX11, WORK ) | |||
| END IF | |||
| IF ( M-Q+1 .GT. I ) THEN | |||
| CALL DLARF( 'R', M-Q-I+1, P-I+1, X11(I,I), LDX11, | |||
| $ TAUP1(I), X12(I,I), LDX12, WORK ) | |||
| END IF | |||
| IF ( Q .GT. I ) THEN | |||
| CALL DLARF( 'R', Q-I, M-P-I+1, X21(I,I), LDX21, TAUP2(I), | |||
| $ X21(I+1,I), LDX21, WORK ) | |||
| END IF | |||
| IF ( M-Q+1 .GT. I ) THEN | |||
| CALL DLARF( 'R', M-Q-I+1, M-P-I+1, X21(I,I), LDX21, | |||
| $ TAUP2(I), X22(I,I), LDX22, WORK ) | |||
| END IF | |||
| * | |||
| IF( I .LT. Q ) THEN | |||
| CALL DSCAL( Q-I, -Z1*Z3*SIN(THETA(I)), X11(I+1,I), 1 ) | |||
| @@ -548,10 +608,22 @@ | |||
| $ DNRM2( M-Q-I+1, X12(I,I), 1 ) ) | |||
| * | |||
| IF( I .LT. Q ) THEN | |||
| CALL DLARFGP( Q-I, X11(I+1,I), X11(I+2,I), 1, TAUQ1(I) ) | |||
| IF ( Q-I .EQ. 1) THEN | |||
| CALL DLARFGP( Q-I, X11(I+1,I), X11(I+1,I), 1, | |||
| $ TAUQ1(I) ) | |||
| ELSE | |||
| CALL DLARFGP( Q-I, X11(I+1,I), X11(I+2,I), 1, | |||
| $ TAUQ1(I) ) | |||
| END IF | |||
| X11(I+1,I) = ONE | |||
| END IF | |||
| CALL DLARFGP( M-Q-I+1, X12(I,I), X12(I+1,I), 1, TAUQ2(I) ) | |||
| IF ( M-Q .GT. I ) THEN | |||
| CALL DLARFGP( M-Q-I+1, X12(I,I), X12(I+1,I), 1, | |||
| $ TAUQ2(I) ) | |||
| ELSE | |||
| CALL DLARFGP( M-Q-I+1, X12(I,I), X12(I,I), 1, | |||
| $ TAUQ2(I) ) | |||
| END IF | |||
| X12(I,I) = ONE | |||
| * | |||
| IF( I .LT. Q ) THEN | |||
| @@ -562,8 +634,10 @@ | |||
| END IF | |||
| CALL DLARF( 'L', M-Q-I+1, P-I, X12(I,I), 1, TAUQ2(I), | |||
| $ X12(I,I+1), LDX12, WORK ) | |||
| CALL DLARF( 'L', M-Q-I+1, M-P-I, X12(I,I), 1, TAUQ2(I), | |||
| $ X22(I,I+1), LDX22, WORK ) | |||
| IF ( M-P-I .GT. 0 ) THEN | |||
| CALL DLARF( 'L', M-Q-I+1, M-P-I, X12(I,I), 1, TAUQ2(I), | |||
| $ X22(I,I+1), LDX22, WORK ) | |||
| END IF | |||
| * | |||
| END DO | |||
| * | |||
| @@ -575,8 +649,10 @@ | |||
| CALL DLARFGP( M-Q-I+1, X12(I,I), X12(I+1,I), 1, TAUQ2(I) ) | |||
| X12(I,I) = ONE | |||
| * | |||
| CALL DLARF( 'L', M-Q-I+1, P-I, X12(I,I), 1, TAUQ2(I), | |||
| IF ( P .GT. I ) THEN | |||
| CALL DLARF( 'L', M-Q-I+1, P-I, X12(I,I), 1, TAUQ2(I), | |||
| $ X12(I,I+1), LDX12, WORK ) | |||
| END IF | |||
| IF( M-P-Q .GE. 1 ) | |||
| $ CALL DLARF( 'L', M-Q-I+1, M-P-Q, X12(I,I), 1, TAUQ2(I), | |||
| $ X22(I,Q+1), LDX22, WORK ) | |||
| @@ -588,12 +664,16 @@ | |||
| DO I = 1, M - P - Q | |||
| * | |||
| CALL DSCAL( M-P-Q-I+1, Z2*Z4, X22(P+I,Q+I), 1 ) | |||
| CALL DLARFGP( M-P-Q-I+1, X22(P+I,Q+I), X22(P+I+1,Q+I), 1, | |||
| $ TAUQ2(P+I) ) | |||
| X22(P+I,Q+I) = ONE | |||
| * | |||
| CALL DLARF( 'L', M-P-Q-I+1, M-P-Q-I, X22(P+I,Q+I), 1, | |||
| IF ( M-P-Q .EQ. I ) THEN | |||
| CALL DLARFGP( M-P-Q-I+1, X22(P+I,Q+I), X22(P+I,Q+I), 1, | |||
| $ TAUQ2(P+I) ) | |||
| ELSE | |||
| CALL DLARFGP( M-P-Q-I+1, X22(P+I,Q+I), X22(P+I+1,Q+I), 1, | |||
| $ TAUQ2(P+I) ) | |||
| CALL DLARF( 'L', M-P-Q-I+1, M-P-Q-I, X22(P+I,Q+I), 1, | |||
| $ TAUQ2(P+I), X22(P+I,Q+I+1), LDX22, WORK ) | |||
| END IF | |||
| X22(P+I,Q+I) = ONE | |||
| * | |||
| END DO | |||
| * | |||
| @@ -0,0 +1,324 @@ | |||
| *> \brief \b DORBDB1 | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download DORBDB1 + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dorbdb1.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dorbdb1.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dorbdb1.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE DORBDB1( M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI, | |||
| * TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * INTEGER INFO, LWORK, M, P, Q, LDX11, LDX21 | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * DOUBLE PRECISION PHI(*), THETA(*) | |||
| * DOUBLE PRECISION TAUP1(*), TAUP2(*), TAUQ1(*), WORK(*), | |||
| * $ X11(LDX11,*), X21(LDX21,*) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| *> ============= | |||
| *> | |||
| *>\verbatim | |||
| *> | |||
| *> DORBDB1 simultaneously bidiagonalizes the blocks of a tall and skinny | |||
| *> matrix X with orthonomal columns: | |||
| *> | |||
| *> [ B11 ] | |||
| *> [ X11 ] [ P1 | ] [ 0 ] | |||
| *> [-----] = [---------] [-----] Q1**T . | |||
| *> [ X21 ] [ | P2 ] [ B21 ] | |||
| *> [ 0 ] | |||
| *> | |||
| *> X11 is P-by-Q, and X21 is (M-P)-by-Q. Q must be no larger than P, | |||
| *> M-P, or M-Q. Routines DORBDB2, DORBDB3, and DORBDB4 handle cases in | |||
| *> which Q is not the minimum dimension. | |||
| *> | |||
| *> The orthogonal matrices P1, P2, and Q1 are P-by-P, (M-P)-by-(M-P), | |||
| *> and (M-Q)-by-(M-Q), respectively. They are represented implicitly by | |||
| *> Householder vectors. | |||
| *> | |||
| *> B11 and B12 are Q-by-Q bidiagonal matrices represented implicitly by | |||
| *> angles THETA, PHI. | |||
| *> | |||
| *>\endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] M | |||
| *> \verbatim | |||
| *> M is INTEGER | |||
| *> The number of rows X11 plus the number of rows in X21. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] P | |||
| *> \verbatim | |||
| *> P is INTEGER | |||
| *> The number of rows in X11. 0 <= P <= M. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] Q | |||
| *> \verbatim | |||
| *> Q is INTEGER | |||
| *> The number of columns in X11 and X21. 0 <= Q <= | |||
| *> MIN(P,M-P,M-Q). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X11 | |||
| *> \verbatim | |||
| *> X11 is DOUBLE PRECISION array, dimension (LDX11,Q) | |||
| *> On entry, the top block of the matrix X to be reduced. On | |||
| *> exit, the columns of tril(X11) specify reflectors for P1 and | |||
| *> the rows of triu(X11,1) specify reflectors for Q1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDX11 | |||
| *> \verbatim | |||
| *> LDX11 is INTEGER | |||
| *> The leading dimension of X11. LDX11 >= P. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X21 | |||
| *> \verbatim | |||
| *> X21 is DOUBLE PRECISION array, dimension (LDX21,Q) | |||
| *> On entry, the bottom block of the matrix X to be reduced. On | |||
| *> exit, the columns of tril(X21) specify reflectors for P2. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDX21 | |||
| *> \verbatim | |||
| *> LDX21 is INTEGER | |||
| *> The leading dimension of X21. LDX21 >= M-P. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] THETA | |||
| *> \verbatim | |||
| *> THETA is DOUBLE PRECISION array, dimension (Q) | |||
| *> The entries of the bidiagonal blocks B11, B21 are defined by | |||
| *> THETA and PHI. See Further Details. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] PHI | |||
| *> \verbatim | |||
| *> PHI is DOUBLE PRECISION array, dimension (Q-1) | |||
| *> The entries of the bidiagonal blocks B11, B21 are defined by | |||
| *> THETA and PHI. See Further Details. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] TAUP1 | |||
| *> \verbatim | |||
| *> TAUP1 is DOUBLE PRECISION array, dimension (P) | |||
| *> The scalar factors of the elementary reflectors that define | |||
| *> P1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] TAUP2 | |||
| *> \verbatim | |||
| *> TAUP2 is DOUBLE PRECISION array, dimension (M-P) | |||
| *> The scalar factors of the elementary reflectors that define | |||
| *> P2. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] TAUQ1 | |||
| *> \verbatim | |||
| *> TAUQ1 is DOUBLE PRECISION array, dimension (Q) | |||
| *> The scalar factors of the elementary reflectors that define | |||
| *> Q1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] WORK | |||
| *> \verbatim | |||
| *> WORK is DOUBLE PRECISION array, dimension (LWORK) | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LWORK | |||
| *> \verbatim | |||
| *> LWORK is INTEGER | |||
| *> The dimension of the array WORK. LWORK >= M-Q. | |||
| *> | |||
| *> 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 July 2012 | |||
| * | |||
| *> \ingroup doubleOTHERcomputational | |||
| * | |||
| *> \par Further Details: | |||
| * ===================== | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> The upper-bidiagonal blocks B11, B21 are represented implicitly by | |||
| *> angles THETA(1), ..., THETA(Q) and PHI(1), ..., PHI(Q-1). Every entry | |||
| *> in each bidiagonal band is a product of a sine or cosine of a THETA | |||
| *> with a sine or cosine of a PHI. See [1] or DORCSD for details. | |||
| *> | |||
| *> P1, P2, and Q1 are represented as products of elementary reflectors. | |||
| *> See DORCSD2BY1 for details on generating P1, P2, and Q1 using DORGQR | |||
| *> and DORGLQ. | |||
| *> \endverbatim | |||
| * | |||
| *> \par References: | |||
| * ================ | |||
| *> | |||
| *> [1] Brian D. Sutton. Computing the complete CS decomposition. Numer. | |||
| *> Algorithms, 50(1):33-65, 2009. | |||
| *> | |||
| * ===================================================================== | |||
| 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 is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * July 2012 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| INTEGER INFO, LWORK, M, P, Q, LDX11, LDX21 | |||
| * .. | |||
| * .. Array Arguments .. | |||
| DOUBLE PRECISION PHI(*), THETA(*) | |||
| DOUBLE PRECISION TAUP1(*), TAUP2(*), TAUQ1(*), WORK(*), | |||
| $ X11(LDX11,*), X21(LDX21,*) | |||
| * .. | |||
| * | |||
| * ==================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| DOUBLE PRECISION ONE | |||
| PARAMETER ( ONE = 1.0D0 ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| DOUBLE PRECISION C, S | |||
| INTEGER CHILDINFO, I, ILARF, IORBDB5, LLARF, LORBDB5, | |||
| $ LWORKMIN, LWORKOPT | |||
| LOGICAL LQUERY | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL DLARF, DLARFGP, DORBDB5, DROT, XERBLA | |||
| * .. | |||
| * .. External Functions .. | |||
| DOUBLE PRECISION DNRM2 | |||
| EXTERNAL DNRM2 | |||
| * .. | |||
| * .. Intrinsic Function .. | |||
| INTRINSIC ATAN2, COS, MAX, SIN, SQRT | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Test input arguments | |||
| * | |||
| INFO = 0 | |||
| LQUERY = LWORK .EQ. -1 | |||
| * | |||
| IF( M .LT. 0 ) THEN | |||
| INFO = -1 | |||
| ELSE IF( P .LT. Q .OR. M-P .LT. Q ) THEN | |||
| INFO = -2 | |||
| ELSE IF( Q .LT. 0 .OR. M-Q .LT. Q ) THEN | |||
| INFO = -3 | |||
| ELSE IF( LDX11 .LT. MAX( 1, P ) ) THEN | |||
| INFO = -5 | |||
| ELSE IF( LDX21 .LT. MAX( 1, M-P ) ) THEN | |||
| INFO = -7 | |||
| END IF | |||
| * | |||
| * Compute workspace | |||
| * | |||
| IF( INFO .EQ. 0 ) THEN | |||
| ILARF = 2 | |||
| LLARF = MAX( P-1, M-P-1, Q-1 ) | |||
| IORBDB5 = 2 | |||
| LORBDB5 = Q-2 | |||
| LWORKOPT = MAX( ILARF+LLARF-1, IORBDB5+LORBDB5-1 ) | |||
| LWORKMIN = LWORKOPT | |||
| WORK(1) = LWORKOPT | |||
| IF( LWORK .LT. LWORKMIN .AND. .NOT.LQUERY ) THEN | |||
| INFO = -14 | |||
| END IF | |||
| END IF | |||
| IF( INFO .NE. 0 ) THEN | |||
| CALL XERBLA( 'DORBDB1', -INFO ) | |||
| RETURN | |||
| ELSE IF( LQUERY ) THEN | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Reduce columns 1, ..., Q of X11 and X21 | |||
| * | |||
| DO I = 1, Q | |||
| * | |||
| CALL DLARFGP( P-I+1, X11(I,I), X11(I+1,I), 1, TAUP1(I) ) | |||
| CALL DLARFGP( M-P-I+1, X21(I,I), X21(I+1,I), 1, TAUP2(I) ) | |||
| THETA(I) = ATAN2( X21(I,I), X11(I,I) ) | |||
| C = COS( THETA(I) ) | |||
| S = SIN( THETA(I) ) | |||
| X11(I,I) = ONE | |||
| X21(I,I) = ONE | |||
| CALL DLARF( 'L', P-I+1, Q-I, X11(I,I), 1, TAUP1(I), X11(I,I+1), | |||
| $ LDX11, WORK(ILARF) ) | |||
| CALL DLARF( 'L', M-P-I+1, Q-I, X21(I,I), 1, TAUP2(I), | |||
| $ X21(I,I+1), LDX21, WORK(ILARF) ) | |||
| * | |||
| IF( I .LT. Q ) THEN | |||
| CALL DROT( Q-I, X11(I,I+1), LDX11, X21(I,I+1), LDX21, C, S ) | |||
| CALL DLARFGP( Q-I, X21(I,I+1), X21(I,I+2), LDX21, TAUQ1(I) ) | |||
| S = X21(I,I+1) | |||
| X21(I,I+1) = ONE | |||
| CALL DLARF( 'R', P-I, Q-I, X21(I,I+1), LDX21, TAUQ1(I), | |||
| $ 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 ) | |||
| 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, | |||
| $ X21(I+1,I+2), LDX21, WORK(IORBDB5), LORBDB5, | |||
| $ CHILDINFO ) | |||
| END IF | |||
| * | |||
| END DO | |||
| * | |||
| RETURN | |||
| * | |||
| * End of DORBDB1 | |||
| * | |||
| END | |||
| @@ -0,0 +1,333 @@ | |||
| *> \brief \b DORBDB2 | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download DORBDB2 + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dorbdb2.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dorbdb2.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dorbdb2.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE DORBDB2( M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI, | |||
| * TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * INTEGER INFO, LWORK, M, P, Q, LDX11, LDX21 | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * DOUBLE PRECISION PHI(*), THETA(*) | |||
| * DOUBLE PRECISION TAUP1(*), TAUP2(*), TAUQ1(*), WORK(*), | |||
| * $ X11(LDX11,*), X21(LDX21,*) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| *> ============= | |||
| *> | |||
| *>\verbatim | |||
| *> | |||
| *> DORBDB2 simultaneously bidiagonalizes the blocks of a tall and skinny | |||
| *> matrix X with orthonomal columns: | |||
| *> | |||
| *> [ B11 ] | |||
| *> [ X11 ] [ P1 | ] [ 0 ] | |||
| *> [-----] = [---------] [-----] Q1**T . | |||
| *> [ X21 ] [ | P2 ] [ B21 ] | |||
| *> [ 0 ] | |||
| *> | |||
| *> X11 is P-by-Q, and X21 is (M-P)-by-Q. P must be no larger than M-P, | |||
| *> Q, or M-Q. Routines DORBDB1, DORBDB3, and DORBDB4 handle cases in | |||
| *> which P is not the minimum dimension. | |||
| *> | |||
| *> The orthogonal matrices P1, P2, and Q1 are P-by-P, (M-P)-by-(M-P), | |||
| *> and (M-Q)-by-(M-Q), respectively. They are represented implicitly by | |||
| *> Householder vectors. | |||
| *> | |||
| *> B11 and B12 are P-by-P bidiagonal matrices represented implicitly by | |||
| *> angles THETA, PHI. | |||
| *> | |||
| *>\endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] M | |||
| *> \verbatim | |||
| *> M is INTEGER | |||
| *> The number of rows X11 plus the number of rows in X21. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] P | |||
| *> \verbatim | |||
| *> P is INTEGER | |||
| *> The number of rows in X11. 0 <= P <= min(M-P,Q,M-Q). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] Q | |||
| *> \verbatim | |||
| *> Q is INTEGER | |||
| *> The number of columns in X11 and X21. 0 <= Q <= M. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X11 | |||
| *> \verbatim | |||
| *> X11 is DOUBLE PRECISION array, dimension (LDX11,Q) | |||
| *> On entry, the top block of the matrix X to be reduced. On | |||
| *> exit, the columns of tril(X11) specify reflectors for P1 and | |||
| *> the rows of triu(X11,1) specify reflectors for Q1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDX11 | |||
| *> \verbatim | |||
| *> LDX11 is INTEGER | |||
| *> The leading dimension of X11. LDX11 >= P. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X21 | |||
| *> \verbatim | |||
| *> X21 is DOUBLE PRECISION array, dimension (LDX21,Q) | |||
| *> On entry, the bottom block of the matrix X to be reduced. On | |||
| *> exit, the columns of tril(X21) specify reflectors for P2. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDX21 | |||
| *> \verbatim | |||
| *> LDX21 is INTEGER | |||
| *> The leading dimension of X21. LDX21 >= M-P. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] THETA | |||
| *> \verbatim | |||
| *> THETA is DOUBLE PRECISION array, dimension (Q) | |||
| *> The entries of the bidiagonal blocks B11, B21 are defined by | |||
| *> THETA and PHI. See Further Details. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] PHI | |||
| *> \verbatim | |||
| *> PHI is DOUBLE PRECISION array, dimension (Q-1) | |||
| *> The entries of the bidiagonal blocks B11, B21 are defined by | |||
| *> THETA and PHI. See Further Details. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] TAUP1 | |||
| *> \verbatim | |||
| *> TAUP1 is DOUBLE PRECISION array, dimension (P) | |||
| *> The scalar factors of the elementary reflectors that define | |||
| *> P1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] TAUP2 | |||
| *> \verbatim | |||
| *> TAUP2 is DOUBLE PRECISION array, dimension (M-P) | |||
| *> The scalar factors of the elementary reflectors that define | |||
| *> P2. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] TAUQ1 | |||
| *> \verbatim | |||
| *> TAUQ1 is DOUBLE PRECISION array, dimension (Q) | |||
| *> The scalar factors of the elementary reflectors that define | |||
| *> Q1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] WORK | |||
| *> \verbatim | |||
| *> WORK is DOUBLE PRECISION array, dimension (LWORK) | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LWORK | |||
| *> \verbatim | |||
| *> LWORK is INTEGER | |||
| *> The dimension of the array WORK. LWORK >= M-Q. | |||
| *> | |||
| *> 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 July 2012 | |||
| * | |||
| *> \ingroup doubleOTHERcomputational | |||
| * | |||
| *> \par Further Details: | |||
| * ===================== | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> The upper-bidiagonal blocks B11, B21 are represented implicitly by | |||
| *> angles THETA(1), ..., THETA(Q) and PHI(1), ..., PHI(Q-1). Every entry | |||
| *> in each bidiagonal band is a product of a sine or cosine of a THETA | |||
| *> with a sine or cosine of a PHI. See [1] or DORCSD for details. | |||
| *> | |||
| *> P1, P2, and Q1 are represented as products of elementary reflectors. | |||
| *> See DORCSD2BY1 for details on generating P1, P2, and Q1 using DORGQR | |||
| *> and DORGLQ. | |||
| *> \endverbatim | |||
| * | |||
| *> \par References: | |||
| * ================ | |||
| *> | |||
| *> [1] Brian D. Sutton. Computing the complete CS decomposition. Numer. | |||
| *> Algorithms, 50(1):33-65, 2009. | |||
| *> | |||
| * ===================================================================== | |||
| 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 is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * July 2012 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| INTEGER INFO, LWORK, M, P, Q, LDX11, LDX21 | |||
| * .. | |||
| * .. Array Arguments .. | |||
| DOUBLE PRECISION PHI(*), THETA(*) | |||
| DOUBLE PRECISION TAUP1(*), TAUP2(*), TAUQ1(*), WORK(*), | |||
| $ X11(LDX11,*), X21(LDX21,*) | |||
| * .. | |||
| * | |||
| * ==================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| DOUBLE PRECISION NEGONE, ONE | |||
| PARAMETER ( NEGONE = -1.0D0, ONE = 1.0D0 ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| DOUBLE PRECISION C, S | |||
| INTEGER CHILDINFO, I, ILARF, IORBDB5, LLARF, LORBDB5, | |||
| $ LWORKMIN, LWORKOPT | |||
| LOGICAL LQUERY | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL DLARF, DLARFGP, DORBDB5, DROT, DSCAL, XERBLA | |||
| * .. | |||
| * .. External Functions .. | |||
| DOUBLE PRECISION DNRM2 | |||
| EXTERNAL DNRM2 | |||
| * .. | |||
| * .. Intrinsic Function .. | |||
| INTRINSIC ATAN2, COS, MAX, SIN, SQRT | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Test input arguments | |||
| * | |||
| INFO = 0 | |||
| LQUERY = LWORK .EQ. -1 | |||
| * | |||
| IF( M .LT. 0 ) THEN | |||
| INFO = -1 | |||
| ELSE IF( P .LT. 0 .OR. P .GT. M-P ) THEN | |||
| INFO = -2 | |||
| ELSE IF( Q .LT. 0 .OR. Q .LT. P .OR. M-Q .LT. P ) THEN | |||
| INFO = -3 | |||
| ELSE IF( LDX11 .LT. MAX( 1, P ) ) THEN | |||
| INFO = -5 | |||
| ELSE IF( LDX21 .LT. MAX( 1, M-P ) ) THEN | |||
| INFO = -7 | |||
| END IF | |||
| * | |||
| * Compute workspace | |||
| * | |||
| IF( INFO .EQ. 0 ) THEN | |||
| ILARF = 2 | |||
| LLARF = MAX( P-1, M-P, Q-1 ) | |||
| IORBDB5 = 2 | |||
| LORBDB5 = Q-1 | |||
| LWORKOPT = MAX( ILARF+LLARF-1, IORBDB5+LORBDB5-1 ) | |||
| LWORKMIN = LWORKOPT | |||
| WORK(1) = LWORKOPT | |||
| IF( LWORK .LT. LWORKMIN .AND. .NOT.LQUERY ) THEN | |||
| INFO = -14 | |||
| END IF | |||
| END IF | |||
| IF( INFO .NE. 0 ) THEN | |||
| CALL XERBLA( 'DORBDB2', -INFO ) | |||
| RETURN | |||
| ELSE IF( LQUERY ) THEN | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Reduce rows 1, ..., P of X11 and X21 | |||
| * | |||
| DO I = 1, P | |||
| * | |||
| IF( I .GT. 1 ) THEN | |||
| CALL DROT( Q-I+1, X11(I,I), LDX11, X21(I-1,I), LDX21, C, S ) | |||
| END IF | |||
| CALL DLARFGP( Q-I+1, X11(I,I), X11(I,I+1), LDX11, TAUQ1(I) ) | |||
| C = X11(I,I) | |||
| X11(I,I) = ONE | |||
| CALL DLARF( 'R', P-I, Q-I+1, X11(I,I), LDX11, TAUQ1(I), | |||
| $ 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 ) | |||
| THETA(I) = ATAN2( S, C ) | |||
| * | |||
| CALL DORBDB5( P-I, M-P-I+1, Q-I, X11(I+1,I), 1, X21(I,I), 1, | |||
| $ X11(I+1,I+1), LDX11, X21(I,I+1), LDX21, | |||
| $ WORK(IORBDB5), LORBDB5, CHILDINFO ) | |||
| CALL DSCAL( P-I, NEGONE, X11(I+1,I), 1 ) | |||
| CALL DLARFGP( M-P-I+1, X21(I,I), X21(I+1,I), 1, TAUP2(I) ) | |||
| IF( I .LT. P ) THEN | |||
| CALL DLARFGP( P-I, X11(I+1,I), X11(I+2,I), 1, TAUP1(I) ) | |||
| PHI(I) = ATAN2( X11(I+1,I), X21(I,I) ) | |||
| C = COS( PHI(I) ) | |||
| S = SIN( PHI(I) ) | |||
| X11(I+1,I) = ONE | |||
| CALL DLARF( 'L', P-I, Q-I, X11(I+1,I), 1, TAUP1(I), | |||
| $ X11(I+1,I+1), LDX11, WORK(ILARF) ) | |||
| END IF | |||
| X21(I,I) = ONE | |||
| CALL DLARF( 'L', M-P-I+1, Q-I, X21(I,I), 1, TAUP2(I), | |||
| $ X21(I,I+1), LDX21, WORK(ILARF) ) | |||
| * | |||
| END DO | |||
| * | |||
| * Reduce the bottom-right portion of X21 to the identity matrix | |||
| * | |||
| DO I = P + 1, Q | |||
| CALL DLARFGP( M-P-I+1, X21(I,I), X21(I+1,I), 1, TAUP2(I) ) | |||
| X21(I,I) = ONE | |||
| CALL DLARF( 'L', M-P-I+1, Q-I, X21(I,I), 1, TAUP2(I), | |||
| $ X21(I,I+1), LDX21, WORK(ILARF) ) | |||
| END DO | |||
| * | |||
| RETURN | |||
| * | |||
| * End of DORBDB2 | |||
| * | |||
| END | |||
| @@ -0,0 +1,332 @@ | |||
| *> \brief \b DORBDB3 | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download DORBDB3 + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dorbdb3.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dorbdb3.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dorbdb3.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE DORBDB3( M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI, | |||
| * TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * INTEGER INFO, LWORK, M, P, Q, LDX11, LDX21 | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * DOUBLE PRECISION PHI(*), THETA(*) | |||
| * DOUBLE PRECISION TAUP1(*), TAUP2(*), TAUQ1(*), WORK(*), | |||
| * $ X11(LDX11,*), X21(LDX21,*) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| *> ============= | |||
| *> | |||
| *>\verbatim | |||
| *> | |||
| *> DORBDB3 simultaneously bidiagonalizes the blocks of a tall and skinny | |||
| *> matrix X with orthonomal columns: | |||
| *> | |||
| *> [ B11 ] | |||
| *> [ X11 ] [ P1 | ] [ 0 ] | |||
| *> [-----] = [---------] [-----] Q1**T . | |||
| *> [ X21 ] [ | P2 ] [ B21 ] | |||
| *> [ 0 ] | |||
| *> | |||
| *> X11 is P-by-Q, and X21 is (M-P)-by-Q. M-P must be no larger than P, | |||
| *> Q, or M-Q. Routines DORBDB1, DORBDB2, and DORBDB4 handle cases in | |||
| *> which M-P is not the minimum dimension. | |||
| *> | |||
| *> The orthogonal matrices P1, P2, and Q1 are P-by-P, (M-P)-by-(M-P), | |||
| *> and (M-Q)-by-(M-Q), respectively. They are represented implicitly by | |||
| *> Householder vectors. | |||
| *> | |||
| *> B11 and B12 are (M-P)-by-(M-P) bidiagonal matrices represented | |||
| *> implicitly by angles THETA, PHI. | |||
| *> | |||
| *>\endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] M | |||
| *> \verbatim | |||
| *> M is INTEGER | |||
| *> The number of rows X11 plus the number of rows in X21. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] P | |||
| *> \verbatim | |||
| *> P is INTEGER | |||
| *> The number of rows in X11. 0 <= P <= M. M-P <= min(P,Q,M-Q). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] Q | |||
| *> \verbatim | |||
| *> Q is INTEGER | |||
| *> The number of columns in X11 and X21. 0 <= Q <= M. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X11 | |||
| *> \verbatim | |||
| *> X11 is DOUBLE PRECISION array, dimension (LDX11,Q) | |||
| *> On entry, the top block of the matrix X to be reduced. On | |||
| *> exit, the columns of tril(X11) specify reflectors for P1 and | |||
| *> the rows of triu(X11,1) specify reflectors for Q1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDX11 | |||
| *> \verbatim | |||
| *> LDX11 is INTEGER | |||
| *> The leading dimension of X11. LDX11 >= P. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X21 | |||
| *> \verbatim | |||
| *> X21 is DOUBLE PRECISION array, dimension (LDX21,Q) | |||
| *> On entry, the bottom block of the matrix X to be reduced. On | |||
| *> exit, the columns of tril(X21) specify reflectors for P2. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDX21 | |||
| *> \verbatim | |||
| *> LDX21 is INTEGER | |||
| *> The leading dimension of X21. LDX21 >= M-P. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] THETA | |||
| *> \verbatim | |||
| *> THETA is DOUBLE PRECISION array, dimension (Q) | |||
| *> The entries of the bidiagonal blocks B11, B21 are defined by | |||
| *> THETA and PHI. See Further Details. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] PHI | |||
| *> \verbatim | |||
| *> PHI is DOUBLE PRECISION array, dimension (Q-1) | |||
| *> The entries of the bidiagonal blocks B11, B21 are defined by | |||
| *> THETA and PHI. See Further Details. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] TAUP1 | |||
| *> \verbatim | |||
| *> TAUP1 is DOUBLE PRECISION array, dimension (P) | |||
| *> The scalar factors of the elementary reflectors that define | |||
| *> P1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] TAUP2 | |||
| *> \verbatim | |||
| *> TAUP2 is DOUBLE PRECISION array, dimension (M-P) | |||
| *> The scalar factors of the elementary reflectors that define | |||
| *> P2. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] TAUQ1 | |||
| *> \verbatim | |||
| *> TAUQ1 is DOUBLE PRECISION array, dimension (Q) | |||
| *> The scalar factors of the elementary reflectors that define | |||
| *> Q1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] WORK | |||
| *> \verbatim | |||
| *> WORK is DOUBLE PRECISION array, dimension (LWORK) | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LWORK | |||
| *> \verbatim | |||
| *> LWORK is INTEGER | |||
| *> The dimension of the array WORK. LWORK >= M-Q. | |||
| *> | |||
| *> 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 July 2012 | |||
| * | |||
| *> \ingroup doubleOTHERcomputational | |||
| * | |||
| *> \par Further Details: | |||
| * ===================== | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> The upper-bidiagonal blocks B11, B21 are represented implicitly by | |||
| *> angles THETA(1), ..., THETA(Q) and PHI(1), ..., PHI(Q-1). Every entry | |||
| *> in each bidiagonal band is a product of a sine or cosine of a THETA | |||
| *> with a sine or cosine of a PHI. See [1] or DORCSD for details. | |||
| *> | |||
| *> P1, P2, and Q1 are represented as products of elementary reflectors. | |||
| *> See DORCSD2BY1 for details on generating P1, P2, and Q1 using DORGQR | |||
| *> and DORGLQ. | |||
| *> \endverbatim | |||
| * | |||
| *> \par References: | |||
| * ================ | |||
| *> | |||
| *> [1] Brian D. Sutton. Computing the complete CS decomposition. Numer. | |||
| *> Algorithms, 50(1):33-65, 2009. | |||
| *> | |||
| * ===================================================================== | |||
| 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 is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * July 2012 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| INTEGER INFO, LWORK, M, P, Q, LDX11, LDX21 | |||
| * .. | |||
| * .. Array Arguments .. | |||
| DOUBLE PRECISION PHI(*), THETA(*) | |||
| DOUBLE PRECISION TAUP1(*), TAUP2(*), TAUQ1(*), WORK(*), | |||
| $ X11(LDX11,*), X21(LDX21,*) | |||
| * .. | |||
| * | |||
| * ==================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| DOUBLE PRECISION ONE | |||
| PARAMETER ( ONE = 1.0D0 ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| DOUBLE PRECISION C, S | |||
| INTEGER CHILDINFO, I, ILARF, IORBDB5, LLARF, LORBDB5, | |||
| $ LWORKMIN, LWORKOPT | |||
| LOGICAL LQUERY | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL DLARF, DLARFGP, DORBDB5, DROT, XERBLA | |||
| * .. | |||
| * .. External Functions .. | |||
| DOUBLE PRECISION DNRM2 | |||
| EXTERNAL DNRM2 | |||
| * .. | |||
| * .. Intrinsic Function .. | |||
| INTRINSIC ATAN2, COS, MAX, SIN, SQRT | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Test input arguments | |||
| * | |||
| INFO = 0 | |||
| LQUERY = LWORK .EQ. -1 | |||
| * | |||
| IF( M .LT. 0 ) THEN | |||
| INFO = -1 | |||
| ELSE IF( 2*P .LT. M .OR. P .GT. M ) THEN | |||
| INFO = -2 | |||
| ELSE IF( Q .LT. M-P .OR. M-Q .LT. M-P ) THEN | |||
| INFO = -3 | |||
| ELSE IF( LDX11 .LT. MAX( 1, P ) ) THEN | |||
| INFO = -5 | |||
| ELSE IF( LDX21 .LT. MAX( 1, M-P ) ) THEN | |||
| INFO = -7 | |||
| END IF | |||
| * | |||
| * Compute workspace | |||
| * | |||
| IF( INFO .EQ. 0 ) THEN | |||
| ILARF = 2 | |||
| LLARF = MAX( P, M-P-1, Q-1 ) | |||
| IORBDB5 = 2 | |||
| LORBDB5 = Q-1 | |||
| LWORKOPT = MAX( ILARF+LLARF-1, IORBDB5+LORBDB5-1 ) | |||
| LWORKMIN = LWORKOPT | |||
| WORK(1) = LWORKOPT | |||
| IF( LWORK .LT. LWORKMIN .AND. .NOT.LQUERY ) THEN | |||
| INFO = -14 | |||
| END IF | |||
| END IF | |||
| IF( INFO .NE. 0 ) THEN | |||
| CALL XERBLA( 'DORBDB3', -INFO ) | |||
| RETURN | |||
| ELSE IF( LQUERY ) THEN | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Reduce rows 1, ..., M-P of X11 and X21 | |||
| * | |||
| DO I = 1, M-P | |||
| * | |||
| IF( I .GT. 1 ) THEN | |||
| CALL DROT( Q-I+1, X11(I-1,I), LDX11, X21(I,I), LDX11, C, S ) | |||
| END IF | |||
| * | |||
| CALL DLARFGP( Q-I+1, X21(I,I), X21(I,I+1), LDX21, TAUQ1(I) ) | |||
| S = X21(I,I) | |||
| X21(I,I) = ONE | |||
| CALL DLARF( 'R', P-I+1, Q-I+1, X21(I,I), LDX21, TAUQ1(I), | |||
| $ 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 ) | |||
| THETA(I) = ATAN2( S, C ) | |||
| * | |||
| CALL DORBDB5( P-I+1, M-P-I, Q-I, X11(I,I), 1, X21(I+1,I), 1, | |||
| $ X11(I,I+1), LDX11, X21(I+1,I+1), LDX21, | |||
| $ WORK(IORBDB5), LORBDB5, CHILDINFO ) | |||
| CALL DLARFGP( P-I+1, X11(I,I), X11(I+1,I), 1, TAUP1(I) ) | |||
| IF( I .LT. M-P ) THEN | |||
| CALL DLARFGP( M-P-I, X21(I+1,I), X21(I+2,I), 1, TAUP2(I) ) | |||
| PHI(I) = ATAN2( X21(I+1,I), X11(I,I) ) | |||
| C = COS( PHI(I) ) | |||
| S = SIN( PHI(I) ) | |||
| X21(I+1,I) = ONE | |||
| CALL DLARF( 'L', M-P-I, Q-I, X21(I+1,I), 1, TAUP2(I), | |||
| $ X21(I+1,I+1), LDX21, WORK(ILARF) ) | |||
| END IF | |||
| X11(I,I) = ONE | |||
| CALL DLARF( 'L', P-I+1, Q-I, X11(I,I), 1, TAUP1(I), X11(I,I+1), | |||
| $ LDX11, WORK(ILARF) ) | |||
| * | |||
| END DO | |||
| * | |||
| * Reduce the bottom-right portion of X11 to the identity matrix | |||
| * | |||
| DO I = M-P + 1, Q | |||
| CALL DLARFGP( P-I+1, X11(I,I), X11(I+1,I), 1, TAUP1(I) ) | |||
| X11(I,I) = ONE | |||
| CALL DLARF( 'L', P-I+1, Q-I, X11(I,I), 1, TAUP1(I), X11(I,I+1), | |||
| $ LDX11, WORK(ILARF) ) | |||
| END DO | |||
| * | |||
| RETURN | |||
| * | |||
| * End of DORBDB3 | |||
| * | |||
| END | |||
| @@ -0,0 +1,378 @@ | |||
| *> \brief \b DORBDB4 | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download DORBDB4 + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dorbdb4.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dorbdb4.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dorbdb4.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE DORBDB4( M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI, | |||
| * TAUP1, TAUP2, TAUQ1, PHANTOM, WORK, LWORK, | |||
| * INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * INTEGER INFO, LWORK, M, P, Q, LDX11, LDX21 | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * DOUBLE PRECISION PHI(*), THETA(*) | |||
| * DOUBLE PRECISION PHANTOM(*), TAUP1(*), TAUP2(*), TAUQ1(*), | |||
| * $ WORK(*), X11(LDX11,*), X21(LDX21,*) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| *> ============= | |||
| *> | |||
| *>\verbatim | |||
| *> | |||
| *> DORBDB4 simultaneously bidiagonalizes the blocks of a tall and skinny | |||
| *> matrix X with orthonomal columns: | |||
| *> | |||
| *> [ B11 ] | |||
| *> [ X11 ] [ P1 | ] [ 0 ] | |||
| *> [-----] = [---------] [-----] Q1**T . | |||
| *> [ X21 ] [ | P2 ] [ B21 ] | |||
| *> [ 0 ] | |||
| *> | |||
| *> X11 is P-by-Q, and X21 is (M-P)-by-Q. M-Q must be no larger than P, | |||
| *> M-P, or Q. Routines DORBDB1, DORBDB2, and DORBDB3 handle cases in | |||
| *> which M-Q is not the minimum dimension. | |||
| *> | |||
| *> The orthogonal matrices P1, P2, and Q1 are P-by-P, (M-P)-by-(M-P), | |||
| *> and (M-Q)-by-(M-Q), respectively. They are represented implicitly by | |||
| *> Householder vectors. | |||
| *> | |||
| *> B11 and B12 are (M-Q)-by-(M-Q) bidiagonal matrices represented | |||
| *> implicitly by angles THETA, PHI. | |||
| *> | |||
| *>\endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] M | |||
| *> \verbatim | |||
| *> M is INTEGER | |||
| *> The number of rows X11 plus the number of rows in X21. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] P | |||
| *> \verbatim | |||
| *> P is INTEGER | |||
| *> The number of rows in X11. 0 <= P <= M. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] Q | |||
| *> \verbatim | |||
| *> Q is INTEGER | |||
| *> The number of columns in X11 and X21. 0 <= Q <= M and | |||
| *> M-Q <= min(P,M-P,Q). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X11 | |||
| *> \verbatim | |||
| *> X11 is DOUBLE PRECISION array, dimension (LDX11,Q) | |||
| *> On entry, the top block of the matrix X to be reduced. On | |||
| *> exit, the columns of tril(X11) specify reflectors for P1 and | |||
| *> the rows of triu(X11,1) specify reflectors for Q1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDX11 | |||
| *> \verbatim | |||
| *> LDX11 is INTEGER | |||
| *> The leading dimension of X11. LDX11 >= P. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X21 | |||
| *> \verbatim | |||
| *> X21 is DOUBLE PRECISION array, dimension (LDX21,Q) | |||
| *> On entry, the bottom block of the matrix X to be reduced. On | |||
| *> exit, the columns of tril(X21) specify reflectors for P2. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDX21 | |||
| *> \verbatim | |||
| *> LDX21 is INTEGER | |||
| *> The leading dimension of X21. LDX21 >= M-P. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] THETA | |||
| *> \verbatim | |||
| *> THETA is DOUBLE PRECISION array, dimension (Q) | |||
| *> The entries of the bidiagonal blocks B11, B21 are defined by | |||
| *> THETA and PHI. See Further Details. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] PHI | |||
| *> \verbatim | |||
| *> PHI is DOUBLE PRECISION array, dimension (Q-1) | |||
| *> The entries of the bidiagonal blocks B11, B21 are defined by | |||
| *> THETA and PHI. See Further Details. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] TAUP1 | |||
| *> \verbatim | |||
| *> TAUP1 is DOUBLE PRECISION array, dimension (P) | |||
| *> The scalar factors of the elementary reflectors that define | |||
| *> P1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] TAUP2 | |||
| *> \verbatim | |||
| *> TAUP2 is DOUBLE PRECISION array, dimension (M-P) | |||
| *> The scalar factors of the elementary reflectors that define | |||
| *> P2. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] TAUQ1 | |||
| *> \verbatim | |||
| *> TAUQ1 is DOUBLE PRECISION array, dimension (Q) | |||
| *> The scalar factors of the elementary reflectors that define | |||
| *> Q1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] PHANTOM | |||
| *> \verbatim | |||
| *> PHANTOM is DOUBLE PRECISION array, dimension (M) | |||
| *> The routine computes an M-by-1 column vector Y that is | |||
| *> orthogonal to the columns of [ X11; X21 ]. PHANTOM(1:P) and | |||
| *> PHANTOM(P+1:M) contain Householder vectors for Y(1:P) and | |||
| *> Y(P+1:M), respectively. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] WORK | |||
| *> \verbatim | |||
| *> WORK is DOUBLE PRECISION array, dimension (LWORK) | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LWORK | |||
| *> \verbatim | |||
| *> LWORK is INTEGER | |||
| *> The dimension of the array WORK. LWORK >= M-Q. | |||
| *> | |||
| *> 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 July 2012 | |||
| * | |||
| *> \ingroup doubleOTHERcomputational | |||
| * | |||
| *> \par Further Details: | |||
| * ===================== | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> The upper-bidiagonal blocks B11, B21 are represented implicitly by | |||
| *> angles THETA(1), ..., THETA(Q) and PHI(1), ..., PHI(Q-1). Every entry | |||
| *> in each bidiagonal band is a product of a sine or cosine of a THETA | |||
| *> with a sine or cosine of a PHI. See [1] or DORCSD for details. | |||
| *> | |||
| *> P1, P2, and Q1 are represented as products of elementary reflectors. | |||
| *> See DORCSD2BY1 for details on generating P1, P2, and Q1 using DORGQR | |||
| *> and DORGLQ. | |||
| *> \endverbatim | |||
| * | |||
| *> \par References: | |||
| * ================ | |||
| *> | |||
| *> [1] Brian D. Sutton. Computing the complete CS decomposition. Numer. | |||
| *> Algorithms, 50(1):33-65, 2009. | |||
| *> | |||
| * ===================================================================== | |||
| SUBROUTINE DORBDB4( M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI, | |||
| $ TAUP1, TAUP2, TAUQ1, PHANTOM, WORK, LWORK, | |||
| $ INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * July 2012 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| INTEGER INFO, LWORK, M, P, Q, LDX11, LDX21 | |||
| * .. | |||
| * .. Array Arguments .. | |||
| DOUBLE PRECISION PHI(*), THETA(*) | |||
| DOUBLE PRECISION PHANTOM(*), TAUP1(*), TAUP2(*), TAUQ1(*), | |||
| $ WORK(*), X11(LDX11,*), X21(LDX21,*) | |||
| * .. | |||
| * | |||
| * ==================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| DOUBLE PRECISION NEGONE, ONE, ZERO | |||
| PARAMETER ( NEGONE = -1.0D0, ONE = 1.0D0, ZERO = 0.0D0 ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| DOUBLE PRECISION C, S | |||
| INTEGER CHILDINFO, I, ILARF, IORBDB5, J, LLARF, | |||
| $ LORBDB5, LWORKMIN, LWORKOPT | |||
| LOGICAL LQUERY | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL DLARF, DLARFGP, DORBDB5, DROT, DSCAL, XERBLA | |||
| * .. | |||
| * .. External Functions .. | |||
| DOUBLE PRECISION DNRM2 | |||
| EXTERNAL DNRM2 | |||
| * .. | |||
| * .. Intrinsic Function .. | |||
| INTRINSIC ATAN2, COS, MAX, SIN, SQRT | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Test input arguments | |||
| * | |||
| INFO = 0 | |||
| LQUERY = LWORK .EQ. -1 | |||
| * | |||
| IF( M .LT. 0 ) THEN | |||
| INFO = -1 | |||
| ELSE IF( P .LT. M-Q .OR. M-P .LT. M-Q ) THEN | |||
| INFO = -2 | |||
| ELSE IF( Q .LT. M-Q .OR. Q .GT. M ) THEN | |||
| INFO = -3 | |||
| ELSE IF( LDX11 .LT. MAX( 1, P ) ) THEN | |||
| INFO = -5 | |||
| ELSE IF( LDX21 .LT. MAX( 1, M-P ) ) THEN | |||
| INFO = -7 | |||
| END IF | |||
| * | |||
| * Compute workspace | |||
| * | |||
| IF( INFO .EQ. 0 ) THEN | |||
| ILARF = 2 | |||
| LLARF = MAX( Q-1, P-1, M-P-1 ) | |||
| IORBDB5 = 2 | |||
| LORBDB5 = Q | |||
| LWORKOPT = ILARF + LLARF - 1 | |||
| LWORKOPT = MAX( LWORKOPT, IORBDB5 + LORBDB5 - 1 ) | |||
| LWORKMIN = LWORKOPT | |||
| WORK(1) = LWORKOPT | |||
| IF( LWORK .LT. LWORKMIN .AND. .NOT.LQUERY ) THEN | |||
| INFO = -14 | |||
| END IF | |||
| END IF | |||
| IF( INFO .NE. 0 ) THEN | |||
| CALL XERBLA( 'DORBDB4', -INFO ) | |||
| RETURN | |||
| ELSE IF( LQUERY ) THEN | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Reduce columns 1, ..., M-Q of X11 and X21 | |||
| * | |||
| DO I = 1, M-Q | |||
| * | |||
| IF( I .EQ. 1 ) THEN | |||
| DO J = 1, M | |||
| PHANTOM(J) = ZERO | |||
| END DO | |||
| CALL DORBDB5( P, M-P, Q, PHANTOM(1), 1, PHANTOM(P+1), 1, | |||
| $ X11, LDX11, X21, LDX21, WORK(IORBDB5), | |||
| $ LORBDB5, CHILDINFO ) | |||
| CALL DSCAL( P, NEGONE, PHANTOM(1), 1 ) | |||
| CALL DLARFGP( P, PHANTOM(1), PHANTOM(2), 1, TAUP1(1) ) | |||
| CALL DLARFGP( M-P, PHANTOM(P+1), PHANTOM(P+2), 1, TAUP2(1) ) | |||
| THETA(I) = ATAN2( PHANTOM(1), PHANTOM(P+1) ) | |||
| C = COS( THETA(I) ) | |||
| S = SIN( THETA(I) ) | |||
| PHANTOM(1) = ONE | |||
| PHANTOM(P+1) = ONE | |||
| CALL DLARF( 'L', P, Q, PHANTOM(1), 1, TAUP1(1), X11, LDX11, | |||
| $ WORK(ILARF) ) | |||
| CALL DLARF( 'L', M-P, Q, PHANTOM(P+1), 1, TAUP2(1), X21, | |||
| $ LDX21, WORK(ILARF) ) | |||
| ELSE | |||
| CALL DORBDB5( P-I+1, M-P-I+1, Q-I+1, X11(I,I-1), 1, | |||
| $ X21(I,I-1), 1, X11(I,I), LDX11, X21(I,I), | |||
| $ LDX21, WORK(IORBDB5), LORBDB5, CHILDINFO ) | |||
| CALL DSCAL( P-I+1, NEGONE, X11(I,I-1), 1 ) | |||
| CALL DLARFGP( P-I+1, X11(I,I-1), X11(I+1,I-1), 1, TAUP1(I) ) | |||
| CALL DLARFGP( M-P-I+1, X21(I,I-1), X21(I+1,I-1), 1, | |||
| $ TAUP2(I) ) | |||
| THETA(I) = ATAN2( X11(I,I-1), X21(I,I-1) ) | |||
| C = COS( THETA(I) ) | |||
| S = SIN( THETA(I) ) | |||
| X11(I,I-1) = ONE | |||
| X21(I,I-1) = ONE | |||
| CALL DLARF( 'L', P-I+1, Q-I+1, X11(I,I-1), 1, TAUP1(I), | |||
| $ X11(I,I), LDX11, WORK(ILARF) ) | |||
| CALL DLARF( 'L', M-P-I+1, Q-I+1, X21(I,I-1), 1, TAUP2(I), | |||
| $ X21(I,I), LDX21, WORK(ILARF) ) | |||
| END IF | |||
| * | |||
| CALL DROT( Q-I+1, X11(I,I), LDX11, X21(I,I), LDX21, S, -C ) | |||
| CALL DLARFGP( Q-I+1, X21(I,I), X21(I,I+1), LDX21, TAUQ1(I) ) | |||
| C = X21(I,I) | |||
| X21(I,I) = ONE | |||
| CALL DLARF( 'R', P-I, Q-I+1, X21(I,I), LDX21, TAUQ1(I), | |||
| $ X11(I+1,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) ) | |||
| 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 ) | |||
| PHI(I) = ATAN2( S, C ) | |||
| END IF | |||
| * | |||
| END DO | |||
| * | |||
| * Reduce the bottom-right portion of X11 to [ I 0 ] | |||
| * | |||
| DO I = M - Q + 1, P | |||
| CALL DLARFGP( Q-I+1, X11(I,I), X11(I,I+1), LDX11, TAUQ1(I) ) | |||
| X11(I,I) = ONE | |||
| CALL DLARF( 'R', P-I, Q-I+1, X11(I,I), LDX11, TAUQ1(I), | |||
| $ X11(I+1,I), LDX11, WORK(ILARF) ) | |||
| CALL DLARF( 'R', Q-P, Q-I+1, X11(I,I), LDX11, TAUQ1(I), | |||
| $ X21(M-Q+1,I), LDX21, WORK(ILARF) ) | |||
| END DO | |||
| * | |||
| * Reduce the bottom-right portion of X21 to [ 0 I ] | |||
| * | |||
| DO I = P + 1, Q | |||
| CALL DLARFGP( Q-I+1, X21(M-Q+I-P,I), X21(M-Q+I-P,I+1), LDX21, | |||
| $ TAUQ1(I) ) | |||
| X21(M-Q+I-P,I) = ONE | |||
| CALL DLARF( 'R', Q-I, Q-I+1, X21(M-Q+I-P,I), LDX21, TAUQ1(I), | |||
| $ X21(M-Q+I-P+1,I), LDX21, WORK(ILARF) ) | |||
| END DO | |||
| * | |||
| RETURN | |||
| * | |||
| * End of DORBDB4 | |||
| * | |||
| END | |||
| @@ -0,0 +1,274 @@ | |||
| *> \brief \b DORBDB5 | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download DORBDB5 + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dorbdb5.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dorbdb5.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dorbdb5.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE DORBDB5( M1, M2, N, X1, INCX1, X2, INCX2, Q1, LDQ1, Q2, | |||
| * LDQ2, WORK, LWORK, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * INTEGER INCX1, INCX2, INFO, LDQ1, LDQ2, LWORK, M1, M2, | |||
| * $ N | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * DOUBLE PRECISION Q1(LDQ1,*), Q2(LDQ2,*), WORK(*), X1(*), X2(*) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| *> ============= | |||
| *> | |||
| *>\verbatim | |||
| *> | |||
| *> DORBDB5 orthogonalizes the column vector | |||
| *> X = [ X1 ] | |||
| *> [ X2 ] | |||
| *> with respect to the columns of | |||
| *> Q = [ Q1 ] . | |||
| *> [ Q2 ] | |||
| *> The columns of Q must be orthonormal. | |||
| *> | |||
| *> If the projection is zero according to Kahan's "twice is enough" | |||
| *> criterion, then some other vector from the orthogonal complement | |||
| *> is returned. This vector is chosen in an arbitrary but deterministic | |||
| *> way. | |||
| *> | |||
| *>\endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] M1 | |||
| *> \verbatim | |||
| *> M1 is INTEGER | |||
| *> The dimension of X1 and the number of rows in Q1. 0 <= M1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] M2 | |||
| *> \verbatim | |||
| *> M2 is INTEGER | |||
| *> The dimension of X2 and the number of rows in Q2. 0 <= M2. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] N | |||
| *> \verbatim | |||
| *> N is INTEGER | |||
| *> The number of columns in Q1 and Q2. 0 <= N. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X1 | |||
| *> \verbatim | |||
| *> X1 is DOUBLE PRECISION array, dimension (M1) | |||
| *> On entry, the top part of the vector to be orthogonalized. | |||
| *> On exit, the top part of the projected vector. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] INCX1 | |||
| *> \verbatim | |||
| *> INCX1 is INTEGER | |||
| *> Increment for entries of X1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X2 | |||
| *> \verbatim | |||
| *> X2 is DOUBLE PRECISION array, dimension (M2) | |||
| *> On entry, the bottom part of the vector to be | |||
| *> orthogonalized. On exit, the bottom part of the projected | |||
| *> vector. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] INCX2 | |||
| *> \verbatim | |||
| *> INCX2 is INTEGER | |||
| *> Increment for entries of X2. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] Q1 | |||
| *> \verbatim | |||
| *> Q1 is DOUBLE PRECISION array, dimension (LDQ1, N) | |||
| *> The top part of the orthonormal basis matrix. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDQ1 | |||
| *> \verbatim | |||
| *> LDQ1 is INTEGER | |||
| *> The leading dimension of Q1. LDQ1 >= M1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] Q2 | |||
| *> \verbatim | |||
| *> Q2 is DOUBLE PRECISION array, dimension (LDQ2, N) | |||
| *> The bottom part of the orthonormal basis matrix. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDQ2 | |||
| *> \verbatim | |||
| *> LDQ2 is INTEGER | |||
| *> The leading dimension of Q2. LDQ2 >= M2. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] WORK | |||
| *> \verbatim | |||
| *> WORK is DOUBLE PRECISION array, dimension (LWORK) | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LWORK | |||
| *> \verbatim | |||
| *> LWORK is INTEGER | |||
| *> The dimension of the array WORK. LWORK >= N. | |||
| *> \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 July 2012 | |||
| * | |||
| *> \ingroup doubleOTHERcomputational | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE DORBDB5( M1, M2, N, X1, INCX1, X2, INCX2, Q1, LDQ1, Q2, | |||
| $ LDQ2, WORK, LWORK, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * July 2012 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| INTEGER INCX1, INCX2, INFO, LDQ1, LDQ2, LWORK, M1, M2, | |||
| $ N | |||
| * .. | |||
| * .. Array Arguments .. | |||
| DOUBLE PRECISION Q1(LDQ1,*), Q2(LDQ2,*), WORK(*), X1(*), X2(*) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| DOUBLE PRECISION ONE, ZERO | |||
| PARAMETER ( ONE = 1.0D0, ZERO = 0.0D0 ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| INTEGER CHILDINFO, I, J | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL DORBDB6, XERBLA | |||
| * .. | |||
| * .. External Functions .. | |||
| DOUBLE PRECISION DNRM2 | |||
| EXTERNAL DNRM2 | |||
| * .. | |||
| * .. Intrinsic Function .. | |||
| INTRINSIC MAX | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Test input arguments | |||
| * | |||
| INFO = 0 | |||
| IF( M1 .LT. 0 ) THEN | |||
| INFO = -1 | |||
| ELSE IF( M2 .LT. 0 ) THEN | |||
| INFO = -2 | |||
| ELSE IF( N .LT. 0 ) THEN | |||
| INFO = -3 | |||
| ELSE IF( INCX1 .LT. 1 ) THEN | |||
| INFO = -5 | |||
| ELSE IF( INCX2 .LT. 1 ) THEN | |||
| INFO = -7 | |||
| ELSE IF( LDQ1 .LT. MAX( 1, M1 ) ) THEN | |||
| INFO = -9 | |||
| ELSE IF( LDQ2 .LT. MAX( 1, M2 ) ) THEN | |||
| INFO = -11 | |||
| ELSE IF( LWORK .LT. N ) THEN | |||
| INFO = -13 | |||
| END IF | |||
| * | |||
| IF( INFO .NE. 0 ) THEN | |||
| CALL XERBLA( 'DORBDB5', -INFO ) | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Project X onto the orthogonal complement of Q | |||
| * | |||
| CALL DORBDB6( M1, M2, N, X1, INCX1, X2, INCX2, Q1, LDQ1, Q2, LDQ2, | |||
| $ WORK, LWORK, CHILDINFO ) | |||
| * | |||
| * If the projection is nonzero, then return | |||
| * | |||
| IF( DNRM2(M1,X1,INCX1) .NE. ZERO | |||
| $ .OR. DNRM2(M2,X2,INCX2) .NE. ZERO ) THEN | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Project each standard basis vector e_1,...,e_M1 in turn, stopping | |||
| * when a nonzero projection is found | |||
| * | |||
| DO I = 1, M1 | |||
| DO J = 1, M1 | |||
| X1(J) = ZERO | |||
| END DO | |||
| X1(I) = ONE | |||
| DO J = 1, M2 | |||
| X2(J) = ZERO | |||
| END DO | |||
| CALL DORBDB6( M1, M2, N, X1, INCX1, X2, INCX2, Q1, LDQ1, Q2, | |||
| $ LDQ2, WORK, LWORK, CHILDINFO ) | |||
| IF( DNRM2(M1,X1,INCX1) .NE. ZERO | |||
| $ .OR. DNRM2(M2,X2,INCX2) .NE. ZERO ) THEN | |||
| RETURN | |||
| END IF | |||
| END DO | |||
| * | |||
| * Project each standard basis vector e_(M1+1),...,e_(M1+M2) in turn, | |||
| * stopping when a nonzero projection is found | |||
| * | |||
| DO I = 1, M2 | |||
| DO J = 1, M1 | |||
| X1(J) = ZERO | |||
| END DO | |||
| DO J = 1, M2 | |||
| X2(J) = ZERO | |||
| END DO | |||
| X2(I) = ONE | |||
| CALL DORBDB6( M1, M2, N, X1, INCX1, X2, INCX2, Q1, LDQ1, Q2, | |||
| $ LDQ2, WORK, LWORK, CHILDINFO ) | |||
| IF( DNRM2(M1,X1,INCX1) .NE. ZERO | |||
| $ .OR. DNRM2(M2,X2,INCX2) .NE. ZERO ) THEN | |||
| RETURN | |||
| END IF | |||
| END DO | |||
| * | |||
| RETURN | |||
| * | |||
| * End of DORBDB5 | |||
| * | |||
| END | |||
| @@ -0,0 +1,312 @@ | |||
| *> \brief \b DORBDB6 | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download DORBDB6 + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dorbdb6.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dorbdb6.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dorbdb6.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE DORBDB6( M1, M2, N, X1, INCX1, X2, INCX2, Q1, LDQ1, Q2, | |||
| * LDQ2, WORK, LWORK, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * INTEGER INCX1, INCX2, INFO, LDQ1, LDQ2, LWORK, M1, M2, | |||
| * $ N | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * DOUBLE PRECISION Q1(LDQ1,*), Q2(LDQ2,*), WORK(*), X1(*), X2(*) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| *> ============= | |||
| *> | |||
| *>\verbatim | |||
| *> | |||
| *> DORBDB6 orthogonalizes the column vector | |||
| *> X = [ X1 ] | |||
| *> [ X2 ] | |||
| *> with respect to the columns of | |||
| *> Q = [ Q1 ] . | |||
| *> [ Q2 ] | |||
| *> The columns of Q must be orthonormal. | |||
| *> | |||
| *> If the projection is zero according to Kahan's "twice is enough" | |||
| *> criterion, then the zero vector is returned. | |||
| *> | |||
| *>\endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] M1 | |||
| *> \verbatim | |||
| *> M1 is INTEGER | |||
| *> The dimension of X1 and the number of rows in Q1. 0 <= M1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] M2 | |||
| *> \verbatim | |||
| *> M2 is INTEGER | |||
| *> The dimension of X2 and the number of rows in Q2. 0 <= M2. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] N | |||
| *> \verbatim | |||
| *> N is INTEGER | |||
| *> The number of columns in Q1 and Q2. 0 <= N. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X1 | |||
| *> \verbatim | |||
| *> X1 is DOUBLE PRECISION array, dimension (M1) | |||
| *> On entry, the top part of the vector to be orthogonalized. | |||
| *> On exit, the top part of the projected vector. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] INCX1 | |||
| *> \verbatim | |||
| *> INCX1 is INTEGER | |||
| *> Increment for entries of X1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X2 | |||
| *> \verbatim | |||
| *> X2 is DOUBLE PRECISION array, dimension (M2) | |||
| *> On entry, the bottom part of the vector to be | |||
| *> orthogonalized. On exit, the bottom part of the projected | |||
| *> vector. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] INCX2 | |||
| *> \verbatim | |||
| *> INCX2 is INTEGER | |||
| *> Increment for entries of X2. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] Q1 | |||
| *> \verbatim | |||
| *> Q1 is DOUBLE PRECISION array, dimension (LDQ1, N) | |||
| *> The top part of the orthonormal basis matrix. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDQ1 | |||
| *> \verbatim | |||
| *> LDQ1 is INTEGER | |||
| *> The leading dimension of Q1. LDQ1 >= M1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] Q2 | |||
| *> \verbatim | |||
| *> Q2 is DOUBLE PRECISION array, dimension (LDQ2, N) | |||
| *> The bottom part of the orthonormal basis matrix. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDQ2 | |||
| *> \verbatim | |||
| *> LDQ2 is INTEGER | |||
| *> The leading dimension of Q2. LDQ2 >= M2. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] WORK | |||
| *> \verbatim | |||
| *> WORK is DOUBLE PRECISION array, dimension (LWORK) | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LWORK | |||
| *> \verbatim | |||
| *> LWORK is INTEGER | |||
| *> The dimension of the array WORK. LWORK >= N. | |||
| *> \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 July 2012 | |||
| * | |||
| *> \ingroup doubleOTHERcomputational | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE DORBDB6( M1, M2, N, X1, INCX1, X2, INCX2, Q1, LDQ1, Q2, | |||
| $ LDQ2, WORK, LWORK, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * July 2012 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| INTEGER INCX1, INCX2, INFO, LDQ1, LDQ2, LWORK, M1, M2, | |||
| $ N | |||
| * .. | |||
| * .. Array Arguments .. | |||
| DOUBLE PRECISION Q1(LDQ1,*), Q2(LDQ2,*), WORK(*), X1(*), X2(*) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| DOUBLE PRECISION ALPHASQ, REALONE, REALZERO | |||
| PARAMETER ( ALPHASQ = 0.01D0, REALONE = 1.0D0, | |||
| $ REALZERO = 0.0D0 ) | |||
| DOUBLE PRECISION NEGONE, ONE, ZERO | |||
| PARAMETER ( NEGONE = -1.0D0, ONE = 1.0D0, ZERO = 0.0D0 ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| INTEGER I | |||
| DOUBLE PRECISION NORMSQ1, NORMSQ2, SCL1, SCL2, SSQ1, SSQ2 | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL DGEMV, DLASSQ, XERBLA | |||
| * .. | |||
| * .. Intrinsic Function .. | |||
| INTRINSIC MAX | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Test input arguments | |||
| * | |||
| INFO = 0 | |||
| IF( M1 .LT. 0 ) THEN | |||
| INFO = -1 | |||
| ELSE IF( M2 .LT. 0 ) THEN | |||
| INFO = -2 | |||
| ELSE IF( N .LT. 0 ) THEN | |||
| INFO = -3 | |||
| ELSE IF( INCX1 .LT. 1 ) THEN | |||
| INFO = -5 | |||
| ELSE IF( INCX2 .LT. 1 ) THEN | |||
| INFO = -7 | |||
| ELSE IF( LDQ1 .LT. MAX( 1, M1 ) ) THEN | |||
| INFO = -9 | |||
| ELSE IF( LDQ2 .LT. MAX( 1, M2 ) ) THEN | |||
| INFO = -11 | |||
| ELSE IF( LWORK .LT. N ) THEN | |||
| INFO = -13 | |||
| END IF | |||
| * | |||
| IF( INFO .NE. 0 ) THEN | |||
| CALL XERBLA( 'DORBDB6', -INFO ) | |||
| RETURN | |||
| END IF | |||
| * | |||
| * First, project X onto the orthogonal complement of Q's column | |||
| * space | |||
| * | |||
| SCL1 = REALZERO | |||
| SSQ1 = REALONE | |||
| CALL DLASSQ( M1, X1, INCX1, SCL1, SSQ1 ) | |||
| SCL2 = REALZERO | |||
| SSQ2 = REALONE | |||
| CALL DLASSQ( M2, X2, INCX2, SCL2, SSQ2 ) | |||
| NORMSQ1 = SCL1**2*SSQ1 + SCL2**2*SSQ2 | |||
| * | |||
| IF( M1 .EQ. 0 ) THEN | |||
| DO I = 1, N | |||
| WORK(I) = ZERO | |||
| END DO | |||
| ELSE | |||
| CALL DGEMV( 'C', M1, N, ONE, Q1, LDQ1, X1, INCX1, ZERO, WORK, | |||
| $ 1 ) | |||
| END IF | |||
| * | |||
| CALL DGEMV( 'C', M2, N, ONE, Q2, LDQ2, X2, INCX2, ONE, WORK, 1 ) | |||
| * | |||
| CALL DGEMV( 'N', M1, N, NEGONE, Q1, LDQ1, WORK, 1, ONE, X1, | |||
| $ INCX1 ) | |||
| CALL DGEMV( 'N', M2, N, NEGONE, Q2, LDQ2, WORK, 1, ONE, X2, | |||
| $ INCX2 ) | |||
| * | |||
| SCL1 = REALZERO | |||
| SSQ1 = REALONE | |||
| CALL DLASSQ( M1, X1, INCX1, SCL1, SSQ1 ) | |||
| SCL2 = REALZERO | |||
| SSQ2 = REALONE | |||
| CALL DLASSQ( M2, X2, INCX2, SCL2, SSQ2 ) | |||
| NORMSQ2 = SCL1**2*SSQ1 + SCL2**2*SSQ2 | |||
| * | |||
| * If projection is sufficiently large in norm, then stop. | |||
| * If projection is zero, then stop. | |||
| * Otherwise, project again. | |||
| * | |||
| IF( NORMSQ2 .GE. ALPHASQ*NORMSQ1 ) THEN | |||
| RETURN | |||
| END IF | |||
| * | |||
| IF( NORMSQ2 .EQ. ZERO ) THEN | |||
| RETURN | |||
| END IF | |||
| * | |||
| NORMSQ1 = NORMSQ2 | |||
| * | |||
| DO I = 1, N | |||
| WORK(I) = ZERO | |||
| END DO | |||
| * | |||
| IF( M1 .EQ. 0 ) THEN | |||
| DO I = 1, N | |||
| WORK(I) = ZERO | |||
| END DO | |||
| ELSE | |||
| CALL DGEMV( 'C', M1, N, ONE, Q1, LDQ1, X1, INCX1, ZERO, WORK, | |||
| $ 1 ) | |||
| END IF | |||
| * | |||
| CALL DGEMV( 'C', M2, N, ONE, Q2, LDQ2, X2, INCX2, ONE, WORK, 1 ) | |||
| * | |||
| CALL DGEMV( 'N', M1, N, NEGONE, Q1, LDQ1, WORK, 1, ONE, X1, | |||
| $ INCX1 ) | |||
| CALL DGEMV( 'N', M2, N, NEGONE, Q2, LDQ2, WORK, 1, ONE, X2, | |||
| $ INCX2 ) | |||
| * | |||
| SCL1 = REALZERO | |||
| SSQ1 = REALONE | |||
| CALL DLASSQ( M1, X1, INCX1, SCL1, SSQ1 ) | |||
| SCL2 = REALZERO | |||
| SSQ2 = REALONE | |||
| CALL DLASSQ( M1, X1, INCX1, SCL1, SSQ1 ) | |||
| NORMSQ2 = SCL1**2*SSQ1 + SCL2**2*SSQ2 | |||
| * | |||
| * If second projection is sufficiently large in norm, then do | |||
| * nothing more. Alternatively, if it shrunk significantly, then | |||
| * truncate it to zero. | |||
| * | |||
| IF( NORMSQ2 .LT. ALPHASQ*NORMSQ1 ) THEN | |||
| DO I = 1, M1 | |||
| X1(I) = ZERO | |||
| END DO | |||
| DO I = 1, M2 | |||
| X2(I) = ZERO | |||
| END DO | |||
| END IF | |||
| * | |||
| RETURN | |||
| * | |||
| * End of DORBDB6 | |||
| * | |||
| END | |||
| @@ -289,7 +289,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date November 2011 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup doubleOTHERcomputational | |||
| * | |||
| @@ -300,10 +300,10 @@ | |||
| $ U1, LDU1, U2, LDU2, V1T, LDV1T, V2T, | |||
| $ LDV2T, WORK, LWORK, IWORK, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.0) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * November 2011 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER JOBU1, JOBU2, JOBV1T, JOBV2T, SIGNS, TRANS | |||
| @@ -368,9 +368,22 @@ | |||
| INFO = -8 | |||
| ELSE IF( Q .LT. 0 .OR. Q .GT. M ) THEN | |||
| INFO = -9 | |||
| ELSE IF( ( COLMAJOR .AND. LDX11 .LT. MAX(1,P) ) .OR. | |||
| $ ( .NOT.COLMAJOR .AND. LDX11 .LT. MAX(1,Q) ) ) THEN | |||
| INFO = -11 | |||
| ELSE IF ( COLMAJOR .AND. LDX11 .LT. MAX( 1, P ) ) THEN | |||
| INFO = -11 | |||
| ELSE IF (.NOT. COLMAJOR .AND. LDX11 .LT. MAX( 1, Q ) ) THEN | |||
| INFO = -11 | |||
| ELSE IF (COLMAJOR .AND. LDX12 .LT. MAX( 1, P ) ) THEN | |||
| INFO = -13 | |||
| ELSE IF (.NOT. COLMAJOR .AND. LDX12 .LT. MAX( 1, M-Q ) ) THEN | |||
| INFO = -13 | |||
| ELSE IF (COLMAJOR .AND. LDX21 .LT. MAX( 1, M-P ) ) THEN | |||
| INFO = -15 | |||
| ELSE IF (.NOT. COLMAJOR .AND. LDX21 .LT. MAX( 1, Q ) ) THEN | |||
| INFO = -15 | |||
| ELSE IF (COLMAJOR .AND. LDX22 .LT. MAX( 1, M-P ) ) THEN | |||
| INFO = -17 | |||
| ELSE IF (.NOT. COLMAJOR .AND. LDX22 .LT. MAX( 1, M-Q ) ) THEN | |||
| INFO = -17 | |||
| ELSE IF( WANTU1 .AND. LDU1 .LT. P ) THEN | |||
| INFO = -20 | |||
| ELSE IF( WANTU2 .AND. LDU2 .LT. M-P ) THEN | |||
| @@ -427,19 +440,19 @@ | |||
| ITAUQ1 = ITAUP2 + MAX( 1, M - P ) | |||
| ITAUQ2 = ITAUQ1 + MAX( 1, Q ) | |||
| IORGQR = ITAUQ2 + MAX( 1, M - Q ) | |||
| CALL DORGQR( M-Q, M-Q, M-Q, 0, MAX(1,M-Q), 0, WORK, -1, | |||
| CALL DORGQR( 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 DORGLQ( M-Q, M-Q, M-Q, 0, MAX(1,M-Q), 0, WORK, -1, | |||
| CALL DORGLQ( M-Q, M-Q, M-Q, U1, MAX(1,M-Q), U1, WORK, -1, | |||
| $ CHILDINFO ) | |||
| LORGLQWORKOPT = INT( WORK(1) ) | |||
| LORGLQWORKMIN = MAX( 1, M - Q ) | |||
| IORBDB = ITAUQ2 + MAX( 1, M - Q ) | |||
| CALL DORBDB( TRANS, SIGNS, M, P, Q, X11, LDX11, X12, LDX12, | |||
| $ X21, LDX21, X22, LDX22, 0, 0, 0, 0, 0, 0, WORK, | |||
| $ -1, CHILDINFO ) | |||
| $ X21, LDX21, X22, LDX22, THETA, V1T, U1, U2, V1T, | |||
| $ V2T, WORK, -1, CHILDINFO ) | |||
| LORBDBWORKOPT = INT( WORK(1) ) | |||
| LORBDBWORKMIN = LORBDBWORKOPT | |||
| IB11D = ITAUQ2 + MAX( 1, M - Q ) | |||
| @@ -451,9 +464,10 @@ | |||
| IB22D = IB21E + MAX( 1, Q - 1 ) | |||
| IB22E = IB22D + MAX( 1, Q ) | |||
| IBBCSD = IB22E + MAX( 1, Q - 1 ) | |||
| CALL DBBCSD( JOBU1, JOBU2, JOBV1T, JOBV2T, TRANS, M, P, Q, 0, | |||
| $ 0, U1, LDU1, U2, LDU2, V1T, LDV1T, V2T, LDV2T, 0, | |||
| $ 0, 0, 0, 0, 0, 0, 0, WORK, -1, CHILDINFO ) | |||
| CALL DBBCSD( JOBU1, JOBU2, JOBV1T, JOBV2T, TRANS, M, P, Q, | |||
| $ THETA, THETA, U1, LDU1, U2, LDU2, V1T, LDV1T, V2T, | |||
| $ LDV2T, U1, U1, U1, U1, U1, U1, U1, U1, WORK, -1, | |||
| $ CHILDINFO ) | |||
| LBBCSDWORKOPT = INT( WORK(1) ) | |||
| LBBCSDWORKMIN = LBBCSDWORKOPT | |||
| LWORKOPT = MAX( IORGQR + LORGQRWORKOPT, IORGLQ + LORGLQWORKOPT, | |||
| @@ -514,10 +528,14 @@ | |||
| END IF | |||
| IF( WANTV2T .AND. M-Q .GT. 0 ) THEN | |||
| CALL DLACPY( 'U', P, M-Q, X12, LDX12, V2T, LDV2T ) | |||
| CALL DLACPY( 'U', M-P-Q, M-P-Q, X22(Q+1,P+1), LDX22, | |||
| $ V2T(P+1,P+1), LDV2T ) | |||
| CALL DORGLQ( M-Q, M-Q, M-Q, V2T, LDV2T, WORK(ITAUQ2), | |||
| $ WORK(IORGLQ), LORGLQWORK, INFO ) | |||
| IF (M-P .GT. Q) Then | |||
| CALL DLACPY( 'U', M-P-Q, M-P-Q, X22(Q+1,P+1), LDX22, | |||
| $ V2T(P+1,P+1), LDV2T ) | |||
| END IF | |||
| IF (M .GT. Q) THEN | |||
| CALL DORGLQ( M-Q, M-Q, M-Q, V2T, LDV2T, WORK(ITAUQ2), | |||
| $ WORK(IORGLQ), LORGLQWORK, INFO ) | |||
| END IF | |||
| END IF | |||
| ELSE | |||
| IF( WANTU1 .AND. P .GT. 0 ) THEN | |||
| @@ -0,0 +1,715 @@ | |||
| *> \brief \b DORCSD2BY1 | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download DORCSD2BY1 + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dorcsd2by1.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dorcsd2by1.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dorcsd2by1.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE DORCSD2BY1( JOBU1, JOBU2, JOBV1T, M, P, Q, X11, LDX11, | |||
| * X21, LDX21, THETA, U1, LDU1, U2, LDU2, V1T, | |||
| * LDV1T, WORK, LWORK, IWORK, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * CHARACTER JOBU1, JOBU2, JOBV1T | |||
| * INTEGER INFO, LDU1, LDU2, LDV1T, LWORK, LDX11, LDX21, | |||
| * $ M, P, Q | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * DOUBLE PRECISION THETA(*) | |||
| * DOUBLE PRECISION U1(LDU1,*), U2(LDU2,*), V1T(LDV1T,*), WORK(*), | |||
| * $ X11(LDX11,*), X21(LDX21,*) | |||
| * INTEGER IWORK(*) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| *> ============= | |||
| *> | |||
| *>\verbatim | |||
| *> Purpose: | |||
| *> ======== | |||
| *> | |||
| *> DORCSD2BY1 computes the CS decomposition of an M-by-Q matrix X with | |||
| *> orthonormal columns that has been partitioned into a 2-by-1 block | |||
| *> structure: | |||
| *> | |||
| *> [ I 0 0 ] | |||
| *> [ 0 C 0 ] | |||
| *> [ X11 ] [ U1 | ] [ 0 0 0 ] | |||
| *> X = [-----] = [---------] [----------] V1**T . | |||
| *> [ X21 ] [ | U2 ] [ 0 0 0 ] | |||
| *> [ 0 S 0 ] | |||
| *> [ 0 0 I ] | |||
| *> | |||
| *> X11 is P-by-Q. The orthogonal matrices U1, U2, V1, and V2 are P-by-P, | |||
| *> (M-P)-by-(M-P), Q-by-Q, and (M-Q)-by-(M-Q), respectively. C and S are | |||
| *> R-by-R nonnegative diagonal matrices satisfying C^2 + S^2 = I, in | |||
| *> which R = MIN(P,M-P,Q,M-Q). | |||
| *> | |||
| *>\endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] JOBU1 | |||
| *> \verbatim | |||
| *> JOBU1 is CHARACTER | |||
| *> = 'Y': U1 is computed; | |||
| *> otherwise: U1 is not computed. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] JOBU2 | |||
| *> \verbatim | |||
| *> JOBU2 is CHARACTER | |||
| *> = 'Y': U2 is computed; | |||
| *> otherwise: U2 is not computed. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] JOBV1T | |||
| *> \verbatim | |||
| *> JOBV1T is CHARACTER | |||
| *> = 'Y': V1T is computed; | |||
| *> otherwise: V1T is not computed. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] M | |||
| *> \verbatim | |||
| *> M is INTEGER | |||
| *> The number of rows and columns in X. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] P | |||
| *> \verbatim | |||
| *> P is INTEGER | |||
| *> The number of rows in X11 and X12. 0 <= P <= M. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] Q | |||
| *> \verbatim | |||
| *> Q is INTEGER | |||
| *> The number of columns in X11 and X21. 0 <= Q <= M. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X11 | |||
| *> \verbatim | |||
| *> X11 is DOUBLE PRECISION array, dimension (LDX11,Q) | |||
| *> On entry, part of the orthogonal matrix whose CSD is | |||
| *> desired. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDX11 | |||
| *> \verbatim | |||
| *> LDX11 is INTEGER | |||
| *> The leading dimension of X11. LDX11 >= MAX(1,P). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] X21 | |||
| *> \verbatim | |||
| *> X21 is DOUBLE PRECISION array, dimension (LDX21,Q) | |||
| *> On entry, part of the orthogonal matrix whose CSD is | |||
| *> desired. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDX21 | |||
| *> \verbatim | |||
| *> LDX21 is INTEGER | |||
| *> The leading dimension of X21. LDX21 >= MAX(1,M-P). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] THETA | |||
| *> \verbatim | |||
| *> THETA is DOUBLE PRECISION array, dimension (R), in which R = | |||
| *> MIN(P,M-P,Q,M-Q). | |||
| *> C = DIAG( COS(THETA(1)), ... , COS(THETA(R)) ) and | |||
| *> S = DIAG( SIN(THETA(1)), ... , SIN(THETA(R)) ). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] U1 | |||
| *> \verbatim | |||
| *> U1 is DOUBLE PRECISION array, dimension (P) | |||
| *> If JOBU1 = 'Y', U1 contains the P-by-P orthogonal matrix U1. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDU1 | |||
| *> \verbatim | |||
| *> LDU1 is INTEGER | |||
| *> The leading dimension of U1. If JOBU1 = 'Y', LDU1 >= | |||
| *> MAX(1,P). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] U2 | |||
| *> \verbatim | |||
| *> U2 is DOUBLE PRECISION array, dimension (M-P) | |||
| *> If JOBU2 = 'Y', U2 contains the (M-P)-by-(M-P) orthogonal | |||
| *> matrix U2. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDU2 | |||
| *> \verbatim | |||
| *> LDU2 is INTEGER | |||
| *> The leading dimension of U2. If JOBU2 = 'Y', LDU2 >= | |||
| *> MAX(1,M-P). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] V1T | |||
| *> \verbatim | |||
| *> V1T is DOUBLE PRECISION array, dimension (Q) | |||
| *> If JOBV1T = 'Y', V1T contains the Q-by-Q matrix orthogonal | |||
| *> matrix V1**T. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDV1T | |||
| *> \verbatim | |||
| *> LDV1T is INTEGER | |||
| *> The leading dimension of V1T. If JOBV1T = 'Y', LDV1T >= | |||
| *> MAX(1,Q). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] WORK | |||
| *> \verbatim | |||
| *> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)) | |||
| *> On exit, if INFO = 0, WORK(1) returns the optimal LWORK. | |||
| *> If INFO > 0 on exit, WORK(2:R) contains the values PHI(1), | |||
| *> ..., PHI(R-1) that, together with THETA(1), ..., THETA(R), | |||
| *> define the matrix in intermediate bidiagonal-block form | |||
| *> remaining after nonconvergence. INFO specifies the number | |||
| *> of nonzero PHI's. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LWORK | |||
| *> \verbatim | |||
| *> LWORK is INTEGER | |||
| *> The dimension of the array WORK. | |||
| *> \endverbatim | |||
| *> | |||
| *> 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. | |||
| *> \param[out] IWORK | |||
| *> \verbatim | |||
| *> IWORK is INTEGER array, dimension (M-MIN(P,M-P,Q,M-Q)) | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] INFO | |||
| *> \verbatim | |||
| *> INFO is INTEGER | |||
| *> = 0: successful exit. | |||
| *> < 0: if INFO = -i, the i-th argument had an illegal value. | |||
| *> > 0: DBBCSD did not converge. See the description of WORK | |||
| *> above for details. | |||
| *> \endverbatim | |||
| * | |||
| * Authors: | |||
| * ======== | |||
| * | |||
| *> \author Univ. of Tennessee | |||
| *> \author Univ. of California Berkeley | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date July 2012 | |||
| * | |||
| *> \ingroup doubleOTHERcomputational | |||
| * | |||
| *> \par References: | |||
| * ================ | |||
| *> | |||
| *> [1] Brian D. Sutton. Computing the complete CS decomposition. Numer. | |||
| *> Algorithms, 50(1):33-65, 2009. | |||
| *> \endverbatim | |||
| *> | |||
| * ===================================================================== | |||
| SUBROUTINE DORCSD2BY1( JOBU1, JOBU2, JOBV1T, M, P, Q, X11, LDX11, | |||
| $ X21, LDX21, THETA, U1, LDU1, U2, LDU2, V1T, | |||
| $ LDV1T, WORK, LWORK, IWORK, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * July 2012 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER JOBU1, JOBU2, JOBV1T | |||
| INTEGER INFO, LDU1, LDU2, LDV1T, LWORK, LDX11, LDX21, | |||
| $ M, P, Q | |||
| * .. | |||
| * .. Array Arguments .. | |||
| DOUBLE PRECISION THETA(*) | |||
| DOUBLE PRECISION U1(LDU1,*), U2(LDU2,*), V1T(LDV1T,*), WORK(*), | |||
| $ X11(LDX11,*), X21(LDX21,*) | |||
| INTEGER IWORK(*) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| DOUBLE PRECISION ONE, ZERO | |||
| PARAMETER ( ONE = 1.0D0, ZERO = 0.0D0 ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| INTEGER CHILDINFO, I, IB11D, IB11E, IB12D, IB12E, | |||
| $ IB21D, IB21E, IB22D, IB22E, IBBCSD, IORBDB, | |||
| $ IORGLQ, IORGQR, IPHI, ITAUP1, ITAUP2, ITAUQ1, | |||
| $ J, LBBCSD, LORBDB, LORGLQ, LORGLQMIN, | |||
| $ LORGLQOPT, LORGQR, LORGQRMIN, LORGQROPT, | |||
| $ LWORKMIN, LWORKOPT, R | |||
| LOGICAL LQUERY, WANTU1, WANTU2, WANTV1T | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL DBBCSD, DCOPY, DLACPY, DLAPMR, DLAPMT, DORBDB1, | |||
| $ DORBDB2, DORBDB3, DORBDB4, DORGLQ, DORGQR, | |||
| $ XERBLA | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| EXTERNAL LSAME | |||
| * .. | |||
| * .. Intrinsic Function .. | |||
| INTRINSIC INT, MAX, MIN | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Test input arguments | |||
| * | |||
| INFO = 0 | |||
| WANTU1 = LSAME( JOBU1, 'Y' ) | |||
| WANTU2 = LSAME( JOBU2, 'Y' ) | |||
| WANTV1T = LSAME( JOBV1T, 'Y' ) | |||
| LQUERY = LWORK .EQ. -1 | |||
| * | |||
| IF( M .LT. 0 ) THEN | |||
| INFO = -4 | |||
| ELSE IF( P .LT. 0 .OR. P .GT. M ) THEN | |||
| INFO = -5 | |||
| ELSE IF( Q .LT. 0 .OR. Q .GT. M ) THEN | |||
| INFO = -6 | |||
| ELSE IF( LDX11 .LT. MAX( 1, P ) ) THEN | |||
| INFO = -8 | |||
| ELSE IF( LDX21 .LT. MAX( 1, M-P ) ) THEN | |||
| INFO = -10 | |||
| ELSE IF( WANTU1 .AND. LDU1 .LT. P ) THEN | |||
| INFO = -13 | |||
| ELSE IF( WANTU2 .AND. LDU2 .LT. M - P ) THEN | |||
| INFO = -15 | |||
| ELSE IF( WANTV1T .AND. LDV1T .LT. Q ) THEN | |||
| INFO = -17 | |||
| END IF | |||
| * | |||
| R = MIN( P, M-P, Q, M-Q ) | |||
| * | |||
| * Compute workspace | |||
| * | |||
| * WORK layout: | |||
| * |-------------------------------------------------------| | |||
| * | LWORKOPT (1) | | |||
| * |-------------------------------------------------------| | |||
| * | PHI (MAX(1,R-1)) | | |||
| * |-------------------------------------------------------| | |||
| * | TAUP1 (MAX(1,P)) | B11D (R) | | |||
| * | TAUP2 (MAX(1,M-P)) | B11E (R-1) | | |||
| * | TAUQ1 (MAX(1,Q)) | B12D (R) | | |||
| * |-----------------------------------------| B12E (R-1) | | |||
| * | DORBDB WORK | DORGQR WORK | DORGLQ WORK | B21D (R) | | |||
| * | | | | B21E (R-1) | | |||
| * | | | | B22D (R) | | |||
| * | | | | B22E (R-1) | | |||
| * | | | | DBBCSD WORK | | |||
| * |-------------------------------------------------------| | |||
| * | |||
| IF( INFO .EQ. 0 ) THEN | |||
| IPHI = 2 | |||
| IB11D = IPHI + MAX( 1, R-1 ) | |||
| IB11E = IB11D + MAX( 1, R ) | |||
| IB12D = IB11E + MAX( 1, R - 1 ) | |||
| IB12E = IB12D + MAX( 1, R ) | |||
| IB21D = IB12E + MAX( 1, R - 1 ) | |||
| IB21E = IB21D + MAX( 1, R ) | |||
| IB22D = IB21E + MAX( 1, R - 1 ) | |||
| IB22E = IB22D + MAX( 1, R ) | |||
| IBBCSD = IB22E + MAX( 1, R - 1 ) | |||
| ITAUP1 = IPHI + MAX( 1, R-1 ) | |||
| ITAUP2 = ITAUP1 + MAX( 1, P ) | |||
| ITAUQ1 = ITAUP2 + MAX( 1, M-P ) | |||
| IORBDB = ITAUQ1 + MAX( 1, Q ) | |||
| IORGQR = ITAUQ1 + MAX( 1, Q ) | |||
| IORGLQ = ITAUQ1 + MAX( 1, Q ) | |||
| IF( R .EQ. Q ) THEN | |||
| CALL DORBDB1( M, P, Q, X11, LDX11, X21, LDX21, THETA, 0, 0, | |||
| $ 0, 0, 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, | |||
| $ CHILDINFO ) | |||
| LORGQRMIN = MAX( 1, M-P ) | |||
| LORGQROPT = 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 ) | |||
| 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 ) | |||
| 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), | |||
| $ -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, | |||
| $ CHILDINFO ) | |||
| LORGQRMIN = MAX( 1, M-P ) | |||
| LORGQROPT = 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 ) | |||
| 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 ) | |||
| LORBDB = INT( WORK(1) ) | |||
| IF( P .GE. M-P-1 ) 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-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) ) | |||
| 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 ) | |||
| LBBCSD = INT( WORK(1) ) | |||
| ELSE | |||
| CALL DORBDB4( M, P, Q, X11, LDX11, X21, LDX21, THETA, 0, 0, | |||
| $ 0, 0, 0, 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, | |||
| $ CHILDINFO ) | |||
| LORGQRMIN = MAX( 1, P ) | |||
| LORGQROPT = INT( WORK(1) ) | |||
| ELSE | |||
| CALL DORGQR( M-P, M-P, M-Q, U2, LDU2, 0, WORK(1), -1, | |||
| $ CHILDINFO ) | |||
| LORGQRMIN = MAX( 1, M-P ) | |||
| LORGQROPT = 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 ) | |||
| LBBCSD = INT( WORK(1) ) | |||
| END IF | |||
| LWORKMIN = MAX( IORBDB+LORBDB-1, | |||
| $ IORGQR+LORGQRMIN-1, | |||
| $ IORGLQ+LORGLQMIN-1, | |||
| $ IBBCSD+LBBCSD-1 ) | |||
| LWORKOPT = MAX( IORBDB+LORBDB-1, | |||
| $ IORGQR+LORGQROPT-1, | |||
| $ IORGLQ+LORGLQOPT-1, | |||
| $ IBBCSD+LBBCSD-1 ) | |||
| WORK(1) = LWORKOPT | |||
| IF( LWORK .LT. LWORKMIN .AND. .NOT.LQUERY ) THEN | |||
| INFO = -19 | |||
| END IF | |||
| END IF | |||
| IF( INFO .NE. 0 ) THEN | |||
| CALL XERBLA( 'DORCSD2BY1', -INFO ) | |||
| RETURN | |||
| ELSE IF( LQUERY ) THEN | |||
| RETURN | |||
| END IF | |||
| LORGQR = LWORK-IORGQR+1 | |||
| LORGLQ = LWORK-IORGLQ+1 | |||
| * | |||
| * Handle four cases separately: R = Q, R = P, R = M-P, and R = M-Q, | |||
| * in which R = MIN(P,M-P,Q,M-Q) | |||
| * | |||
| IF( R .EQ. Q ) THEN | |||
| * | |||
| * Case 1: R = Q | |||
| * | |||
| * Simultaneously bidiagonalize X11 and X21 | |||
| * | |||
| CALL DORBDB1( M, P, Q, X11, LDX11, X21, LDX21, THETA, | |||
| $ WORK(IPHI), WORK(ITAUP1), WORK(ITAUP2), | |||
| $ WORK(ITAUQ1), WORK(IORBDB), LORBDB, CHILDINFO ) | |||
| * | |||
| * Accumulate Householder reflectors | |||
| * | |||
| IF( WANTU1 .AND. P .GT. 0 ) THEN | |||
| CALL DLACPY( 'L', P, Q, X11, LDX11, U1, LDU1 ) | |||
| CALL DORGQR( P, P, Q, U1, LDU1, WORK(ITAUP1), WORK(IORGQR), | |||
| $ LORGQR, CHILDINFO ) | |||
| END IF | |||
| IF( WANTU2 .AND. M-P .GT. 0 ) THEN | |||
| CALL DLACPY( 'L', M-P, Q, X21, LDX21, U2, LDU2 ) | |||
| CALL DORGQR( M-P, M-P, Q, U2, LDU2, WORK(ITAUP2), | |||
| $ WORK(IORGQR), LORGQR, CHILDINFO ) | |||
| END IF | |||
| IF( WANTV1T .AND. Q .GT. 0 ) THEN | |||
| V1T(1,1) = ONE | |||
| DO J = 2, Q | |||
| V1T(1,J) = ZERO | |||
| V1T(J,1) = ZERO | |||
| END DO | |||
| CALL DLACPY( 'U', Q-1, Q-1, X21(1,2), LDX21, V1T(2,2), | |||
| $ LDV1T ) | |||
| CALL DORGLQ( Q-1, Q-1, Q-1, V1T(2,2), LDV1T, WORK(ITAUQ1), | |||
| $ WORK(IORGLQ), LORGLQ, CHILDINFO ) | |||
| END IF | |||
| * | |||
| * 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 ) | |||
| * | |||
| * Permute rows and columns to place zero submatrices in | |||
| * preferred positions | |||
| * | |||
| IF( Q .GT. 0 .AND. WANTU2 ) THEN | |||
| DO I = 1, Q | |||
| IWORK(I) = M - P - Q + I | |||
| END DO | |||
| DO I = Q + 1, M - P | |||
| IWORK(I) = I - Q | |||
| END DO | |||
| CALL DLAPMT( .FALSE., M-P, M-P, U2, LDU2, IWORK ) | |||
| END IF | |||
| ELSE IF( R .EQ. P ) THEN | |||
| * | |||
| * Case 2: R = P | |||
| * | |||
| * Simultaneously bidiagonalize X11 and X21 | |||
| * | |||
| CALL DORBDB2( M, P, Q, X11, LDX11, X21, LDX21, THETA, | |||
| $ WORK(IPHI), WORK(ITAUP1), WORK(ITAUP2), | |||
| $ WORK(ITAUQ1), WORK(IORBDB), LORBDB, CHILDINFO ) | |||
| * | |||
| * Accumulate Householder reflectors | |||
| * | |||
| IF( WANTU1 .AND. P .GT. 0 ) THEN | |||
| U1(1,1) = ONE | |||
| DO J = 2, P | |||
| U1(1,J) = ZERO | |||
| U1(J,1) = ZERO | |||
| END DO | |||
| CALL DLACPY( 'L', P-1, P-1, X11(2,1), LDX11, U1(2,2), LDU1 ) | |||
| CALL DORGQR( P-1, P-1, P-1, U1(2,2), LDU1, WORK(ITAUP1), | |||
| $ WORK(IORGQR), LORGQR, CHILDINFO ) | |||
| END IF | |||
| IF( WANTU2 .AND. M-P .GT. 0 ) THEN | |||
| CALL DLACPY( 'L', M-P, Q, X21, LDX21, U2, LDU2 ) | |||
| CALL DORGQR( M-P, M-P, Q, U2, LDU2, WORK(ITAUP2), | |||
| $ WORK(IORGQR), LORGQR, CHILDINFO ) | |||
| END IF | |||
| IF( WANTV1T .AND. Q .GT. 0 ) THEN | |||
| CALL DLACPY( 'U', P, Q, X11, LDX11, V1T, LDV1T ) | |||
| CALL DORGLQ( Q, Q, R, V1T, LDV1T, WORK(ITAUQ1), | |||
| $ WORK(IORGLQ), LORGLQ, CHILDINFO ) | |||
| END IF | |||
| * | |||
| * 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(IB12E), WORK(IB21D), WORK(IB21E), | |||
| $ WORK(IB22D), WORK(IB22E), WORK(IBBCSD), LBBCSD, | |||
| $ CHILDINFO ) | |||
| * | |||
| * Permute rows and columns to place identity submatrices in | |||
| * preferred positions | |||
| * | |||
| IF( Q .GT. 0 .AND. WANTU2 ) THEN | |||
| DO I = 1, Q | |||
| IWORK(I) = M - P - Q + I | |||
| END DO | |||
| DO I = Q + 1, M - P | |||
| IWORK(I) = I - Q | |||
| END DO | |||
| CALL DLAPMT( .FALSE., M-P, M-P, U2, LDU2, IWORK ) | |||
| END IF | |||
| ELSE IF( R .EQ. M-P ) THEN | |||
| * | |||
| * Case 3: R = M-P | |||
| * | |||
| * Simultaneously bidiagonalize X11 and X21 | |||
| * | |||
| CALL DORBDB3( M, P, Q, X11, LDX11, X21, LDX21, THETA, | |||
| $ WORK(IPHI), WORK(ITAUP1), WORK(ITAUP2), | |||
| $ WORK(ITAUQ1), WORK(IORBDB), LORBDB, CHILDINFO ) | |||
| * | |||
| * Accumulate Householder reflectors | |||
| * | |||
| IF( WANTU1 .AND. P .GT. 0 ) THEN | |||
| CALL DLACPY( 'L', P, Q, X11, LDX11, U1, LDU1 ) | |||
| CALL DORGQR( P, P, Q, U1, LDU1, WORK(ITAUP1), WORK(IORGQR), | |||
| $ LORGQR, CHILDINFO ) | |||
| END IF | |||
| IF( WANTU2 .AND. M-P .GT. 0 ) THEN | |||
| U2(1,1) = ONE | |||
| DO J = 2, M-P | |||
| U2(1,J) = ZERO | |||
| U2(J,1) = ZERO | |||
| END DO | |||
| CALL DLACPY( 'L', M-P-1, M-P-1, X21(2,1), LDX21, U2(2,2), | |||
| $ LDU2 ) | |||
| CALL DORGQR( M-P-1, M-P-1, M-P-1, U2(2,2), LDU2, | |||
| $ WORK(ITAUP2), WORK(IORGQR), LORGQR, CHILDINFO ) | |||
| END IF | |||
| IF( WANTV1T .AND. Q .GT. 0 ) THEN | |||
| CALL DLACPY( 'U', M-P, Q, X21, LDX21, V1T, LDV1T ) | |||
| CALL DORGLQ( Q, Q, R, V1T, LDV1T, WORK(ITAUQ1), | |||
| $ WORK(IORGLQ), LORGLQ, CHILDINFO ) | |||
| END IF | |||
| * | |||
| * 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 ) | |||
| * | |||
| * Permute rows and columns to place identity submatrices in | |||
| * preferred positions | |||
| * | |||
| IF( Q .GT. R ) THEN | |||
| DO I = 1, R | |||
| IWORK(I) = Q - R + I | |||
| END DO | |||
| DO I = R + 1, Q | |||
| IWORK(I) = I - R | |||
| END DO | |||
| IF( WANTU1 ) THEN | |||
| CALL DLAPMT( .FALSE., P, Q, U1, LDU1, IWORK ) | |||
| END IF | |||
| IF( WANTV1T ) THEN | |||
| CALL DLAPMR( .FALSE., Q, Q, V1T, LDV1T, IWORK ) | |||
| END IF | |||
| END IF | |||
| ELSE | |||
| * | |||
| * Case 4: R = M-Q | |||
| * | |||
| * Simultaneously bidiagonalize X11 and X21 | |||
| * | |||
| CALL DORBDB4( M, P, Q, X11, LDX11, X21, LDX21, THETA, | |||
| $ WORK(IPHI), WORK(ITAUP1), WORK(ITAUP2), | |||
| $ WORK(ITAUQ1), WORK(IORBDB), WORK(IORBDB+M), | |||
| $ LORBDB-M, CHILDINFO ) | |||
| * | |||
| * Accumulate Householder reflectors | |||
| * | |||
| IF( WANTU1 .AND. P .GT. 0 ) THEN | |||
| CALL DCOPY( P, WORK(IORBDB), 1, U1, 1 ) | |||
| DO J = 2, P | |||
| U1(1,J) = ZERO | |||
| END DO | |||
| CALL DLACPY( 'L', P-1, M-Q-1, X11(2,1), LDX11, U1(2,2), | |||
| $ LDU1 ) | |||
| CALL DORGQR( P, P, M-Q, U1, LDU1, WORK(ITAUP1), | |||
| $ WORK(IORGQR), LORGQR, CHILDINFO ) | |||
| END IF | |||
| IF( WANTU2 .AND. M-P .GT. 0 ) THEN | |||
| CALL DCOPY( M-P, WORK(IORBDB+P), 1, U2, 1 ) | |||
| DO J = 2, M-P | |||
| U2(1,J) = ZERO | |||
| END DO | |||
| CALL DLACPY( 'L', M-P-1, M-Q-1, X21(2,1), LDX21, U2(2,2), | |||
| $ LDU2 ) | |||
| CALL DORGQR( M-P, M-P, M-Q, U2, LDU2, WORK(ITAUP2), | |||
| $ WORK(IORGQR), LORGQR, CHILDINFO ) | |||
| END IF | |||
| IF( WANTV1T .AND. Q .GT. 0 ) THEN | |||
| CALL DLACPY( 'U', M-Q, Q, X21, LDX21, V1T, LDV1T ) | |||
| CALL DLACPY( 'U', P-(M-Q), Q-(M-Q), X11(M-Q+1,M-Q+1), LDX11, | |||
| $ V1T(M-Q+1,M-Q+1), LDV1T ) | |||
| CALL DLACPY( 'U', -P+Q, Q-P, X21(M-Q+1,P+1), LDX21, | |||
| $ V1T(P+1,P+1), LDV1T ) | |||
| CALL DORGLQ( Q, Q, Q, V1T, LDV1T, WORK(ITAUQ1), | |||
| $ WORK(IORGLQ), LORGLQ, CHILDINFO ) | |||
| END IF | |||
| * | |||
| * 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 ) | |||
| * | |||
| * Permute rows and columns to place identity submatrices in | |||
| * preferred positions | |||
| * | |||
| IF( P .GT. R ) THEN | |||
| DO I = 1, R | |||
| IWORK(I) = P - R + I | |||
| END DO | |||
| DO I = R + 1, P | |||
| IWORK(I) = I - R | |||
| END DO | |||
| IF( WANTU1 ) THEN | |||
| CALL DLAPMT( .FALSE., P, P, U1, LDU1, IWORK ) | |||
| END IF | |||
| IF( WANTV1T ) THEN | |||
| CALL DLAPMR( .FALSE., P, Q, V1T, LDV1T, IWORK ) | |||
| END IF | |||
| END IF | |||
| END IF | |||
| * | |||
| RETURN | |||
| * | |||
| * End of DORCSD2BY1 | |||
| * | |||
| END | |||
| @@ -294,7 +294,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date September 2012 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup doubleOTHERcomputational | |||
| * | |||
| @@ -312,10 +312,10 @@ | |||
| $ M, W, Z, LDZ, NZC, ISUPPZ, TRYRAC, WORK, LWORK, | |||
| $ IWORK, LIWORK, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.2) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * September 2012 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER JOBZ, RANGE | |||
| @@ -391,6 +391,7 @@ | |||
| WU = ZERO | |||
| IIL = 0 | |||
| IIU = 0 | |||
| NSPLIT = 0 | |||
| IF( VALEIG ) THEN | |||
| * We do not reference VL, VU in the cases RANGE = 'I','A' | |||
| @@ -0,0 +1,258 @@ | |||
| *> \brief \b DSYCON_ROOK | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download DSYCON_ROOK + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsycon_rook.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsycon_rook.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsycon_rook.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE DSYCON_ROOK( UPLO, N, A, LDA, IPIV, ANORM, RCOND, | |||
| * WORK, IWORK, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * CHARACTER UPLO | |||
| * INTEGER INFO, LDA, N | |||
| * DOUBLE PRECISION ANORM, RCOND | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * INTEGER IPIV( * ), IWORK( * ) | |||
| * DOUBLE PRECISION A( LDA, * ), WORK( * ) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| * ============= | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> DSYCON_ROOK estimates the reciprocal of the condition number (in the | |||
| *> 1-norm) of a real symmetric matrix A using the factorization | |||
| *> A = U*D*U**T or A = L*D*L**T computed by DSYTRF_ROOK. | |||
| *> | |||
| *> An estimate is obtained for norm(inv(A)), and the reciprocal of the | |||
| *> condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))). | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] UPLO | |||
| *> \verbatim | |||
| *> UPLO is CHARACTER*1 | |||
| *> Specifies whether the details of the factorization are stored | |||
| *> as an upper or lower triangular matrix. | |||
| *> = 'U': Upper triangular, form is A = U*D*U**T; | |||
| *> = 'L': Lower triangular, form is A = L*D*L**T. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] N | |||
| *> \verbatim | |||
| *> N is INTEGER | |||
| *> The order of the matrix A. N >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] A | |||
| *> \verbatim | |||
| *> A is DOUBLE PRECISION array, dimension (LDA,N) | |||
| *> The block diagonal matrix D and the multipliers used to | |||
| *> obtain the factor U or L as computed by DSYTRF_ROOK. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDA | |||
| *> \verbatim | |||
| *> LDA is INTEGER | |||
| *> The leading dimension of the array A. LDA >= max(1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] IPIV | |||
| *> \verbatim | |||
| *> IPIV is INTEGER array, dimension (N) | |||
| *> Details of the interchanges and the block structure of D | |||
| *> as determined by DSYTRF_ROOK. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] ANORM | |||
| *> \verbatim | |||
| *> ANORM is DOUBLE PRECISION | |||
| *> The 1-norm of the original matrix A. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] RCOND | |||
| *> \verbatim | |||
| *> RCOND is DOUBLE PRECISION | |||
| *> The reciprocal of the condition number of the matrix A, | |||
| *> computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is an | |||
| *> estimate of the 1-norm of inv(A) computed in this routine. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] WORK | |||
| *> \verbatim | |||
| *> WORK is DOUBLE PRECISION array, dimension (2*N) | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] IWORK | |||
| *> \verbatim | |||
| *> IWORK is INTEGER array, dimension (N) | |||
| *> \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 April 2012 | |||
| * | |||
| *> \ingroup doubleSYcomputational | |||
| * | |||
| *> \par Contributors: | |||
| * ================== | |||
| *> \verbatim | |||
| *> | |||
| *> April 2012, Igor Kozachenko, | |||
| *> Computer Science Division, | |||
| *> University of California, Berkeley | |||
| *> | |||
| *> September 2007, Sven Hammarling, Nicholas J. Higham, Craig Lucas, | |||
| *> School of Mathematics, | |||
| *> University of Manchester | |||
| *> | |||
| *> \endverbatim | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE DSYCON_ROOK( UPLO, N, A, LDA, IPIV, ANORM, RCOND, WORK, | |||
| $ IWORK, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.1) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * April 2012 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER UPLO | |||
| INTEGER INFO, LDA, N | |||
| DOUBLE PRECISION ANORM, RCOND | |||
| * .. | |||
| * .. Array Arguments .. | |||
| INTEGER IPIV( * ), IWORK( * ) | |||
| DOUBLE PRECISION A( LDA, * ), WORK( * ) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| DOUBLE PRECISION ONE, ZERO | |||
| PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| LOGICAL UPPER | |||
| INTEGER I, KASE | |||
| DOUBLE PRECISION AINVNM | |||
| * .. | |||
| * .. Local Arrays .. | |||
| INTEGER ISAVE( 3 ) | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| EXTERNAL LSAME | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL DLACN2, DSYTRS_ROOK, XERBLA | |||
| * .. | |||
| * .. Intrinsic Functions .. | |||
| INTRINSIC MAX | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Test the input parameters. | |||
| * | |||
| INFO = 0 | |||
| UPPER = LSAME( UPLO, 'U' ) | |||
| IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN | |||
| INFO = -1 | |||
| ELSE IF( N.LT.0 ) THEN | |||
| INFO = -2 | |||
| ELSE IF( LDA.LT.MAX( 1, N ) ) THEN | |||
| INFO = -4 | |||
| ELSE IF( ANORM.LT.ZERO ) THEN | |||
| INFO = -6 | |||
| END IF | |||
| IF( INFO.NE.0 ) THEN | |||
| CALL XERBLA( 'DSYCON_ROOK', -INFO ) | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Quick return if possible | |||
| * | |||
| RCOND = ZERO | |||
| IF( N.EQ.0 ) THEN | |||
| RCOND = ONE | |||
| RETURN | |||
| ELSE IF( ANORM.LE.ZERO ) THEN | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Check that the diagonal matrix D is nonsingular. | |||
| * | |||
| IF( UPPER ) THEN | |||
| * | |||
| * Upper triangular storage: examine D from bottom to top | |||
| * | |||
| DO 10 I = N, 1, -1 | |||
| IF( IPIV( I ).GT.0 .AND. A( I, I ).EQ.ZERO ) | |||
| $ RETURN | |||
| 10 CONTINUE | |||
| ELSE | |||
| * | |||
| * Lower triangular storage: examine D from top to bottom. | |||
| * | |||
| DO 20 I = 1, N | |||
| IF( IPIV( I ).GT.0 .AND. A( I, I ).EQ.ZERO ) | |||
| $ RETURN | |||
| 20 CONTINUE | |||
| END IF | |||
| * | |||
| * Estimate the 1-norm of the inverse. | |||
| * | |||
| KASE = 0 | |||
| 30 CONTINUE | |||
| CALL DLACN2( N, WORK( N+1 ), WORK, IWORK, AINVNM, KASE, ISAVE ) | |||
| IF( KASE.NE.0 ) THEN | |||
| * | |||
| * Multiply by inv(L*D*L**T) or inv(U*D*U**T). | |||
| * | |||
| CALL DSYTRS_ROOK( UPLO, N, 1, A, LDA, IPIV, WORK, N, INFO ) | |||
| GO TO 30 | |||
| END IF | |||
| * | |||
| * Compute the estimate of the reciprocal condition number. | |||
| * | |||
| IF( AINVNM.NE.ZERO ) | |||
| $ RCOND = ( ONE / AINVNM ) / ANORM | |||
| * | |||
| RETURN | |||
| * | |||
| * End of DSYCON_ROOK | |||
| * | |||
| END | |||
| @@ -0,0 +1,293 @@ | |||
| *> \brief <b> DSYSV_ROOK computes the solution to system of linear equations A * X = B for SY matrices</b> | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download DSYSV_ROOK + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsysv_rook.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsysv_rook.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsysv_rook.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE DSYSV_ROOK( UPLO, N, NRHS, A, LDA, IPIV, B, LDB, WORK, | |||
| * LWORK, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * CHARACTER UPLO | |||
| * INTEGER INFO, LDA, LDB, LWORK, N, NRHS | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * INTEGER IPIV( * ) | |||
| * DOUBLE PRECISION A( LDA, * ), B( LDB, * ), WORK( * ) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| * ============= | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> DSYSV_ROOK computes the solution to a real system of linear | |||
| *> equations | |||
| *> A * X = B, | |||
| *> where A is an N-by-N symmetric matrix and X and B are N-by-NRHS | |||
| *> matrices. | |||
| *> | |||
| *> The diagonal pivoting method is used to factor A as | |||
| *> A = U * D * U**T, if UPLO = 'U', or | |||
| *> A = L * D * L**T, if UPLO = 'L', | |||
| *> where U (or L) is a product of permutation and unit upper (lower) | |||
| *> triangular matrices, and D is symmetric and block diagonal with | |||
| *> 1-by-1 and 2-by-2 diagonal blocks. | |||
| *> | |||
| *> DSYTRF_ROOK is called to compute the factorization of a real | |||
| *> symmetric matrix A using the bounded Bunch-Kaufman ("rook") diagonal | |||
| *> pivoting method. | |||
| *> | |||
| *> The factored form of A is then used to solve the system | |||
| *> of equations A * X = B by calling DSYTRS_ROOK. | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] UPLO | |||
| *> \verbatim | |||
| *> UPLO is CHARACTER*1 | |||
| *> = 'U': Upper triangle of A is stored; | |||
| *> = 'L': Lower triangle of A is stored. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] N | |||
| *> \verbatim | |||
| *> N is INTEGER | |||
| *> The number of linear equations, i.e., the order of the | |||
| *> matrix A. N >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] NRHS | |||
| *> \verbatim | |||
| *> NRHS is INTEGER | |||
| *> The number of right hand sides, i.e., the number of columns | |||
| *> of the matrix B. NRHS >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] A | |||
| *> \verbatim | |||
| *> A is DOUBLE PRECISION 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 | |||
| *> triangular part of A is not referenced. If UPLO = 'L', the | |||
| *> leading N-by-N lower triangular part of A contains the lower | |||
| *> triangular part of the matrix A, and the strictly upper | |||
| *> triangular part of A is not referenced. | |||
| *> | |||
| *> On exit, if INFO = 0, the block diagonal matrix D and the | |||
| *> multipliers used to obtain the factor U or L from the | |||
| *> factorization A = U*D*U**T or A = L*D*L**T as computed by | |||
| *> DSYTRF_ROOK. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDA | |||
| *> \verbatim | |||
| *> LDA is INTEGER | |||
| *> The leading dimension of the array A. LDA >= max(1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] IPIV | |||
| *> \verbatim | |||
| *> IPIV is INTEGER array, dimension (N) | |||
| *> Details of the interchanges and the block structure of D, | |||
| *> as determined by DSYTRF_ROOK. | |||
| *> | |||
| *> If UPLO = 'U': | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) | |||
| *> were interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) < 0 and IPIV(k-1) < 0, then rows and | |||
| *> columns k and -IPIV(k) were interchanged and rows and | |||
| *> columns k-1 and -IPIV(k-1) were inerchaged, | |||
| *> D(k-1:k,k-1:k) is a 2-by-2 diagonal block. | |||
| *> | |||
| *> If UPLO = 'L': | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) | |||
| *> were interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) < 0 and IPIV(k+1) < 0, then rows and | |||
| *> columns k and -IPIV(k) were interchanged and rows and | |||
| *> columns k+1 and -IPIV(k+1) were inerchaged, | |||
| *> D(k:k+1,k:k+1) is a 2-by-2 diagonal block. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] B | |||
| *> \verbatim | |||
| *> B is DOUBLE PRECISION array, dimension (LDB,NRHS) | |||
| *> On entry, the N-by-NRHS right hand side matrix B. | |||
| *> On exit, if INFO = 0, the N-by-NRHS solution matrix X. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDB | |||
| *> \verbatim | |||
| *> LDB is INTEGER | |||
| *> The leading dimension of the array B. LDB >= max(1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] WORK | |||
| *> \verbatim | |||
| *> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)) | |||
| *> On exit, if INFO = 0, WORK(1) returns the optimal LWORK. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LWORK | |||
| *> \verbatim | |||
| *> LWORK is INTEGER | |||
| *> The length of WORK. LWORK >= 1, and for best performance | |||
| *> LWORK >= max(1,N*NB), where NB is the optimal blocksize for | |||
| *> DSYTRF_ROOK. | |||
| *> | |||
| *> TRS will be done with Level 2 BLAS | |||
| *> | |||
| *> 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 | |||
| *> > 0: if INFO = i, D(i,i) is exactly zero. The factorization | |||
| *> has been completed, but the block diagonal matrix D is | |||
| *> exactly singular, so the solution could not be computed. | |||
| *> \endverbatim | |||
| * | |||
| * Authors: | |||
| * ======== | |||
| * | |||
| *> \author Univ. of Tennessee | |||
| *> \author Univ. of California Berkeley | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date April 2012 | |||
| * | |||
| *> \ingroup doubleSYsolve | |||
| * | |||
| *> \par Contributors: | |||
| * ================== | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> April 2012, Igor Kozachenko, | |||
| *> Computer Science Division, | |||
| *> University of California, Berkeley | |||
| *> | |||
| *> September 2007, Sven Hammarling, Nicholas J. Higham, Craig Lucas, | |||
| *> School of Mathematics, | |||
| *> University of Manchester | |||
| *> | |||
| *> \endverbatim | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE DSYSV_ROOK( UPLO, N, NRHS, A, LDA, IPIV, B, LDB, WORK, | |||
| $ LWORK, INFO ) | |||
| * | |||
| * -- LAPACK driver routine (version 3.4.1) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * April 2012 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER UPLO | |||
| INTEGER INFO, LDA, LDB, LWORK, N, NRHS | |||
| * .. | |||
| * .. Array Arguments .. | |||
| INTEGER IPIV( * ) | |||
| DOUBLE PRECISION A( LDA, * ), B( LDB, * ), WORK( * ) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Local Scalars .. | |||
| LOGICAL LQUERY | |||
| INTEGER LWKOPT | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| EXTERNAL LSAME | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL XERBLA, DSYTRF_ROOK, DSYTRS_ROOK | |||
| * .. | |||
| * .. Intrinsic Functions .. | |||
| INTRINSIC MAX | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Test the input parameters. | |||
| * | |||
| INFO = 0 | |||
| LQUERY = ( LWORK.EQ.-1 ) | |||
| IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN | |||
| INFO = -1 | |||
| ELSE IF( N.LT.0 ) THEN | |||
| INFO = -2 | |||
| ELSE IF( NRHS.LT.0 ) THEN | |||
| INFO = -3 | |||
| ELSE IF( LDA.LT.MAX( 1, N ) ) THEN | |||
| INFO = -5 | |||
| ELSE IF( LDB.LT.MAX( 1, N ) ) THEN | |||
| INFO = -8 | |||
| ELSE IF( LWORK.LT.1 .AND. .NOT.LQUERY ) THEN | |||
| INFO = -10 | |||
| END IF | |||
| * | |||
| IF( INFO.EQ.0 ) THEN | |||
| IF( N.EQ.0 ) THEN | |||
| LWKOPT = 1 | |||
| ELSE | |||
| CALL DSYTRF_ROOK( UPLO, N, A, LDA, IPIV, WORK, -1, INFO ) | |||
| LWKOPT = WORK(1) | |||
| END IF | |||
| WORK( 1 ) = LWKOPT | |||
| END IF | |||
| * | |||
| IF( INFO.NE.0 ) THEN | |||
| CALL XERBLA( 'DSYSV_ROOK ', -INFO ) | |||
| RETURN | |||
| ELSE IF( LQUERY ) THEN | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Compute the factorization A = U*D*U**T or A = L*D*L**T. | |||
| * | |||
| CALL DSYTRF_ROOK( UPLO, N, A, LDA, IPIV, WORK, LWORK, INFO ) | |||
| IF( INFO.EQ.0 ) THEN | |||
| * | |||
| * Solve the system A*X = B, overwriting B with X. | |||
| * | |||
| * Solve with TRS_ROOK ( Use Level 2 BLAS) | |||
| * | |||
| CALL DSYTRS_ROOK( UPLO, N, NRHS, A, LDA, IPIV, B, LDB, INFO ) | |||
| * | |||
| END IF | |||
| * | |||
| WORK( 1 ) = LWKOPT | |||
| * | |||
| RETURN | |||
| * | |||
| * End of DSYSV_ROOK | |||
| * | |||
| END | |||
| @@ -90,13 +90,22 @@ | |||
| *> \verbatim | |||
| *> IPIV is INTEGER array, dimension (N) | |||
| *> Details of the interchanges and the block structure of D. | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) were | |||
| *> interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> If UPLO = 'U' and IPIV(k) = IPIV(k-1) < 0, then rows and | |||
| *> columns k-1 and -IPIV(k) were interchanged and D(k-1:k,k-1:k) | |||
| *> is a 2-by-2 diagonal block. If UPLO = 'L' and IPIV(k) = | |||
| *> IPIV(k+1) < 0, then rows and columns k+1 and -IPIV(k) were | |||
| *> interchanged and D(k:k+1,k:k+1) is a 2-by-2 diagonal block. | |||
| *> | |||
| *> If UPLO = 'U': | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) were | |||
| *> interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) = IPIV(k-1) < 0, then rows and columns | |||
| *> k-1 and -IPIV(k) were interchanged and D(k-1:k,k-1:k) | |||
| *> is a 2-by-2 diagonal block. | |||
| *> | |||
| *> If UPLO = 'L': | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) were | |||
| *> interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) = IPIV(k+1) < 0, then rows and columns | |||
| *> k+1 and -IPIV(k) were interchanged and D(k:k+1,k:k+1) | |||
| *> is a 2-by-2 diagonal block. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] INFO | |||
| @@ -118,7 +127,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date September 2012 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup doubleSYcomputational | |||
| * | |||
| @@ -185,10 +194,10 @@ | |||
| * ===================================================================== | |||
| SUBROUTINE DSYTF2( UPLO, N, A, LDA, IPIV, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.2) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * September 2012 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER UPLO | |||
| @@ -268,7 +277,8 @@ | |||
| ABSAKK = ABS( A( K, K ) ) | |||
| * | |||
| * IMAX is the row-index of the largest off-diagonal element in | |||
| * column K, and COLMAX is its absolute value | |||
| * column K, and COLMAX is its absolute value. | |||
| * Determine both COLMAX and IMAX. | |||
| * | |||
| IF( K.GT.1 ) THEN | |||
| IMAX = IDAMAX( K-1, A( 1, K ), 1 ) | |||
| @@ -279,7 +289,8 @@ | |||
| * | |||
| IF( (MAX( ABSAKK, COLMAX ).EQ.ZERO) .OR. DISNAN(ABSAKK) ) THEN | |||
| * | |||
| * Column K is zero or contains a NaN: set INFO and continue | |||
| * Column K is zero or underflow, or contains a NaN: | |||
| * set INFO and continue | |||
| * | |||
| IF( INFO.EQ.0 ) | |||
| $ INFO = K | |||
| @@ -436,7 +447,8 @@ | |||
| ABSAKK = ABS( A( K, K ) ) | |||
| * | |||
| * IMAX is the row-index of the largest off-diagonal element in | |||
| * column K, and COLMAX is its absolute value | |||
| * column K, and COLMAX is its absolute value. | |||
| * Determine both COLMAX and IMAX. | |||
| * | |||
| IF( K.LT.N ) THEN | |||
| IMAX = K + IDAMAX( N-K, A( K+1, K ), 1 ) | |||
| @@ -447,7 +459,8 @@ | |||
| * | |||
| IF( (MAX( ABSAKK, COLMAX ).EQ.ZERO) .OR. DISNAN(ABSAKK) ) THEN | |||
| * | |||
| * Column K is zero or contains a NaN: set INFO and continue | |||
| * Column K is zero or underflow, or contains a NaN: | |||
| * set INFO and continue | |||
| * | |||
| IF( INFO.EQ.0 ) | |||
| $ INFO = K | |||
| @@ -0,0 +1,813 @@ | |||
| *> \brief \b DSYTF2_ROOK computes the factorization of a real symmetric indefinite matrix using the bounded Bunch-Kaufman ("rook") diagonal pivoting method (unblocked algorithm). | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download DSYTF2_ROOK + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsytf2_rook.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsytf2_rook.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsytf2_rook.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE DSYTF2_ROOK( UPLO, N, A, LDA, IPIV, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * CHARACTER UPLO | |||
| * INTEGER INFO, LDA, N | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * INTEGER IPIV( * ) | |||
| * DOUBLE PRECISION A( LDA, * ) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| * ============= | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> DSYTF2_ROOK computes the factorization of a real symmetric matrix A | |||
| *> using the bounded Bunch-Kaufman ("rook") diagonal pivoting method: | |||
| *> | |||
| *> A = U*D*U**T or A = L*D*L**T | |||
| *> | |||
| *> where U (or L) is a product of permutation and unit upper (lower) | |||
| *> triangular matrices, U**T is the transpose of U, and D is symmetric and | |||
| *> block diagonal with 1-by-1 and 2-by-2 diagonal blocks. | |||
| *> | |||
| *> This is the unblocked version of the algorithm, calling Level 2 BLAS. | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] UPLO | |||
| *> \verbatim | |||
| *> UPLO is CHARACTER*1 | |||
| *> Specifies whether the upper or lower triangular part of the | |||
| *> symmetric matrix A is stored: | |||
| *> = 'U': Upper triangular | |||
| *> = 'L': Lower triangular | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] N | |||
| *> \verbatim | |||
| *> N is INTEGER | |||
| *> The order of the matrix A. N >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] A | |||
| *> \verbatim | |||
| *> A is DOUBLE PRECISION 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 | |||
| *> triangular part of A is not referenced. If UPLO = 'L', the | |||
| *> leading n-by-n lower triangular part of A contains the lower | |||
| *> triangular part of the matrix A, and the strictly upper | |||
| *> triangular part of A is not referenced. | |||
| *> | |||
| *> On exit, the block diagonal matrix D and the multipliers used | |||
| *> to obtain the factor U or L (see below for further details). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDA | |||
| *> \verbatim | |||
| *> LDA is INTEGER | |||
| *> The leading dimension of the array A. LDA >= max(1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] IPIV | |||
| *> \verbatim | |||
| *> IPIV is INTEGER array, dimension (N) | |||
| *> Details of the interchanges and the block structure of D. | |||
| *> | |||
| *> If UPLO = 'U': | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) | |||
| *> were interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) < 0 and IPIV(k-1) < 0, then rows and | |||
| *> columns k and -IPIV(k) were interchanged and rows and | |||
| *> columns k-1 and -IPIV(k-1) were inerchaged, | |||
| *> D(k-1:k,k-1:k) is a 2-by-2 diagonal block. | |||
| *> | |||
| *> If UPLO = 'L': | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) | |||
| *> were interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) < 0 and IPIV(k+1) < 0, then rows and | |||
| *> columns k and -IPIV(k) were interchanged and rows and | |||
| *> columns k+1 and -IPIV(k+1) were inerchaged, | |||
| *> D(k:k+1,k:k+1) is a 2-by-2 diagonal block. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] INFO | |||
| *> \verbatim | |||
| *> INFO is INTEGER | |||
| *> = 0: successful exit | |||
| *> < 0: if INFO = -k, the k-th argument had an illegal value | |||
| *> > 0: if INFO = k, D(k,k) is exactly zero. The factorization | |||
| *> has been completed, but the block diagonal matrix D is | |||
| *> exactly singular, and division by zero will occur if it | |||
| *> is used to solve a system of equations. | |||
| *> \endverbatim | |||
| * | |||
| * Authors: | |||
| * ======== | |||
| * | |||
| *> \author Univ. of Tennessee | |||
| *> \author Univ. of California Berkeley | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup doubleSYcomputational | |||
| * | |||
| *> \par Further Details: | |||
| * ===================== | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> If UPLO = 'U', then A = U*D*U**T, where | |||
| *> U = P(n)*U(n)* ... *P(k)U(k)* ..., | |||
| *> i.e., U is a product of terms P(k)*U(k), where k decreases from n to | |||
| *> 1 in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1 | |||
| *> and 2-by-2 diagonal blocks D(k). P(k) is a permutation matrix as | |||
| *> defined by IPIV(k), and U(k) is a unit upper triangular matrix, such | |||
| *> that if the diagonal block D(k) is of order s (s = 1 or 2), then | |||
| *> | |||
| *> ( I v 0 ) k-s | |||
| *> U(k) = ( 0 I 0 ) s | |||
| *> ( 0 0 I ) n-k | |||
| *> k-s s n-k | |||
| *> | |||
| *> If s = 1, D(k) overwrites A(k,k), and v overwrites A(1:k-1,k). | |||
| *> If s = 2, the upper triangle of D(k) overwrites A(k-1,k-1), A(k-1,k), | |||
| *> and A(k,k), and v overwrites A(1:k-2,k-1:k). | |||
| *> | |||
| *> If UPLO = 'L', then A = L*D*L**T, where | |||
| *> L = P(1)*L(1)* ... *P(k)*L(k)* ..., | |||
| *> i.e., L is a product of terms P(k)*L(k), where k increases from 1 to | |||
| *> n in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1 | |||
| *> and 2-by-2 diagonal blocks D(k). P(k) is a permutation matrix as | |||
| *> defined by IPIV(k), and L(k) is a unit lower triangular matrix, such | |||
| *> that if the diagonal block D(k) is of order s (s = 1 or 2), then | |||
| *> | |||
| *> ( I 0 0 ) k-1 | |||
| *> L(k) = ( 0 I 0 ) s | |||
| *> ( 0 v I ) n-k-s+1 | |||
| *> k-1 s n-k-s+1 | |||
| *> | |||
| *> If s = 1, D(k) overwrites A(k,k), and v overwrites A(k+1:n,k). | |||
| *> If s = 2, the lower triangle of D(k) overwrites A(k,k), A(k+1,k), | |||
| *> and A(k+1,k+1), and v overwrites A(k+2:n,k:k+1). | |||
| *> \endverbatim | |||
| * | |||
| *> \par Contributors: | |||
| * ================== | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> November 2013, Igor Kozachenko, | |||
| *> Computer Science Division, | |||
| *> University of California, Berkeley | |||
| *> | |||
| *> September 2007, Sven Hammarling, Nicholas J. Higham, Craig Lucas, | |||
| *> School of Mathematics, | |||
| *> University of Manchester | |||
| *> | |||
| *> 01-01-96 - Based on modifications by | |||
| *> J. Lewis, Boeing Computer Services Company | |||
| *> A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville abd , USA | |||
| *> \endverbatim | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE DSYTF2_ROOK( UPLO, N, A, LDA, IPIV, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER UPLO | |||
| INTEGER INFO, LDA, N | |||
| * .. | |||
| * .. Array Arguments .. | |||
| INTEGER IPIV( * ) | |||
| DOUBLE PRECISION A( LDA, * ) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| DOUBLE PRECISION ZERO, ONE | |||
| PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 ) | |||
| DOUBLE PRECISION EIGHT, SEVTEN | |||
| PARAMETER ( EIGHT = 8.0D+0, SEVTEN = 17.0D+0 ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| LOGICAL UPPER, DONE | |||
| INTEGER I, IMAX, J, JMAX, ITEMP, K, KK, KP, KSTEP, | |||
| $ P, II | |||
| DOUBLE PRECISION ABSAKK, ALPHA, COLMAX, D11, D12, D21, D22, | |||
| $ ROWMAX, DTEMP, T, WK, WKM1, WKP1, SFMIN | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| INTEGER IDAMAX | |||
| DOUBLE PRECISION DLAMCH | |||
| EXTERNAL LSAME, IDAMAX, DLAMCH | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL DSCAL, DSWAP, DSYR, XERBLA | |||
| * .. | |||
| * .. Intrinsic Functions .. | |||
| INTRINSIC ABS, MAX, SQRT | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Test the input parameters. | |||
| * | |||
| INFO = 0 | |||
| UPPER = LSAME( UPLO, 'U' ) | |||
| IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN | |||
| INFO = -1 | |||
| ELSE IF( N.LT.0 ) THEN | |||
| INFO = -2 | |||
| ELSE IF( LDA.LT.MAX( 1, N ) ) THEN | |||
| INFO = -4 | |||
| END IF | |||
| IF( INFO.NE.0 ) THEN | |||
| CALL XERBLA( 'DSYTF2_ROOK', -INFO ) | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Initialize ALPHA for use in choosing pivot block size. | |||
| * | |||
| ALPHA = ( ONE+SQRT( SEVTEN ) ) / EIGHT | |||
| * | |||
| * Compute machine safe minimum | |||
| * | |||
| SFMIN = DLAMCH( 'S' ) | |||
| * | |||
| IF( UPPER ) THEN | |||
| * | |||
| * Factorize A as U*D*U**T using the upper triangle of A | |||
| * | |||
| * K is the main loop index, decreasing from N to 1 in steps of | |||
| * 1 or 2 | |||
| * | |||
| K = N | |||
| 10 CONTINUE | |||
| * | |||
| * If K < 1, exit from loop | |||
| * | |||
| IF( K.LT.1 ) | |||
| $ GO TO 70 | |||
| KSTEP = 1 | |||
| P = K | |||
| * | |||
| * Determine rows and columns to be interchanged and whether | |||
| * a 1-by-1 or 2-by-2 pivot block will be used | |||
| * | |||
| ABSAKK = ABS( A( K, K ) ) | |||
| * | |||
| * IMAX is the row-index of the largest off-diagonal element in | |||
| * column K, and COLMAX is its absolute value. | |||
| * Determine both COLMAX and IMAX. | |||
| * | |||
| IF( K.GT.1 ) THEN | |||
| IMAX = IDAMAX( K-1, A( 1, K ), 1 ) | |||
| COLMAX = ABS( A( IMAX, K ) ) | |||
| ELSE | |||
| COLMAX = ZERO | |||
| END IF | |||
| * | |||
| IF( (MAX( ABSAKK, COLMAX ).EQ.ZERO) ) THEN | |||
| * | |||
| * Column K is zero or underflow: set INFO and continue | |||
| * | |||
| IF( INFO.EQ.0 ) | |||
| $ INFO = K | |||
| KP = K | |||
| ELSE | |||
| * | |||
| * Test for interchange | |||
| * | |||
| * Equivalent to testing for (used to handle NaN and Inf) | |||
| * ABSAKK.GE.ALPHA*COLMAX | |||
| * | |||
| IF( .NOT.( ABSAKK.LT.ALPHA*COLMAX ) ) THEN | |||
| * | |||
| * no interchange, | |||
| * use 1-by-1 pivot block | |||
| * | |||
| KP = K | |||
| ELSE | |||
| * | |||
| DONE = .FALSE. | |||
| * | |||
| * Loop until pivot found | |||
| * | |||
| 12 CONTINUE | |||
| * | |||
| * Begin pivot search loop body | |||
| * | |||
| * JMAX is the column-index of the largest off-diagonal | |||
| * element in row IMAX, and ROWMAX is its absolute value. | |||
| * Determine both ROWMAX and JMAX. | |||
| * | |||
| IF( IMAX.NE.K ) THEN | |||
| JMAX = IMAX + IDAMAX( K-IMAX, A( IMAX, IMAX+1 ), | |||
| $ LDA ) | |||
| ROWMAX = ABS( A( IMAX, JMAX ) ) | |||
| ELSE | |||
| ROWMAX = ZERO | |||
| END IF | |||
| * | |||
| IF( IMAX.GT.1 ) THEN | |||
| ITEMP = IDAMAX( IMAX-1, A( 1, IMAX ), 1 ) | |||
| DTEMP = ABS( A( ITEMP, IMAX ) ) | |||
| IF( DTEMP.GT.ROWMAX ) THEN | |||
| ROWMAX = DTEMP | |||
| JMAX = ITEMP | |||
| END IF | |||
| END IF | |||
| * | |||
| * Equivalent to testing for (used to handle NaN and Inf) | |||
| * ABS( A( IMAX, IMAX ) ).GE.ALPHA*ROWMAX | |||
| * | |||
| IF( .NOT.( ABS( A( IMAX, IMAX ) ).LT.ALPHA*ROWMAX ) ) | |||
| $ THEN | |||
| * | |||
| * interchange rows and columns K and IMAX, | |||
| * use 1-by-1 pivot block | |||
| * | |||
| KP = IMAX | |||
| DONE = .TRUE. | |||
| * | |||
| * Equivalent to testing for ROWMAX .EQ. COLMAX, | |||
| * used to handle NaN and Inf | |||
| * | |||
| ELSE IF( ( P.EQ.JMAX ).OR.( ROWMAX.LE.COLMAX ) ) THEN | |||
| * | |||
| * interchange rows and columns K+1 and IMAX, | |||
| * use 2-by-2 pivot block | |||
| * | |||
| KP = IMAX | |||
| KSTEP = 2 | |||
| DONE = .TRUE. | |||
| ELSE | |||
| * | |||
| * Pivot NOT found, set variables and repeat | |||
| * | |||
| P = IMAX | |||
| COLMAX = ROWMAX | |||
| IMAX = JMAX | |||
| END IF | |||
| * | |||
| * End pivot search loop body | |||
| * | |||
| IF( .NOT. DONE ) GOTO 12 | |||
| * | |||
| END IF | |||
| * | |||
| * Swap TWO rows and TWO columns | |||
| * | |||
| * First swap | |||
| * | |||
| IF( ( KSTEP.EQ.2 ) .AND. ( P.NE.K ) ) THEN | |||
| * | |||
| * Interchange rows and column K and P in the leading | |||
| * submatrix A(1:k,1:k) if we have a 2-by-2 pivot | |||
| * | |||
| IF( P.GT.1 ) | |||
| $ CALL DSWAP( P-1, A( 1, K ), 1, A( 1, P ), 1 ) | |||
| IF( P.LT.(K-1) ) | |||
| $ CALL DSWAP( K-P-1, A( P+1, K ), 1, A( P, P+1 ), | |||
| $ LDA ) | |||
| T = A( K, K ) | |||
| A( K, K ) = A( P, P ) | |||
| A( P, P ) = T | |||
| END IF | |||
| * | |||
| * Second swap | |||
| * | |||
| KK = K - KSTEP + 1 | |||
| IF( KP.NE.KK ) THEN | |||
| * | |||
| * Interchange rows and columns KK and KP in the leading | |||
| * submatrix A(1:k,1:k) | |||
| * | |||
| IF( KP.GT.1 ) | |||
| $ CALL DSWAP( KP-1, A( 1, KK ), 1, A( 1, KP ), 1 ) | |||
| IF( ( KK.GT.1 ) .AND. ( KP.LT.(KK-1) ) ) | |||
| $ CALL DSWAP( KK-KP-1, A( KP+1, KK ), 1, A( KP, KP+1 ), | |||
| $ LDA ) | |||
| T = A( KK, KK ) | |||
| A( KK, KK ) = A( KP, KP ) | |||
| A( KP, KP ) = T | |||
| IF( KSTEP.EQ.2 ) THEN | |||
| T = A( K-1, K ) | |||
| A( K-1, K ) = A( KP, K ) | |||
| A( KP, K ) = T | |||
| END IF | |||
| END IF | |||
| * | |||
| * Update the leading submatrix | |||
| * | |||
| IF( KSTEP.EQ.1 ) THEN | |||
| * | |||
| * 1-by-1 pivot block D(k): column k now holds | |||
| * | |||
| * W(k) = U(k)*D(k) | |||
| * | |||
| * where U(k) is the k-th column of U | |||
| * | |||
| IF( K.GT.1 ) THEN | |||
| * | |||
| * Perform a rank-1 update of A(1:k-1,1:k-1) and | |||
| * store U(k) in column k | |||
| * | |||
| IF( ABS( A( K, K ) ).GE.SFMIN ) THEN | |||
| * | |||
| * Perform a rank-1 update of A(1:k-1,1:k-1) as | |||
| * A := A - U(k)*D(k)*U(k)**T | |||
| * = A - W(k)*1/D(k)*W(k)**T | |||
| * | |||
| D11 = ONE / A( K, K ) | |||
| CALL DSYR( UPLO, K-1, -D11, A( 1, K ), 1, A, LDA ) | |||
| * | |||
| * Store U(k) in column k | |||
| * | |||
| CALL DSCAL( K-1, D11, A( 1, K ), 1 ) | |||
| ELSE | |||
| * | |||
| * Store L(k) in column K | |||
| * | |||
| D11 = A( K, K ) | |||
| DO 16 II = 1, K - 1 | |||
| A( II, K ) = A( II, K ) / D11 | |||
| 16 CONTINUE | |||
| * | |||
| * Perform a rank-1 update of A(k+1:n,k+1:n) as | |||
| * A := A - U(k)*D(k)*U(k)**T | |||
| * = A - W(k)*(1/D(k))*W(k)**T | |||
| * = A - (W(k)/D(k))*(D(k))*(W(k)/D(K))**T | |||
| * | |||
| CALL DSYR( UPLO, K-1, -D11, A( 1, K ), 1, A, LDA ) | |||
| END IF | |||
| END IF | |||
| * | |||
| ELSE | |||
| * | |||
| * 2-by-2 pivot block D(k): columns k and k-1 now hold | |||
| * | |||
| * ( W(k-1) W(k) ) = ( U(k-1) U(k) )*D(k) | |||
| * | |||
| * where U(k) and U(k-1) are the k-th and (k-1)-th columns | |||
| * of U | |||
| * | |||
| * Perform a rank-2 update of A(1:k-2,1:k-2) as | |||
| * | |||
| * A := A - ( U(k-1) U(k) )*D(k)*( U(k-1) U(k) )**T | |||
| * = A - ( ( A(k-1)A(k) )*inv(D(k)) ) * ( A(k-1)A(k) )**T | |||
| * | |||
| * and store L(k) and L(k+1) in columns k and k+1 | |||
| * | |||
| IF( K.GT.2 ) THEN | |||
| * | |||
| D12 = A( K-1, K ) | |||
| D22 = A( K-1, K-1 ) / D12 | |||
| D11 = A( K, K ) / D12 | |||
| T = ONE / ( D11*D22-ONE ) | |||
| * | |||
| DO 30 J = K - 2, 1, -1 | |||
| * | |||
| WKM1 = T*( D11*A( J, K-1 )-A( J, K ) ) | |||
| WK = T*( D22*A( J, K )-A( J, K-1 ) ) | |||
| * | |||
| DO 20 I = J, 1, -1 | |||
| A( I, J ) = A( I, J ) - (A( I, K ) / D12 )*WK - | |||
| $ ( A( I, K-1 ) / D12 )*WKM1 | |||
| 20 CONTINUE | |||
| * | |||
| * Store U(k) and U(k-1) in cols k and k-1 for row J | |||
| * | |||
| A( J, K ) = WK / D12 | |||
| A( J, K-1 ) = WKM1 / D12 | |||
| * | |||
| 30 CONTINUE | |||
| * | |||
| END IF | |||
| * | |||
| END IF | |||
| END IF | |||
| * | |||
| * Store details of the interchanges in IPIV | |||
| * | |||
| IF( KSTEP.EQ.1 ) THEN | |||
| IPIV( K ) = KP | |||
| ELSE | |||
| IPIV( K ) = -P | |||
| IPIV( K-1 ) = -KP | |||
| END IF | |||
| * | |||
| * Decrease K and return to the start of the main loop | |||
| * | |||
| K = K - KSTEP | |||
| GO TO 10 | |||
| * | |||
| ELSE | |||
| * | |||
| * Factorize A as L*D*L**T using the lower triangle of A | |||
| * | |||
| * K is the main loop index, increasing from 1 to N in steps of | |||
| * 1 or 2 | |||
| * | |||
| K = 1 | |||
| 40 CONTINUE | |||
| * | |||
| * If K > N, exit from loop | |||
| * | |||
| IF( K.GT.N ) | |||
| $ GO TO 70 | |||
| KSTEP = 1 | |||
| P = K | |||
| * | |||
| * Determine rows and columns to be interchanged and whether | |||
| * a 1-by-1 or 2-by-2 pivot block will be used | |||
| * | |||
| ABSAKK = ABS( A( K, K ) ) | |||
| * | |||
| * IMAX is the row-index of the largest off-diagonal element in | |||
| * column K, and COLMAX is its absolute value. | |||
| * Determine both COLMAX and IMAX. | |||
| * | |||
| IF( K.LT.N ) THEN | |||
| IMAX = K + IDAMAX( N-K, A( K+1, K ), 1 ) | |||
| COLMAX = ABS( A( IMAX, K ) ) | |||
| ELSE | |||
| COLMAX = ZERO | |||
| END IF | |||
| * | |||
| IF( ( MAX( ABSAKK, COLMAX ).EQ.ZERO ) ) THEN | |||
| * | |||
| * Column K is zero or underflow: set INFO and continue | |||
| * | |||
| IF( INFO.EQ.0 ) | |||
| $ INFO = K | |||
| KP = K | |||
| ELSE | |||
| * | |||
| * Test for interchange | |||
| * | |||
| * Equivalent to testing for (used to handle NaN and Inf) | |||
| * ABSAKK.GE.ALPHA*COLMAX | |||
| * | |||
| IF( .NOT.( ABSAKK.LT.ALPHA*COLMAX ) ) THEN | |||
| * | |||
| * no interchange, use 1-by-1 pivot block | |||
| * | |||
| KP = K | |||
| ELSE | |||
| * | |||
| DONE = .FALSE. | |||
| * | |||
| * Loop until pivot found | |||
| * | |||
| 42 CONTINUE | |||
| * | |||
| * Begin pivot search loop body | |||
| * | |||
| * JMAX is the column-index of the largest off-diagonal | |||
| * element in row IMAX, and ROWMAX is its absolute value. | |||
| * Determine both ROWMAX and JMAX. | |||
| * | |||
| IF( IMAX.NE.K ) THEN | |||
| JMAX = K - 1 + IDAMAX( IMAX-K, A( IMAX, K ), LDA ) | |||
| ROWMAX = ABS( A( IMAX, JMAX ) ) | |||
| ELSE | |||
| ROWMAX = ZERO | |||
| END IF | |||
| * | |||
| IF( IMAX.LT.N ) THEN | |||
| ITEMP = IMAX + IDAMAX( N-IMAX, A( IMAX+1, IMAX ), | |||
| $ 1 ) | |||
| DTEMP = ABS( A( ITEMP, IMAX ) ) | |||
| IF( DTEMP.GT.ROWMAX ) THEN | |||
| ROWMAX = DTEMP | |||
| JMAX = ITEMP | |||
| END IF | |||
| END IF | |||
| * | |||
| * Equivalent to testing for (used to handle NaN and Inf) | |||
| * ABS( A( IMAX, IMAX ) ).GE.ALPHA*ROWMAX | |||
| * | |||
| IF( .NOT.( ABS( A( IMAX, IMAX ) ).LT.ALPHA*ROWMAX ) ) | |||
| $ THEN | |||
| * | |||
| * interchange rows and columns K and IMAX, | |||
| * use 1-by-1 pivot block | |||
| * | |||
| KP = IMAX | |||
| DONE = .TRUE. | |||
| * | |||
| * Equivalent to testing for ROWMAX .EQ. COLMAX, | |||
| * used to handle NaN and Inf | |||
| * | |||
| ELSE IF( ( P.EQ.JMAX ).OR.( ROWMAX.LE.COLMAX ) ) THEN | |||
| * | |||
| * interchange rows and columns K+1 and IMAX, | |||
| * use 2-by-2 pivot block | |||
| * | |||
| KP = IMAX | |||
| KSTEP = 2 | |||
| DONE = .TRUE. | |||
| ELSE | |||
| * | |||
| * Pivot NOT found, set variables and repeat | |||
| * | |||
| P = IMAX | |||
| COLMAX = ROWMAX | |||
| IMAX = JMAX | |||
| END IF | |||
| * | |||
| * End pivot search loop body | |||
| * | |||
| IF( .NOT. DONE ) GOTO 42 | |||
| * | |||
| END IF | |||
| * | |||
| * Swap TWO rows and TWO columns | |||
| * | |||
| * First swap | |||
| * | |||
| IF( ( KSTEP.EQ.2 ) .AND. ( P.NE.K ) ) THEN | |||
| * | |||
| * Interchange rows and column K and P in the trailing | |||
| * submatrix A(k:n,k:n) if we have a 2-by-2 pivot | |||
| * | |||
| IF( P.LT.N ) | |||
| $ CALL DSWAP( N-P, A( P+1, K ), 1, A( P+1, P ), 1 ) | |||
| IF( P.GT.(K+1) ) | |||
| $ CALL DSWAP( P-K-1, A( K+1, K ), 1, A( P, K+1 ), LDA ) | |||
| T = A( K, K ) | |||
| A( K, K ) = A( P, P ) | |||
| A( P, P ) = T | |||
| END IF | |||
| * | |||
| * Second swap | |||
| * | |||
| KK = K + KSTEP - 1 | |||
| IF( KP.NE.KK ) THEN | |||
| * | |||
| * Interchange rows and columns KK and KP in the trailing | |||
| * submatrix A(k:n,k:n) | |||
| * | |||
| IF( KP.LT.N ) | |||
| $ CALL DSWAP( N-KP, A( KP+1, KK ), 1, A( KP+1, KP ), 1 ) | |||
| IF( ( KK.LT.N ) .AND. ( KP.GT.(KK+1) ) ) | |||
| $ CALL DSWAP( KP-KK-1, A( KK+1, KK ), 1, A( KP, KK+1 ), | |||
| $ LDA ) | |||
| T = A( KK, KK ) | |||
| A( KK, KK ) = A( KP, KP ) | |||
| A( KP, KP ) = T | |||
| IF( KSTEP.EQ.2 ) THEN | |||
| T = A( K+1, K ) | |||
| A( K+1, K ) = A( KP, K ) | |||
| A( KP, K ) = T | |||
| END IF | |||
| END IF | |||
| * | |||
| * Update the trailing submatrix | |||
| * | |||
| IF( KSTEP.EQ.1 ) THEN | |||
| * | |||
| * 1-by-1 pivot block D(k): column k now holds | |||
| * | |||
| * W(k) = L(k)*D(k) | |||
| * | |||
| * where L(k) is the k-th column of L | |||
| * | |||
| IF( K.LT.N ) THEN | |||
| * | |||
| * Perform a rank-1 update of A(k+1:n,k+1:n) and | |||
| * store L(k) in column k | |||
| * | |||
| IF( ABS( A( K, K ) ).GE.SFMIN ) THEN | |||
| * | |||
| * Perform a rank-1 update of A(k+1:n,k+1:n) as | |||
| * A := A - L(k)*D(k)*L(k)**T | |||
| * = A - W(k)*(1/D(k))*W(k)**T | |||
| * | |||
| D11 = ONE / A( K, K ) | |||
| CALL DSYR( UPLO, N-K, -D11, A( K+1, K ), 1, | |||
| $ A( K+1, K+1 ), LDA ) | |||
| * | |||
| * Store L(k) in column k | |||
| * | |||
| CALL DSCAL( N-K, D11, A( K+1, K ), 1 ) | |||
| ELSE | |||
| * | |||
| * Store L(k) in column k | |||
| * | |||
| D11 = A( K, K ) | |||
| DO 46 II = K + 1, N | |||
| A( II, K ) = A( II, K ) / D11 | |||
| 46 CONTINUE | |||
| * | |||
| * Perform a rank-1 update of A(k+1:n,k+1:n) as | |||
| * A := A - L(k)*D(k)*L(k)**T | |||
| * = A - W(k)*(1/D(k))*W(k)**T | |||
| * = A - (W(k)/D(k))*(D(k))*(W(k)/D(K))**T | |||
| * | |||
| CALL DSYR( UPLO, N-K, -D11, A( K+1, K ), 1, | |||
| $ A( K+1, K+1 ), LDA ) | |||
| END IF | |||
| END IF | |||
| * | |||
| ELSE | |||
| * | |||
| * 2-by-2 pivot block D(k): columns k and k+1 now hold | |||
| * | |||
| * ( W(k) W(k+1) ) = ( L(k) L(k+1) )*D(k) | |||
| * | |||
| * where L(k) and L(k+1) are the k-th and (k+1)-th columns | |||
| * of L | |||
| * | |||
| * | |||
| * Perform a rank-2 update of A(k+2:n,k+2:n) as | |||
| * | |||
| * A := A - ( L(k) L(k+1) ) * D(k) * ( L(k) L(k+1) )**T | |||
| * = A - ( ( A(k)A(k+1) )*inv(D(k) ) * ( A(k)A(k+1) )**T | |||
| * | |||
| * and store L(k) and L(k+1) in columns k and k+1 | |||
| * | |||
| IF( K.LT.N-1 ) THEN | |||
| * | |||
| D21 = A( K+1, K ) | |||
| D11 = A( K+1, K+1 ) / D21 | |||
| D22 = A( K, K ) / D21 | |||
| T = ONE / ( D11*D22-ONE ) | |||
| * | |||
| DO 60 J = K + 2, N | |||
| * | |||
| * Compute D21 * ( W(k)W(k+1) ) * inv(D(k)) for row J | |||
| * | |||
| WK = T*( D11*A( J, K )-A( J, K+1 ) ) | |||
| WKP1 = T*( D22*A( J, K+1 )-A( J, K ) ) | |||
| * | |||
| * Perform a rank-2 update of A(k+2:n,k+2:n) | |||
| * | |||
| DO 50 I = J, N | |||
| A( I, J ) = A( I, J ) - ( A( I, K ) / D21 )*WK - | |||
| $ ( A( I, K+1 ) / D21 )*WKP1 | |||
| 50 CONTINUE | |||
| * | |||
| * Store L(k) and L(k+1) in cols k and k+1 for row J | |||
| * | |||
| A( J, K ) = WK / D21 | |||
| A( J, K+1 ) = WKP1 / D21 | |||
| * | |||
| 60 CONTINUE | |||
| * | |||
| END IF | |||
| * | |||
| END IF | |||
| END IF | |||
| * | |||
| * Store details of the interchanges in IPIV | |||
| * | |||
| IF( KSTEP.EQ.1 ) THEN | |||
| IPIV( K ) = KP | |||
| ELSE | |||
| IPIV( K ) = -P | |||
| IPIV( K+1 ) = -KP | |||
| END IF | |||
| * | |||
| * Increase K and return to the start of the main loop | |||
| * | |||
| K = K + KSTEP | |||
| GO TO 40 | |||
| * | |||
| END IF | |||
| * | |||
| 70 CONTINUE | |||
| * | |||
| RETURN | |||
| * | |||
| * End of DSYTF2_ROOK | |||
| * | |||
| END | |||
| @@ -0,0 +1,393 @@ | |||
| *> \brief \b DSYTRF_ROOK | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download DSYTRF_ROOK + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsytrf_rook.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsytrf_rook.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsytrf_rook.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE DSYTRF_ROOK( UPLO, N, A, LDA, IPIV, WORK, LWORK, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * CHARACTER UPLO | |||
| * INTEGER INFO, LDA, LWORK, N | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * INTEGER IPIV( * ) | |||
| * DOUBLE PRECISION A( LDA, * ), WORK( * ) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| * ============= | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> DSYTRF_ROOK computes the factorization of a real symmetric matrix A | |||
| *> using the bounded Bunch-Kaufman ("rook") diagonal pivoting method. | |||
| *> The form of the factorization is | |||
| *> | |||
| *> A = U*D*U**T or A = L*D*L**T | |||
| *> | |||
| *> where U (or L) is a product of permutation and unit upper (lower) | |||
| *> triangular matrices, and D is symmetric and block diagonal with | |||
| *> 1-by-1 and 2-by-2 diagonal blocks. | |||
| *> | |||
| *> This is the blocked version of the algorithm, calling Level 3 BLAS. | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] UPLO | |||
| *> \verbatim | |||
| *> UPLO is CHARACTER*1 | |||
| *> = 'U': Upper triangle of A is stored; | |||
| *> = 'L': Lower triangle of A is stored. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] N | |||
| *> \verbatim | |||
| *> N is INTEGER | |||
| *> The order of the matrix A. N >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] A | |||
| *> \verbatim | |||
| *> A is DOUBLE PRECISION 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 | |||
| *> triangular part of A is not referenced. If UPLO = 'L', the | |||
| *> leading N-by-N lower triangular part of A contains the lower | |||
| *> triangular part of the matrix A, and the strictly upper | |||
| *> triangular part of A is not referenced. | |||
| *> | |||
| *> On exit, the block diagonal matrix D and the multipliers used | |||
| *> to obtain the factor U or L (see below for further details). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDA | |||
| *> \verbatim | |||
| *> LDA is INTEGER | |||
| *> The leading dimension of the array A. LDA >= max(1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] IPIV | |||
| *> \verbatim | |||
| *> IPIV is INTEGER array, dimension (N) | |||
| *> Details of the interchanges and the block structure of D. | |||
| *> | |||
| *> If UPLO = 'U': | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) | |||
| *> were interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) < 0 and IPIV(k-1) < 0, then rows and | |||
| *> columns k and -IPIV(k) were interchanged and rows and | |||
| *> columns k-1 and -IPIV(k-1) were inerchaged, | |||
| *> D(k-1:k,k-1:k) is a 2-by-2 diagonal block. | |||
| *> | |||
| *> If UPLO = 'L': | |||
| *> If IPIV(k) > 0, then rows and columns k and IPIV(k) | |||
| *> were interchanged and D(k,k) is a 1-by-1 diagonal block. | |||
| *> | |||
| *> If IPIV(k) < 0 and IPIV(k+1) < 0, then rows and | |||
| *> columns k and -IPIV(k) were interchanged and rows and | |||
| *> columns k+1 and -IPIV(k+1) were inerchaged, | |||
| *> D(k:k+1,k:k+1) is a 2-by-2 diagonal block. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] WORK | |||
| *> \verbatim | |||
| *> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)). | |||
| *> On exit, if INFO = 0, WORK(1) returns the optimal LWORK. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LWORK | |||
| *> \verbatim | |||
| *> LWORK is INTEGER | |||
| *> The length of WORK. LWORK >=1. For best performance | |||
| *> LWORK >= N*NB, where NB is the block size returned by ILAENV. | |||
| *> | |||
| *> 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 | |||
| *> > 0: if INFO = i, D(i,i) is exactly zero. The factorization | |||
| *> has been completed, but the block diagonal matrix D is | |||
| *> exactly singular, and division by zero will occur if it | |||
| *> is used to solve a system of equations. | |||
| *> \endverbatim | |||
| * | |||
| * Authors: | |||
| * ======== | |||
| * | |||
| *> \author Univ. of Tennessee | |||
| *> \author Univ. of California Berkeley | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date April 2012 | |||
| * | |||
| *> \ingroup doubleSYcomputational | |||
| * | |||
| *> \par Further Details: | |||
| * ===================== | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> If UPLO = 'U', then A = U*D*U**T, where | |||
| *> U = P(n)*U(n)* ... *P(k)U(k)* ..., | |||
| *> i.e., U is a product of terms P(k)*U(k), where k decreases from n to | |||
| *> 1 in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1 | |||
| *> and 2-by-2 diagonal blocks D(k). P(k) is a permutation matrix as | |||
| *> defined by IPIV(k), and U(k) is a unit upper triangular matrix, such | |||
| *> that if the diagonal block D(k) is of order s (s = 1 or 2), then | |||
| *> | |||
| *> ( I v 0 ) k-s | |||
| *> U(k) = ( 0 I 0 ) s | |||
| *> ( 0 0 I ) n-k | |||
| *> k-s s n-k | |||
| *> | |||
| *> If s = 1, D(k) overwrites A(k,k), and v overwrites A(1:k-1,k). | |||
| *> If s = 2, the upper triangle of D(k) overwrites A(k-1,k-1), A(k-1,k), | |||
| *> and A(k,k), and v overwrites A(1:k-2,k-1:k). | |||
| *> | |||
| *> If UPLO = 'L', then A = L*D*L**T, where | |||
| *> L = P(1)*L(1)* ... *P(k)*L(k)* ..., | |||
| *> i.e., L is a product of terms P(k)*L(k), where k increases from 1 to | |||
| *> n in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1 | |||
| *> and 2-by-2 diagonal blocks D(k). P(k) is a permutation matrix as | |||
| *> defined by IPIV(k), and L(k) is a unit lower triangular matrix, such | |||
| *> that if the diagonal block D(k) is of order s (s = 1 or 2), then | |||
| *> | |||
| *> ( I 0 0 ) k-1 | |||
| *> L(k) = ( 0 I 0 ) s | |||
| *> ( 0 v I ) n-k-s+1 | |||
| *> k-1 s n-k-s+1 | |||
| *> | |||
| *> If s = 1, D(k) overwrites A(k,k), and v overwrites A(k+1:n,k). | |||
| *> If s = 2, the lower triangle of D(k) overwrites A(k,k), A(k+1,k), | |||
| *> and A(k+1,k+1), and v overwrites A(k+2:n,k:k+1). | |||
| *> \endverbatim | |||
| * | |||
| *> \par Contributors: | |||
| * ================== | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> April 2012, Igor Kozachenko, | |||
| *> Computer Science Division, | |||
| *> University of California, Berkeley | |||
| *> | |||
| *> September 2007, Sven Hammarling, Nicholas J. Higham, Craig Lucas, | |||
| *> School of Mathematics, | |||
| *> University of Manchester | |||
| *> | |||
| *> \endverbatim | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE DSYTRF_ROOK( UPLO, N, A, LDA, IPIV, WORK, LWORK, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.1) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * April 2012 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER UPLO | |||
| INTEGER INFO, LDA, LWORK, N | |||
| * .. | |||
| * .. Array Arguments .. | |||
| INTEGER IPIV( * ) | |||
| DOUBLE PRECISION A( LDA, * ), WORK( * ) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Local Scalars .. | |||
| LOGICAL LQUERY, UPPER | |||
| INTEGER IINFO, IWS, J, K, KB, LDWORK, LWKOPT, NB, NBMIN | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| INTEGER ILAENV | |||
| EXTERNAL LSAME, ILAENV | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL DLASYF_ROOK, DSYTF2_ROOK, XERBLA | |||
| * .. | |||
| * .. Intrinsic Functions .. | |||
| INTRINSIC MAX | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Test the input parameters. | |||
| * | |||
| INFO = 0 | |||
| UPPER = LSAME( UPLO, 'U' ) | |||
| LQUERY = ( LWORK.EQ.-1 ) | |||
| IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN | |||
| INFO = -1 | |||
| ELSE IF( N.LT.0 ) THEN | |||
| INFO = -2 | |||
| ELSE IF( LDA.LT.MAX( 1, N ) ) THEN | |||
| INFO = -4 | |||
| ELSE IF( LWORK.LT.1 .AND. .NOT.LQUERY ) THEN | |||
| INFO = -7 | |||
| END IF | |||
| * | |||
| IF( INFO.EQ.0 ) THEN | |||
| * | |||
| * Determine the block size | |||
| * | |||
| NB = ILAENV( 1, 'DSYTRF_ROOK', UPLO, N, -1, -1, -1 ) | |||
| LWKOPT = N*NB | |||
| WORK( 1 ) = LWKOPT | |||
| END IF | |||
| * | |||
| IF( INFO.NE.0 ) THEN | |||
| CALL XERBLA( 'DSYTRF_ROOK', -INFO ) | |||
| RETURN | |||
| ELSE IF( LQUERY ) THEN | |||
| RETURN | |||
| END IF | |||
| * | |||
| NBMIN = 2 | |||
| LDWORK = N | |||
| IF( NB.GT.1 .AND. NB.LT.N ) THEN | |||
| IWS = LDWORK*NB | |||
| IF( LWORK.LT.IWS ) THEN | |||
| NB = MAX( LWORK / LDWORK, 1 ) | |||
| NBMIN = MAX( 2, ILAENV( 2, 'DSYTRF_ROOK', | |||
| $ UPLO, N, -1, -1, -1 ) ) | |||
| END IF | |||
| ELSE | |||
| IWS = 1 | |||
| END IF | |||
| IF( NB.LT.NBMIN ) | |||
| $ NB = N | |||
| * | |||
| IF( UPPER ) THEN | |||
| * | |||
| * Factorize A as U*D*U**T using the upper triangle of A | |||
| * | |||
| * K is the main loop index, decreasing from N to 1 in steps of | |||
| * KB, where KB is the number of columns factorized by DLASYF_ROOK; | |||
| * KB is either NB or NB-1, or K for the last block | |||
| * | |||
| K = N | |||
| 10 CONTINUE | |||
| * | |||
| * If K < 1, exit from loop | |||
| * | |||
| IF( K.LT.1 ) | |||
| $ GO TO 40 | |||
| * | |||
| IF( K.GT.NB ) THEN | |||
| * | |||
| * Factorize columns k-kb+1:k of A and use blocked code to | |||
| * update columns 1:k-kb | |||
| * | |||
| CALL DLASYF_ROOK( UPLO, K, NB, KB, A, LDA, | |||
| $ IPIV, WORK, LDWORK, IINFO ) | |||
| ELSE | |||
| * | |||
| * Use unblocked code to factorize columns 1:k of A | |||
| * | |||
| CALL DSYTF2_ROOK( UPLO, K, A, LDA, IPIV, IINFO ) | |||
| KB = K | |||
| END IF | |||
| * | |||
| * Set INFO on the first occurrence of a zero pivot | |||
| * | |||
| IF( INFO.EQ.0 .AND. IINFO.GT.0 ) | |||
| $ INFO = IINFO | |||
| * | |||
| * No need to adjust IPIV | |||
| * | |||
| * Decrease K and return to the start of the main loop | |||
| * | |||
| K = K - KB | |||
| GO TO 10 | |||
| * | |||
| ELSE | |||
| * | |||
| * Factorize A as L*D*L**T using the lower triangle of A | |||
| * | |||
| * K is the main loop index, increasing from 1 to N in steps of | |||
| * KB, where KB is the number of columns factorized by DLASYF_ROOK; | |||
| * KB is either NB or NB-1, or N-K+1 for the last block | |||
| * | |||
| K = 1 | |||
| 20 CONTINUE | |||
| * | |||
| * If K > N, exit from loop | |||
| * | |||
| IF( K.GT.N ) | |||
| $ GO TO 40 | |||
| * | |||
| IF( K.LE.N-NB ) THEN | |||
| * | |||
| * Factorize columns k:k+kb-1 of A and use blocked code to | |||
| * update columns k+kb:n | |||
| * | |||
| CALL DLASYF_ROOK( UPLO, N-K+1, NB, KB, A( K, K ), LDA, | |||
| $ IPIV( K ), WORK, LDWORK, IINFO ) | |||
| ELSE | |||
| * | |||
| * Use unblocked code to factorize columns k:n of A | |||
| * | |||
| CALL DSYTF2_ROOK( UPLO, N-K+1, A( K, K ), LDA, IPIV( K ), | |||
| $ IINFO ) | |||
| KB = N - K + 1 | |||
| END IF | |||
| * | |||
| * Set INFO on the first occurrence of a zero pivot | |||
| * | |||
| IF( INFO.EQ.0 .AND. IINFO.GT.0 ) | |||
| $ INFO = IINFO + K - 1 | |||
| * | |||
| * Adjust IPIV | |||
| * | |||
| DO 30 J = K, K + KB - 1 | |||
| IF( IPIV( J ).GT.0 ) THEN | |||
| IPIV( J ) = IPIV( J ) + K - 1 | |||
| ELSE | |||
| IPIV( J ) = IPIV( J ) - K + 1 | |||
| END IF | |||
| 30 CONTINUE | |||
| * | |||
| * Increase K and return to the start of the main loop | |||
| * | |||
| K = K + KB | |||
| GO TO 20 | |||
| * | |||
| END IF | |||
| * | |||
| 40 CONTINUE | |||
| WORK( 1 ) = LWKOPT | |||
| RETURN | |||
| * | |||
| * End of DSYTRF_ROOK | |||
| * | |||
| END | |||
| @@ -0,0 +1,450 @@ | |||
| *> \brief \b DSYTRI_ROOK | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download DSYTRI_ROOK + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsytri_rook.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsytri_rook.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsytri_rook.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE DSYTRI_ROOK( UPLO, N, A, LDA, IPIV, WORK, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * CHARACTER UPLO | |||
| * INTEGER INFO, LDA, N | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * INTEGER IPIV( * ) | |||
| * DOUBLE PRECISION A( LDA, * ), WORK( * ) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| * ============= | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> DSYTRI_ROOK computes the inverse of a real symmetric | |||
| *> matrix A using the factorization A = U*D*U**T or A = L*D*L**T | |||
| *> computed by DSYTRF_ROOK. | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] UPLO | |||
| *> \verbatim | |||
| *> UPLO is CHARACTER*1 | |||
| *> Specifies whether the details of the factorization are stored | |||
| *> as an upper or lower triangular matrix. | |||
| *> = 'U': Upper triangular, form is A = U*D*U**T; | |||
| *> = 'L': Lower triangular, form is A = L*D*L**T. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] N | |||
| *> \verbatim | |||
| *> N is INTEGER | |||
| *> The order of the matrix A. N >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] A | |||
| *> \verbatim | |||
| *> A is DOUBLE PRECISION array, dimension (LDA,N) | |||
| *> On entry, the block diagonal matrix D and the multipliers | |||
| *> used to obtain the factor U or L as computed by DSYTRF_ROOK. | |||
| *> | |||
| *> On exit, if INFO = 0, the (symmetric) inverse of the original | |||
| *> matrix. If UPLO = 'U', the upper triangular part of the | |||
| *> inverse is formed and the part of A below the diagonal is not | |||
| *> referenced; if UPLO = 'L' the lower triangular part of the | |||
| *> inverse is formed and the part of A above the diagonal is | |||
| *> not referenced. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDA | |||
| *> \verbatim | |||
| *> LDA is INTEGER | |||
| *> The leading dimension of the array A. LDA >= max(1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] IPIV | |||
| *> \verbatim | |||
| *> IPIV is INTEGER array, dimension (N) | |||
| *> Details of the interchanges and the block structure of D | |||
| *> as determined by DSYTRF_ROOK. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] WORK | |||
| *> \verbatim | |||
| *> WORK is DOUBLE PRECISION array, dimension (N) | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[out] INFO | |||
| *> \verbatim | |||
| *> INFO is INTEGER | |||
| *> = 0: successful exit | |||
| *> < 0: if INFO = -i, the i-th argument had an illegal value | |||
| *> > 0: if INFO = i, D(i,i) = 0; the matrix is singular and its | |||
| *> inverse could not be computed. | |||
| *> \endverbatim | |||
| * | |||
| * Authors: | |||
| * ======== | |||
| * | |||
| *> \author Univ. of Tennessee | |||
| *> \author Univ. of California Berkeley | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date April 2012 | |||
| * | |||
| *> \ingroup doubleSYcomputational | |||
| * | |||
| *> \par Contributors: | |||
| * ================== | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> April 2012, Igor Kozachenko, | |||
| *> Computer Science Division, | |||
| *> University of California, Berkeley | |||
| *> | |||
| *> September 2007, Sven Hammarling, Nicholas J. Higham, Craig Lucas, | |||
| *> School of Mathematics, | |||
| *> University of Manchester | |||
| *> | |||
| *> \endverbatim | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE DSYTRI_ROOK( UPLO, N, A, LDA, IPIV, WORK, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.1) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * April 2012 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER UPLO | |||
| INTEGER INFO, LDA, N | |||
| * .. | |||
| * .. Array Arguments .. | |||
| INTEGER IPIV( * ) | |||
| DOUBLE PRECISION A( LDA, * ), WORK( * ) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| DOUBLE PRECISION ONE, ZERO | |||
| PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| LOGICAL UPPER | |||
| INTEGER K, KP, KSTEP | |||
| DOUBLE PRECISION AK, AKKP1, AKP1, D, T, TEMP | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| DOUBLE PRECISION DDOT | |||
| EXTERNAL LSAME, DDOT | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL DCOPY, DSWAP, DSYMV, XERBLA | |||
| * .. | |||
| * .. Intrinsic Functions .. | |||
| INTRINSIC ABS, MAX | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| * Test the input parameters. | |||
| * | |||
| INFO = 0 | |||
| UPPER = LSAME( UPLO, 'U' ) | |||
| IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN | |||
| INFO = -1 | |||
| ELSE IF( N.LT.0 ) THEN | |||
| INFO = -2 | |||
| ELSE IF( LDA.LT.MAX( 1, N ) ) THEN | |||
| INFO = -4 | |||
| END IF | |||
| IF( INFO.NE.0 ) THEN | |||
| CALL XERBLA( 'DSYTRI_ROOK', -INFO ) | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Quick return if possible | |||
| * | |||
| IF( N.EQ.0 ) | |||
| $ RETURN | |||
| * | |||
| * Check that the diagonal matrix D is nonsingular. | |||
| * | |||
| IF( UPPER ) THEN | |||
| * | |||
| * Upper triangular storage: examine D from bottom to top | |||
| * | |||
| DO 10 INFO = N, 1, -1 | |||
| IF( IPIV( INFO ).GT.0 .AND. A( INFO, INFO ).EQ.ZERO ) | |||
| $ RETURN | |||
| 10 CONTINUE | |||
| ELSE | |||
| * | |||
| * Lower triangular storage: examine D from top to bottom. | |||
| * | |||
| DO 20 INFO = 1, N | |||
| IF( IPIV( INFO ).GT.0 .AND. A( INFO, INFO ).EQ.ZERO ) | |||
| $ RETURN | |||
| 20 CONTINUE | |||
| END IF | |||
| INFO = 0 | |||
| * | |||
| IF( UPPER ) THEN | |||
| * | |||
| * Compute inv(A) from the factorization A = U*D*U**T. | |||
| * | |||
| * K is the main loop index, increasing from 1 to N in steps of | |||
| * 1 or 2, depending on the size of the diagonal blocks. | |||
| * | |||
| K = 1 | |||
| 30 CONTINUE | |||
| * | |||
| * If K > N, exit from loop. | |||
| * | |||
| IF( K.GT.N ) | |||
| $ GO TO 40 | |||
| * | |||
| IF( IPIV( K ).GT.0 ) THEN | |||
| * | |||
| * 1 x 1 diagonal block | |||
| * | |||
| * Invert the diagonal block. | |||
| * | |||
| A( K, K ) = ONE / A( K, K ) | |||
| * | |||
| * Compute column K of the inverse. | |||
| * | |||
| IF( K.GT.1 ) THEN | |||
| CALL DCOPY( K-1, A( 1, K ), 1, WORK, 1 ) | |||
| CALL DSYMV( UPLO, K-1, -ONE, A, LDA, WORK, 1, ZERO, | |||
| $ A( 1, K ), 1 ) | |||
| A( K, K ) = A( K, K ) - DDOT( K-1, WORK, 1, A( 1, K ), | |||
| $ 1 ) | |||
| END IF | |||
| KSTEP = 1 | |||
| ELSE | |||
| * | |||
| * 2 x 2 diagonal block | |||
| * | |||
| * Invert the diagonal block. | |||
| * | |||
| T = ABS( A( K, K+1 ) ) | |||
| AK = A( K, K ) / T | |||
| AKP1 = A( K+1, K+1 ) / T | |||
| AKKP1 = A( K, K+1 ) / T | |||
| D = T*( AK*AKP1-ONE ) | |||
| A( K, K ) = AKP1 / D | |||
| A( K+1, K+1 ) = AK / D | |||
| A( K, K+1 ) = -AKKP1 / D | |||
| * | |||
| * Compute columns K and K+1 of the inverse. | |||
| * | |||
| IF( K.GT.1 ) THEN | |||
| CALL DCOPY( K-1, A( 1, K ), 1, WORK, 1 ) | |||
| CALL DSYMV( UPLO, K-1, -ONE, A, LDA, WORK, 1, ZERO, | |||
| $ A( 1, K ), 1 ) | |||
| A( K, K ) = A( K, K ) - DDOT( K-1, WORK, 1, A( 1, K ), | |||
| $ 1 ) | |||
| A( K, K+1 ) = A( K, K+1 ) - | |||
| $ DDOT( K-1, A( 1, K ), 1, A( 1, K+1 ), 1 ) | |||
| CALL DCOPY( K-1, A( 1, K+1 ), 1, WORK, 1 ) | |||
| CALL DSYMV( UPLO, K-1, -ONE, A, LDA, WORK, 1, ZERO, | |||
| $ A( 1, K+1 ), 1 ) | |||
| A( K+1, K+1 ) = A( K+1, K+1 ) - | |||
| $ DDOT( K-1, WORK, 1, A( 1, K+1 ), 1 ) | |||
| END IF | |||
| KSTEP = 2 | |||
| END IF | |||
| * | |||
| IF( KSTEP.EQ.1 ) THEN | |||
| * | |||
| * Interchange rows and columns K and IPIV(K) in the leading | |||
| * submatrix A(1:k+1,1:k+1) | |||
| * | |||
| KP = IPIV( K ) | |||
| IF( KP.NE.K ) THEN | |||
| IF( KP.GT.1 ) | |||
| $ CALL DSWAP( KP-1, A( 1, K ), 1, A( 1, KP ), 1 ) | |||
| CALL DSWAP( K-KP-1, A( KP+1, K ), 1, A( KP, KP+1 ), LDA ) | |||
| TEMP = A( K, K ) | |||
| A( K, K ) = A( KP, KP ) | |||
| A( KP, KP ) = TEMP | |||
| END IF | |||
| ELSE | |||
| * | |||
| * Interchange rows and columns K and K+1 with -IPIV(K) and | |||
| * -IPIV(K+1)in the leading submatrix A(1:k+1,1:k+1) | |||
| * | |||
| KP = -IPIV( K ) | |||
| IF( KP.NE.K ) THEN | |||
| IF( KP.GT.1 ) | |||
| $ CALL DSWAP( KP-1, A( 1, K ), 1, A( 1, KP ), 1 ) | |||
| CALL DSWAP( K-KP-1, A( KP+1, K ), 1, A( KP, KP+1 ), LDA ) | |||
| * | |||
| TEMP = A( K, K ) | |||
| A( K, K ) = A( KP, KP ) | |||
| A( KP, KP ) = TEMP | |||
| TEMP = A( K, K+1 ) | |||
| A( K, K+1 ) = A( KP, K+1 ) | |||
| A( KP, K+1 ) = TEMP | |||
| END IF | |||
| * | |||
| K = K + 1 | |||
| KP = -IPIV( K ) | |||
| IF( KP.NE.K ) THEN | |||
| IF( KP.GT.1 ) | |||
| $ CALL DSWAP( KP-1, A( 1, K ), 1, A( 1, KP ), 1 ) | |||
| CALL DSWAP( K-KP-1, A( KP+1, K ), 1, A( KP, KP+1 ), LDA ) | |||
| TEMP = A( K, K ) | |||
| A( K, K ) = A( KP, KP ) | |||
| A( KP, KP ) = TEMP | |||
| END IF | |||
| END IF | |||
| * | |||
| K = K + 1 | |||
| GO TO 30 | |||
| 40 CONTINUE | |||
| * | |||
| ELSE | |||
| * | |||
| * Compute inv(A) from the factorization A = L*D*L**T. | |||
| * | |||
| * K is the main loop index, increasing from 1 to N in steps of | |||
| * 1 or 2, depending on the size of the diagonal blocks. | |||
| * | |||
| K = N | |||
| 50 CONTINUE | |||
| * | |||
| * If K < 1, exit from loop. | |||
| * | |||
| IF( K.LT.1 ) | |||
| $ GO TO 60 | |||
| * | |||
| IF( IPIV( K ).GT.0 ) THEN | |||
| * | |||
| * 1 x 1 diagonal block | |||
| * | |||
| * Invert the diagonal block. | |||
| * | |||
| A( K, K ) = ONE / A( K, K ) | |||
| * | |||
| * Compute column K of the inverse. | |||
| * | |||
| IF( K.LT.N ) THEN | |||
| CALL DCOPY( N-K, A( K+1, K ), 1, WORK, 1 ) | |||
| CALL DSYMV( UPLO, N-K, -ONE, A( K+1, K+1 ), LDA, WORK, 1, | |||
| $ ZERO, A( K+1, K ), 1 ) | |||
| A( K, K ) = A( K, K ) - DDOT( N-K, WORK, 1, A( K+1, K ), | |||
| $ 1 ) | |||
| END IF | |||
| KSTEP = 1 | |||
| ELSE | |||
| * | |||
| * 2 x 2 diagonal block | |||
| * | |||
| * Invert the diagonal block. | |||
| * | |||
| T = ABS( A( K, K-1 ) ) | |||
| AK = A( K-1, K-1 ) / T | |||
| AKP1 = A( K, K ) / T | |||
| AKKP1 = A( K, K-1 ) / T | |||
| D = T*( AK*AKP1-ONE ) | |||
| A( K-1, K-1 ) = AKP1 / D | |||
| A( K, K ) = AK / D | |||
| A( K, K-1 ) = -AKKP1 / D | |||
| * | |||
| * Compute columns K-1 and K of the inverse. | |||
| * | |||
| IF( K.LT.N ) THEN | |||
| CALL DCOPY( N-K, A( K+1, K ), 1, WORK, 1 ) | |||
| CALL DSYMV( UPLO, N-K, -ONE, A( K+1, K+1 ), LDA, WORK, 1, | |||
| $ ZERO, A( K+1, K ), 1 ) | |||
| A( K, K ) = A( K, K ) - DDOT( N-K, WORK, 1, A( K+1, K ), | |||
| $ 1 ) | |||
| A( K, K-1 ) = A( K, K-1 ) - | |||
| $ DDOT( N-K, A( K+1, K ), 1, A( K+1, K-1 ), | |||
| $ 1 ) | |||
| CALL DCOPY( N-K, A( K+1, K-1 ), 1, WORK, 1 ) | |||
| CALL DSYMV( UPLO, N-K, -ONE, A( K+1, K+1 ), LDA, WORK, 1, | |||
| $ ZERO, A( K+1, K-1 ), 1 ) | |||
| A( K-1, K-1 ) = A( K-1, K-1 ) - | |||
| $ DDOT( N-K, WORK, 1, A( K+1, K-1 ), 1 ) | |||
| END IF | |||
| KSTEP = 2 | |||
| END IF | |||
| * | |||
| IF( KSTEP.EQ.1 ) THEN | |||
| * | |||
| * Interchange rows and columns K and IPIV(K) in the trailing | |||
| * submatrix A(k-1:n,k-1:n) | |||
| * | |||
| KP = IPIV( K ) | |||
| IF( KP.NE.K ) THEN | |||
| IF( KP.LT.N ) | |||
| $ CALL DSWAP( N-KP, A( KP+1, K ), 1, A( KP+1, KP ), 1 ) | |||
| CALL DSWAP( KP-K-1, A( K+1, K ), 1, A( KP, K+1 ), LDA ) | |||
| TEMP = A( K, K ) | |||
| A( K, K ) = A( KP, KP ) | |||
| A( KP, KP ) = TEMP | |||
| END IF | |||
| ELSE | |||
| * | |||
| * Interchange rows and columns K and K-1 with -IPIV(K) and | |||
| * -IPIV(K-1) in the trailing submatrix A(k-1:n,k-1:n) | |||
| * | |||
| KP = -IPIV( K ) | |||
| IF( KP.NE.K ) THEN | |||
| IF( KP.LT.N ) | |||
| $ CALL DSWAP( N-KP, A( KP+1, K ), 1, A( KP+1, KP ), 1 ) | |||
| CALL DSWAP( KP-K-1, A( K+1, K ), 1, A( KP, K+1 ), LDA ) | |||
| * | |||
| TEMP = A( K, K ) | |||
| A( K, K ) = A( KP, KP ) | |||
| A( KP, KP ) = TEMP | |||
| TEMP = A( K, K-1 ) | |||
| A( K, K-1 ) = A( KP, K-1 ) | |||
| A( KP, K-1 ) = TEMP | |||
| END IF | |||
| * | |||
| K = K - 1 | |||
| KP = -IPIV( K ) | |||
| IF( KP.NE.K ) THEN | |||
| IF( KP.LT.N ) | |||
| $ CALL DSWAP( N-KP, A( KP+1, K ), 1, A( KP+1, KP ), 1 ) | |||
| CALL DSWAP( KP-K-1, A( K+1, K ), 1, A( KP, K+1 ), LDA ) | |||
| TEMP = A( K, K ) | |||
| A( K, K ) = A( KP, KP ) | |||
| A( KP, KP ) = TEMP | |||
| END IF | |||
| END IF | |||
| * | |||
| K = K - 1 | |||
| GO TO 50 | |||
| 60 CONTINUE | |||
| END IF | |||
| * | |||
| RETURN | |||
| * | |||
| * End of DSYTRI_ROOK | |||
| * | |||
| END | |||
| @@ -0,0 +1,484 @@ | |||
| *> \brief \b DSYTRS_ROOK | |||
| * | |||
| * =========== DOCUMENTATION =========== | |||
| * | |||
| * Online html documentation available at | |||
| * http://www.netlib.org/lapack/explore-html/ | |||
| * | |||
| *> \htmlonly | |||
| *> Download DSYTRS_ROOK + dependencies | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsytrs_rook.f"> | |||
| *> [TGZ]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsytrs_rook.f"> | |||
| *> [ZIP]</a> | |||
| *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsytrs_rook.f"> | |||
| *> [TXT]</a> | |||
| *> \endhtmlonly | |||
| * | |||
| * Definition: | |||
| * =========== | |||
| * | |||
| * SUBROUTINE DSYTRS_ROOK( UPLO, N, NRHS, A, LDA, IPIV, B, LDB, INFO ) | |||
| * | |||
| * .. Scalar Arguments .. | |||
| * CHARACTER UPLO | |||
| * INTEGER INFO, LDA, LDB, N, NRHS | |||
| * .. | |||
| * .. Array Arguments .. | |||
| * INTEGER IPIV( * ) | |||
| * DOUBLE PRECISION A( LDA, * ), B( LDB, * ) | |||
| * .. | |||
| * | |||
| * | |||
| *> \par Purpose: | |||
| * ============= | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> DSYTRS_ROOK solves a system of linear equations A*X = B with | |||
| *> a real symmetric matrix A using the factorization A = U*D*U**T or | |||
| *> A = L*D*L**T computed by DSYTRF_ROOK. | |||
| *> \endverbatim | |||
| * | |||
| * Arguments: | |||
| * ========== | |||
| * | |||
| *> \param[in] UPLO | |||
| *> \verbatim | |||
| *> UPLO is CHARACTER*1 | |||
| *> Specifies whether the details of the factorization are stored | |||
| *> as an upper or lower triangular matrix. | |||
| *> = 'U': Upper triangular, form is A = U*D*U**T; | |||
| *> = 'L': Lower triangular, form is A = L*D*L**T. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] N | |||
| *> \verbatim | |||
| *> N is INTEGER | |||
| *> The order of the matrix A. N >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] NRHS | |||
| *> \verbatim | |||
| *> NRHS is INTEGER | |||
| *> The number of right hand sides, i.e., the number of columns | |||
| *> of the matrix B. NRHS >= 0. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] A | |||
| *> \verbatim | |||
| *> A is DOUBLE PRECISION array, dimension (LDA,N) | |||
| *> The block diagonal matrix D and the multipliers used to | |||
| *> obtain the factor U or L as computed by DSYTRF_ROOK. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDA | |||
| *> \verbatim | |||
| *> LDA is INTEGER | |||
| *> The leading dimension of the array A. LDA >= max(1,N). | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] IPIV | |||
| *> \verbatim | |||
| *> IPIV is INTEGER array, dimension (N) | |||
| *> Details of the interchanges and the block structure of D | |||
| *> as determined by DSYTRF_ROOK. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in,out] B | |||
| *> \verbatim | |||
| *> B is DOUBLE PRECISION array, dimension (LDB,NRHS) | |||
| *> On entry, the right hand side matrix B. | |||
| *> On exit, the solution matrix X. | |||
| *> \endverbatim | |||
| *> | |||
| *> \param[in] LDB | |||
| *> \verbatim | |||
| *> LDB is INTEGER | |||
| *> The leading dimension of the array B. LDB >= max(1,N). | |||
| *> \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 April 2012 | |||
| * | |||
| *> \ingroup doubleSYcomputational | |||
| * | |||
| *> \par Contributors: | |||
| * ================== | |||
| *> | |||
| *> \verbatim | |||
| *> | |||
| *> April 2012, Igor Kozachenko, | |||
| *> Computer Science Division, | |||
| *> University of California, Berkeley | |||
| *> | |||
| *> September 2007, Sven Hammarling, Nicholas J. Higham, Craig Lucas, | |||
| *> School of Mathematics, | |||
| *> University of Manchester | |||
| *> | |||
| *> \endverbatim | |||
| * | |||
| * ===================================================================== | |||
| SUBROUTINE DSYTRS_ROOK( UPLO, N, NRHS, A, LDA, IPIV, B, LDB, | |||
| $ INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.1) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * April 2012 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER UPLO | |||
| INTEGER INFO, LDA, LDB, N, NRHS | |||
| * .. | |||
| * .. Array Arguments .. | |||
| INTEGER IPIV( * ) | |||
| DOUBLE PRECISION A( LDA, * ), B( LDB, * ) | |||
| * .. | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| * .. Parameters .. | |||
| DOUBLE PRECISION ONE | |||
| PARAMETER ( ONE = 1.0D+0 ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| LOGICAL UPPER | |||
| INTEGER J, K, KP | |||
| DOUBLE PRECISION AK, AKM1, AKM1K, BK, BKM1, DENOM | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| EXTERNAL LSAME | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL DGEMV, DGER, DSCAL, DSWAP, XERBLA | |||
| * .. | |||
| * .. Intrinsic Functions .. | |||
| INTRINSIC MAX | |||
| * .. | |||
| * .. Executable Statements .. | |||
| * | |||
| INFO = 0 | |||
| UPPER = LSAME( UPLO, 'U' ) | |||
| IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN | |||
| INFO = -1 | |||
| ELSE IF( N.LT.0 ) THEN | |||
| INFO = -2 | |||
| ELSE IF( NRHS.LT.0 ) THEN | |||
| INFO = -3 | |||
| ELSE IF( LDA.LT.MAX( 1, N ) ) THEN | |||
| INFO = -5 | |||
| ELSE IF( LDB.LT.MAX( 1, N ) ) THEN | |||
| INFO = -8 | |||
| END IF | |||
| IF( INFO.NE.0 ) THEN | |||
| CALL XERBLA( 'DSYTRS_ROOK', -INFO ) | |||
| RETURN | |||
| END IF | |||
| * | |||
| * Quick return if possible | |||
| * | |||
| IF( N.EQ.0 .OR. NRHS.EQ.0 ) | |||
| $ RETURN | |||
| * | |||
| IF( UPPER ) THEN | |||
| * | |||
| * Solve A*X = B, where A = U*D*U**T. | |||
| * | |||
| * First solve U*D*X = B, overwriting B with X. | |||
| * | |||
| * K is the main loop index, decreasing from N to 1 in steps of | |||
| * 1 or 2, depending on the size of the diagonal blocks. | |||
| * | |||
| K = N | |||
| 10 CONTINUE | |||
| * | |||
| * If K < 1, exit from loop. | |||
| * | |||
| IF( K.LT.1 ) | |||
| $ GO TO 30 | |||
| * | |||
| IF( IPIV( K ).GT.0 ) THEN | |||
| * | |||
| * 1 x 1 diagonal block | |||
| * | |||
| * Interchange rows K and IPIV(K). | |||
| * | |||
| KP = IPIV( K ) | |||
| IF( KP.NE.K ) | |||
| $ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| * | |||
| * Multiply by inv(U(K)), where U(K) is the transformation | |||
| * stored in column K of A. | |||
| * | |||
| CALL DGER( K-1, NRHS, -ONE, A( 1, K ), 1, B( K, 1 ), LDB, | |||
| $ B( 1, 1 ), LDB ) | |||
| * | |||
| * Multiply by the inverse of the diagonal block. | |||
| * | |||
| CALL DSCAL( NRHS, ONE / A( K, K ), B( K, 1 ), LDB ) | |||
| K = K - 1 | |||
| ELSE | |||
| * | |||
| * 2 x 2 diagonal block | |||
| * | |||
| * Interchange rows K and -IPIV(K) THEN K-1 and -IPIV(K-1) | |||
| * | |||
| KP = -IPIV( K ) | |||
| IF( KP.NE.K ) | |||
| $ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| * | |||
| KP = -IPIV( K-1 ) | |||
| IF( KP.NE.K-1 ) | |||
| $ CALL DSWAP( NRHS, B( K-1, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| * | |||
| * Multiply by inv(U(K)), where U(K) is the transformation | |||
| * stored in columns K-1 and K of A. | |||
| * | |||
| IF( K.GT.2 ) THEN | |||
| CALL DGER( K-2, NRHS, -ONE, A( 1, K ), 1, B( K, 1 ), | |||
| $ LDB, B( 1, 1 ), LDB ) | |||
| CALL DGER( K-2, NRHS, -ONE, A( 1, K-1 ), 1, B( K-1, 1 ), | |||
| $ LDB, B( 1, 1 ), LDB ) | |||
| END IF | |||
| * | |||
| * Multiply by the inverse of the diagonal block. | |||
| * | |||
| AKM1K = A( K-1, K ) | |||
| AKM1 = A( K-1, K-1 ) / AKM1K | |||
| AK = A( K, K ) / AKM1K | |||
| DENOM = AKM1*AK - ONE | |||
| DO 20 J = 1, NRHS | |||
| BKM1 = B( K-1, J ) / AKM1K | |||
| BK = B( K, J ) / AKM1K | |||
| B( K-1, J ) = ( AK*BKM1-BK ) / DENOM | |||
| B( K, J ) = ( AKM1*BK-BKM1 ) / DENOM | |||
| 20 CONTINUE | |||
| K = K - 2 | |||
| END IF | |||
| * | |||
| GO TO 10 | |||
| 30 CONTINUE | |||
| * | |||
| * Next solve U**T *X = B, overwriting B with X. | |||
| * | |||
| * K is the main loop index, increasing from 1 to N in steps of | |||
| * 1 or 2, depending on the size of the diagonal blocks. | |||
| * | |||
| K = 1 | |||
| 40 CONTINUE | |||
| * | |||
| * If K > N, exit from loop. | |||
| * | |||
| IF( K.GT.N ) | |||
| $ GO TO 50 | |||
| * | |||
| IF( IPIV( K ).GT.0 ) THEN | |||
| * | |||
| * 1 x 1 diagonal block | |||
| * | |||
| * Multiply by inv(U**T(K)), where U(K) is the transformation | |||
| * stored in column K of A. | |||
| * | |||
| IF( K.GT.1 ) | |||
| $ CALL DGEMV( 'Transpose', K-1, NRHS, -ONE, B, | |||
| $ LDB, A( 1, K ), 1, ONE, B( K, 1 ), LDB ) | |||
| * | |||
| * Interchange rows K and IPIV(K). | |||
| * | |||
| KP = IPIV( K ) | |||
| IF( KP.NE.K ) | |||
| $ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| K = K + 1 | |||
| ELSE | |||
| * | |||
| * 2 x 2 diagonal block | |||
| * | |||
| * Multiply by inv(U**T(K+1)), where U(K+1) is the transformation | |||
| * stored in columns K and K+1 of A. | |||
| * | |||
| IF( K.GT.1 ) THEN | |||
| CALL DGEMV( 'Transpose', K-1, NRHS, -ONE, B, | |||
| $ LDB, A( 1, K ), 1, ONE, B( K, 1 ), LDB ) | |||
| CALL DGEMV( 'Transpose', K-1, NRHS, -ONE, B, | |||
| $ LDB, A( 1, K+1 ), 1, ONE, B( K+1, 1 ), LDB ) | |||
| END IF | |||
| * | |||
| * Interchange rows K and -IPIV(K) THEN K+1 and -IPIV(K+1). | |||
| * | |||
| KP = -IPIV( K ) | |||
| IF( KP.NE.K ) | |||
| $ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| * | |||
| KP = -IPIV( K+1 ) | |||
| IF( KP.NE.K+1 ) | |||
| $ CALL DSWAP( NRHS, B( K+1, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| * | |||
| K = K + 2 | |||
| END IF | |||
| * | |||
| GO TO 40 | |||
| 50 CONTINUE | |||
| * | |||
| ELSE | |||
| * | |||
| * Solve A*X = B, where A = L*D*L**T. | |||
| * | |||
| * First solve L*D*X = B, overwriting B with X. | |||
| * | |||
| * K is the main loop index, increasing from 1 to N in steps of | |||
| * 1 or 2, depending on the size of the diagonal blocks. | |||
| * | |||
| K = 1 | |||
| 60 CONTINUE | |||
| * | |||
| * If K > N, exit from loop. | |||
| * | |||
| IF( K.GT.N ) | |||
| $ GO TO 80 | |||
| * | |||
| IF( IPIV( K ).GT.0 ) THEN | |||
| * | |||
| * 1 x 1 diagonal block | |||
| * | |||
| * Interchange rows K and IPIV(K). | |||
| * | |||
| KP = IPIV( K ) | |||
| IF( KP.NE.K ) | |||
| $ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| * | |||
| * Multiply by inv(L(K)), where L(K) is the transformation | |||
| * stored in column K of A. | |||
| * | |||
| IF( K.LT.N ) | |||
| $ CALL DGER( N-K, NRHS, -ONE, A( K+1, K ), 1, B( K, 1 ), | |||
| $ LDB, B( K+1, 1 ), LDB ) | |||
| * | |||
| * Multiply by the inverse of the diagonal block. | |||
| * | |||
| CALL DSCAL( NRHS, ONE / A( K, K ), B( K, 1 ), LDB ) | |||
| K = K + 1 | |||
| ELSE | |||
| * | |||
| * 2 x 2 diagonal block | |||
| * | |||
| * Interchange rows K and -IPIV(K) THEN K+1 and -IPIV(K+1) | |||
| * | |||
| KP = -IPIV( K ) | |||
| IF( KP.NE.K ) | |||
| $ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| * | |||
| KP = -IPIV( K+1 ) | |||
| IF( KP.NE.K+1 ) | |||
| $ CALL DSWAP( NRHS, B( K+1, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| * | |||
| * Multiply by inv(L(K)), where L(K) is the transformation | |||
| * stored in columns K and K+1 of A. | |||
| * | |||
| IF( K.LT.N-1 ) THEN | |||
| CALL DGER( N-K-1, NRHS, -ONE, A( K+2, K ), 1, B( K, 1 ), | |||
| $ LDB, B( K+2, 1 ), LDB ) | |||
| CALL DGER( N-K-1, NRHS, -ONE, A( K+2, K+1 ), 1, | |||
| $ B( K+1, 1 ), LDB, B( K+2, 1 ), LDB ) | |||
| END IF | |||
| * | |||
| * Multiply by the inverse of the diagonal block. | |||
| * | |||
| AKM1K = A( K+1, K ) | |||
| AKM1 = A( K, K ) / AKM1K | |||
| AK = A( K+1, K+1 ) / AKM1K | |||
| DENOM = AKM1*AK - ONE | |||
| DO 70 J = 1, NRHS | |||
| BKM1 = B( K, J ) / AKM1K | |||
| BK = B( K+1, J ) / AKM1K | |||
| B( K, J ) = ( AK*BKM1-BK ) / DENOM | |||
| B( K+1, J ) = ( AKM1*BK-BKM1 ) / DENOM | |||
| 70 CONTINUE | |||
| K = K + 2 | |||
| END IF | |||
| * | |||
| GO TO 60 | |||
| 80 CONTINUE | |||
| * | |||
| * Next solve L**T *X = B, overwriting B with X. | |||
| * | |||
| * K is the main loop index, decreasing from N to 1 in steps of | |||
| * 1 or 2, depending on the size of the diagonal blocks. | |||
| * | |||
| K = N | |||
| 90 CONTINUE | |||
| * | |||
| * If K < 1, exit from loop. | |||
| * | |||
| IF( K.LT.1 ) | |||
| $ GO TO 100 | |||
| * | |||
| IF( IPIV( K ).GT.0 ) THEN | |||
| * | |||
| * 1 x 1 diagonal block | |||
| * | |||
| * Multiply by inv(L**T(K)), where L(K) is the transformation | |||
| * stored in column K of A. | |||
| * | |||
| IF( K.LT.N ) | |||
| $ CALL DGEMV( 'Transpose', N-K, NRHS, -ONE, B( K+1, 1 ), | |||
| $ LDB, A( K+1, K ), 1, ONE, B( K, 1 ), LDB ) | |||
| * | |||
| * Interchange rows K and IPIV(K). | |||
| * | |||
| KP = IPIV( K ) | |||
| IF( KP.NE.K ) | |||
| $ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| K = K - 1 | |||
| ELSE | |||
| * | |||
| * 2 x 2 diagonal block | |||
| * | |||
| * Multiply by inv(L**T(K-1)), where L(K-1) is the transformation | |||
| * stored in columns K-1 and K of A. | |||
| * | |||
| IF( K.LT.N ) THEN | |||
| CALL DGEMV( 'Transpose', N-K, NRHS, -ONE, B( K+1, 1 ), | |||
| $ LDB, A( K+1, K ), 1, ONE, B( K, 1 ), LDB ) | |||
| CALL DGEMV( 'Transpose', N-K, NRHS, -ONE, B( K+1, 1 ), | |||
| $ LDB, A( K+1, K-1 ), 1, ONE, B( K-1, 1 ), | |||
| $ LDB ) | |||
| END IF | |||
| * | |||
| * Interchange rows K and -IPIV(K) THEN K-1 and -IPIV(K-1) | |||
| * | |||
| KP = -IPIV( K ) | |||
| IF( KP.NE.K ) | |||
| $ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| * | |||
| KP = -IPIV( K-1 ) | |||
| IF( KP.NE.K-1 ) | |||
| $ CALL DSWAP( NRHS, B( K-1, 1 ), LDB, B( KP, 1 ), LDB ) | |||
| * | |||
| K = K - 2 | |||
| END IF | |||
| * | |||
| GO TO 90 | |||
| 100 CONTINUE | |||
| END IF | |||
| * | |||
| RETURN | |||
| * | |||
| * End of DSYTRS_ROOK | |||
| * | |||
| END | |||
| @@ -175,7 +175,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date April 2012 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup doubleOTHERcomputational | |||
| * | |||
| @@ -216,10 +216,10 @@ | |||
| SUBROUTINE DTPMQRT( SIDE, TRANS, M, N, K, L, NB, V, LDV, T, LDT, | |||
| $ A, LDA, B, LDB, WORK, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.1) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * April 2012 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER SIDE, TRANS | |||
| @@ -235,7 +235,7 @@ | |||
| * .. | |||
| * .. Local Scalars .. | |||
| LOGICAL LEFT, RIGHT, TRAN, NOTRAN | |||
| INTEGER I, IB, MB, LB, KF, Q | |||
| INTEGER I, IB, MB, LB, KF, LDAQ, LDVQ | |||
| * .. | |||
| * .. External Functions .. | |||
| LOGICAL LSAME | |||
| @@ -257,10 +257,12 @@ | |||
| TRAN = LSAME( TRANS, 'T' ) | |||
| NOTRAN = LSAME( TRANS, 'N' ) | |||
| * | |||
| IF( LEFT ) THEN | |||
| Q = M | |||
| IF ( LEFT ) THEN | |||
| LDVQ = MAX( 1, M ) | |||
| LDAQ = MAX( 1, K ) | |||
| ELSE IF ( RIGHT ) THEN | |||
| Q = N | |||
| LDVQ = MAX( 1, N ) | |||
| LDAQ = MAX( 1, M ) | |||
| END IF | |||
| IF( .NOT.LEFT .AND. .NOT.RIGHT ) THEN | |||
| INFO = -1 | |||
| @@ -274,13 +276,13 @@ | |||
| INFO = -5 | |||
| ELSE IF( L.LT.0 .OR. L.GT.K ) THEN | |||
| INFO = -6 | |||
| ELSE IF( NB.LT.1 .OR. NB.GT.K ) THEN | |||
| ELSE IF( NB.LT.1 .OR. (NB.GT.K .AND. K.GT.0) ) THEN | |||
| INFO = -7 | |||
| ELSE IF( LDV.LT.MAX( 1, Q ) ) THEN | |||
| ELSE IF( LDV.LT.LDVQ ) THEN | |||
| INFO = -9 | |||
| ELSE IF( LDT.LT.NB ) THEN | |||
| INFO = -11 | |||
| ELSE IF( LDA.LT.MAX( 1, M ) ) THEN | |||
| ELSE IF( LDA.LT.LDAQ ) THEN | |||
| INFO = -13 | |||
| ELSE IF( LDB.LT.MAX( 1, M ) ) THEN | |||
| INFO = -15 | |||
| @@ -132,7 +132,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date April 2012 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup doubleOTHERcomputational | |||
| * | |||
| @@ -189,10 +189,10 @@ | |||
| SUBROUTINE DTPQRT( M, N, L, NB, A, LDA, B, LDB, T, LDT, WORK, | |||
| $ INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.1) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * April 2012 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| INTEGER INFO, LDA, LDB, LDT, N, M, L, NB | |||
| @@ -219,9 +219,9 @@ | |||
| INFO = -1 | |||
| ELSE IF( N.LT.0 ) THEN | |||
| INFO = -2 | |||
| ELSE IF( L.LT.0 .OR. L.GT.MIN(M,N) ) THEN | |||
| ELSE IF( L.LT.0 .OR. (L.GT.MIN(M,N) .AND. MIN(M,N).GE.0)) THEN | |||
| INFO = -3 | |||
| ELSE IF( NB.LT.1 .OR. NB.GT.N ) THEN | |||
| ELSE IF( NB.LT.1 .OR. (NB.GT.N .AND. N.GT.0)) THEN | |||
| INFO = -4 | |||
| ELSE IF( LDA.LT.MAX( 1, N ) ) THEN | |||
| INFO = -6 | |||
| @@ -48,18 +48,18 @@ | |||
| * ===================================================================== | |||
| SUBROUTINE ILAVER( VERS_MAJOR, VERS_MINOR, VERS_PATCH ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.2) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * September 2012 | |||
| * November 2013 | |||
| * | |||
| * ===================================================================== | |||
| * | |||
| INTEGER VERS_MAJOR, VERS_MINOR, VERS_PATCH | |||
| * ===================================================================== | |||
| VERS_MAJOR = 3 | |||
| VERS_MINOR = 4 | |||
| VERS_PATCH = 2 | |||
| VERS_MINOR = 5 | |||
| VERS_PATCH = 0 | |||
| * ===================================================================== | |||
| * | |||
| RETURN | |||
| @@ -322,7 +322,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date November 2011 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup realOTHERcomputational | |||
| * | |||
| @@ -332,10 +332,10 @@ | |||
| $ V2T, LDV2T, B11D, B11E, B12D, B12E, B21D, B21E, | |||
| $ B22D, B22E, WORK, LWORK, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.0) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * November 2011 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER JOBU1, JOBU2, JOBV1T, JOBV2T, TRANS | |||
| @@ -358,8 +358,8 @@ | |||
| PARAMETER ( HUNDRED = 100.0E0, MEIGHTH = -0.125E0, | |||
| $ ONE = 1.0E0, PIOVER2 = 1.57079632679489662E0, | |||
| $ TEN = 10.0E0, ZERO = 0.0E0 ) | |||
| REAL NEGONECOMPLEX | |||
| PARAMETER ( NEGONECOMPLEX = -1.0E0 ) | |||
| REAL NEGONE | |||
| PARAMETER ( NEGONE = -1.0E0 ) | |||
| * .. | |||
| * .. Local Scalars .. | |||
| LOGICAL COLMAJOR, LQUERY, RESTART11, RESTART12, | |||
| @@ -477,7 +477,10 @@ | |||
| * Initial deflation | |||
| * | |||
| IMAX = Q | |||
| DO WHILE( ( IMAX .GT. 1 ) .AND. ( PHI(IMAX-1) .EQ. ZERO ) ) | |||
| DO WHILE( IMAX .GT. 1 ) | |||
| IF( PHI(IMAX-1) .NE. ZERO ) THEN | |||
| EXIT | |||
| END IF | |||
| IMAX = IMAX - 1 | |||
| END DO | |||
| IMIN = IMAX - 1 | |||
| @@ -939,9 +942,9 @@ | |||
| B21D(IMAX) = -B21D(IMAX) | |||
| IF( WANTV1T ) THEN | |||
| IF( COLMAJOR ) THEN | |||
| CALL SSCAL( Q, NEGONECOMPLEX, V1T(IMAX,1), LDV1T ) | |||
| CALL SSCAL( Q, NEGONE, V1T(IMAX,1), LDV1T ) | |||
| ELSE | |||
| CALL SSCAL( Q, NEGONECOMPLEX, V1T(1,IMAX), 1 ) | |||
| CALL SSCAL( Q, NEGONE, V1T(1,IMAX), 1 ) | |||
| END IF | |||
| END IF | |||
| END IF | |||
| @@ -962,9 +965,9 @@ | |||
| B12D(IMAX) = -B12D(IMAX) | |||
| IF( WANTU1 ) THEN | |||
| IF( COLMAJOR ) THEN | |||
| CALL SSCAL( P, NEGONECOMPLEX, U1(1,IMAX), 1 ) | |||
| CALL SSCAL( P, NEGONE, U1(1,IMAX), 1 ) | |||
| ELSE | |||
| CALL SSCAL( P, NEGONECOMPLEX, U1(IMAX,1), LDU1 ) | |||
| CALL SSCAL( P, NEGONE, U1(IMAX,1), LDU1 ) | |||
| END IF | |||
| END IF | |||
| END IF | |||
| @@ -972,9 +975,9 @@ | |||
| B22D(IMAX) = -B22D(IMAX) | |||
| IF( WANTU2 ) THEN | |||
| IF( COLMAJOR ) THEN | |||
| CALL SSCAL( M-P, NEGONECOMPLEX, U2(1,IMAX), 1 ) | |||
| CALL SSCAL( M-P, NEGONE, U2(1,IMAX), 1 ) | |||
| ELSE | |||
| CALL SSCAL( M-P, NEGONECOMPLEX, U2(IMAX,1), LDU2 ) | |||
| CALL SSCAL( M-P, NEGONE, U2(IMAX,1), LDU2 ) | |||
| END IF | |||
| END IF | |||
| END IF | |||
| @@ -984,9 +987,9 @@ | |||
| IF( B12D(IMAX)+B22D(IMAX) .LT. 0 ) THEN | |||
| IF( WANTV2T ) THEN | |||
| IF( COLMAJOR ) THEN | |||
| CALL SSCAL( M-Q, NEGONECOMPLEX, V2T(IMAX,1), LDV2T ) | |||
| CALL SSCAL( M-Q, NEGONE, V2T(IMAX,1), LDV2T ) | |||
| ELSE | |||
| CALL SSCAL( M-Q, NEGONECOMPLEX, V2T(1,IMAX), 1 ) | |||
| CALL SSCAL( M-Q, NEGONE, V2T(1,IMAX), 1 ) | |||
| END IF | |||
| END IF | |||
| END IF | |||
| @@ -121,7 +121,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date November 2011 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup realGEcomputational | |||
| * | |||
| @@ -160,10 +160,10 @@ | |||
| * ===================================================================== | |||
| SUBROUTINE SGEBAL( JOB, N, A, LDA, ILO, IHI, SCALE, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.0) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * November 2011 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER JOB | |||
| @@ -192,8 +192,8 @@ | |||
| * .. External Functions .. | |||
| LOGICAL SISNAN, LSAME | |||
| INTEGER ISAMAX | |||
| REAL SLAMCH | |||
| EXTERNAL SISNAN, LSAME, ISAMAX, SLAMCH | |||
| REAL SLAMCH, SNRM2 | |||
| EXTERNAL SISNAN, LSAME, ISAMAX, SLAMCH, SNRM2 | |||
| * .. | |||
| * .. External Subroutines .. | |||
| EXTERNAL SSCAL, SSWAP, XERBLA | |||
| @@ -316,15 +316,9 @@ | |||
| NOCONV = .FALSE. | |||
| * | |||
| DO 200 I = K, L | |||
| C = ZERO | |||
| R = ZERO | |||
| * | |||
| DO 150 J = K, L | |||
| IF( J.EQ.I ) | |||
| $ GO TO 150 | |||
| C = C + ABS( A( J, I ) ) | |||
| R = R + ABS( A( I, J ) ) | |||
| 150 CONTINUE | |||
| * | |||
| C = SNRM2( L-K+1, A( K, I ), 1 ) | |||
| R = SNRM2( L-K+1, A( I, K ), LDA ) | |||
| ICA = ISAMAX( L, A( 1, I ), 1 ) | |||
| CA = ABS( A( ICA, I ) ) | |||
| IRA = ISAMAX( N-K+1, A( I, K ), LDA ) | |||
| @@ -160,7 +160,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date November 2011 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup realGEcomputational | |||
| * | |||
| @@ -168,10 +168,10 @@ | |||
| SUBROUTINE SGEMQRT( SIDE, TRANS, M, N, K, NB, V, LDV, T, LDT, | |||
| $ C, LDC, WORK, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.0) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * November 2011 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| CHARACTER SIDE, TRANS | |||
| @@ -225,7 +225,7 @@ | |||
| INFO = -4 | |||
| ELSE IF( K.LT.0 .OR. K.GT.Q ) THEN | |||
| INFO = -5 | |||
| ELSE IF( NB.LT.1 .OR. NB.GT.K ) THEN | |||
| ELSE IF( NB.LT.1 .OR. (NB.GT.K .AND. K.GT.0)) THEN | |||
| INFO = -6 | |||
| ELSE IF( LDV.LT.MAX( 1, Q ) ) THEN | |||
| INFO = -8 | |||
| @@ -108,7 +108,7 @@ | |||
| *> \author Univ. of Colorado Denver | |||
| *> \author NAG Ltd. | |||
| * | |||
| *> \date November 2011 | |||
| *> \date November 2013 | |||
| * | |||
| *> \ingroup realGEcomputational | |||
| * | |||
| @@ -141,10 +141,10 @@ | |||
| * ===================================================================== | |||
| SUBROUTINE SGEQRT( M, N, NB, A, LDA, T, LDT, WORK, INFO ) | |||
| * | |||
| * -- LAPACK computational routine (version 3.4.0) -- | |||
| * -- LAPACK computational routine (version 3.5.0) -- | |||
| * -- LAPACK is a software package provided by Univ. of Tennessee, -- | |||
| * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- | |||
| * November 2011 | |||
| * November 2013 | |||
| * | |||
| * .. Scalar Arguments .. | |||
| INTEGER INFO, LDA, LDT, M, N, NB | |||
| @@ -173,7 +173,7 @@ | |||
| INFO = -1 | |||
| ELSE IF( N.LT.0 ) THEN | |||
| INFO = -2 | |||
| ELSE IF( NB.LT.1 .OR. NB.GT.MIN(M,N) ) THEN | |||
| ELSE IF( NB.LT.1 .OR. ( NB.GT.MIN(M,N) .AND. MIN(M,N).GT.0 ) )THEN | |||
| INFO = -3 | |||
| ELSE IF( LDA.LT.MAX( 1, M ) ) THEN | |||
| INFO = -5 | |||