uncsd(3)
uncsd(3) β Library Functions Manual πβ¨
okay bestie, welcome to the Library Functions Manual page for uncsd(3) β yes, the whole thing, and we're doing it with the sparkle it deserves. π
β¨ NAME β¨
uncsd - {un,or}csd: ??
π SYNOPSIS π
okay so these are the four recursive subroutines this page is serving, and yes, every arg is getting its moment:
cuncsd:
recursive subroutine cuncsd (jobu1, jobu2, jobv1t, jobv2t, trans, signs,
m, p, q, x11, ldx11, x12, ldx12, x21, ldx21, x22, ldx22, theta, u1,
ldu1, u2, ldu2, v1t, ldv1t, v2t, ldv2t, work, lwork, rwork, lrwork,
iwork, info)
CUNCSD π
dorcsd:
recursive subroutine dorcsd (jobu1, jobu2, jobv1t, jobv2t, trans, signs,
m, p, q, x11, ldx11, x12, ldx12, x21, ldx21, x22, ldx22, theta, u1,
ldu1, u2, ldu2, v1t, ldv1t, v2t, ldv2t, work, lwork, iwork, info)
DORCSD π₯
sorcsd:
recursive subroutine sorcsd (jobu1, jobu2, jobv1t, jobv2t, trans, signs,
m, p, q, x11, ldx11, x12, ldx12, x21, ldx21, x22, ldx22, theta, u1,
ldu1, u2, ldu2, v1t, ldv1t, v2t, ldv2t, work, lwork, iwork, info)
SORCSD πΈ
zuncsd:
recursive subroutine zuncsd (jobu1, jobu2, jobv1t, jobv2t, trans, signs,
m, p, q, x11, ldx11, x12, ldx12, x21, ldx21, x22, ldx22, theta, u1,
ldu1, u2, ldu2, v1t, ldv1t, v2t, ldv2t, work, lwork, rwork, lrwork,
iwork, info)
ZUNCSD π
π¦ Detailed Description π¦
the original page has this heading and then slides straight into the function docs, so no extra lore here β just vibes and then the real tea. π«Ά
π₯ Function Documentation π₯
recursive subroutine cuncsd (character jobu1, character jobu2, character jobv1t, character jobv2t, character trans, character signs, integer m, integer p, integer q, complex, dimension( ldx11, * ) x11, integer ldx11, complex, dimension( ldx12, * ) x12, integer ldx12, complex, dimension( ldx21, * ) x21, integer ldx21, complex, dimension( ldx22, * ) x22, integer ldx22, real, dimension( * ) theta, complex, dimension( ldu1, * ) u1, integer ldu1, complex, dimension( ldu2, * ) u2, integer ldu2, complex, dimension( ldv1t, * ) v1t, integer ldv1t, complex, dimension( ldv2t, * ) v2t, integer ldv2t, complex, dimension( * ) work, integer lwork, real, dimension( * ) rwork, integer lrwork, integer, dimension( * ) iwork, integer info)
recursive subroutine cuncsd (character jobu1, character jobu2, character
jobv1t, character jobv2t, character trans, character signs, integer m,
integer p, integer q, complex, dimension( ldx11, * ) x11, integer ldx11,
complex, dimension( ldx12, * ) x12, integer ldx12, complex, dimension(
ldx21, * ) x21, integer ldx21, complex, dimension( ldx22,
* ) x22, integer ldx22, real, dimension( * ) theta, complex, dimension(
ldu1, * ) u1, integer ldu1, complex, dimension( ldu2, * ) u2, integer
ldu2, complex, dimension( ldv1t, * ) v1t, integer ldv1t, complex,
dimension( ldv2t, * ) v2t, integer ldv2t, complex, dimension( * ) work,
integer lwork, real, dimension( * ) rwork, integer lrwork, integer,
dimension( * ) iwork, integer info)
CUNCSD π
β¨ Purpose β¨
okay so CUNCSD computes the CS decomposition of an M-by-M partitioned unitary matrix X, and the math is literally this:
[ I 0 0 | 0 0 0 ]
[ 0 C 0 | 0 -S 0 ]
[ X11 | X12 ] [ U1 | ] [ 0 0 0 | 0 0 -I ] [ V1 | ]**H
X = [-----------] = [---------] [---------------------] [---------] .
[ X21 | X22 ] [ | U2 ] [ 0 0 0 | I 0 0 ] [ | V2 ]
[ 0 S 0 | 0 C 0 ]
[ 0 0 I | 0 0 0 ]
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).
π Parameters π
JOBU1βJOBU1isCHARACTER. If it's'Y',U1is computed; otherwise,U1is not computed.JOBU2βJOBU2isCHARACTER. If it's'Y',U2is computed; otherwise,U2is not computed.JOBV1TβJOBV1TisCHARACTER. If it's'Y',V1Tis computed; otherwise,V1Tis not computed.JOBV2TβJOBV2TisCHARACTER. If it's'Y',V2Tis computed; otherwise,V2Tis not computed.TRANSβTRANSisCHARACTER. If it's'T',X,U1,U2,V1T, andV2Tare stored in row-major order; otherwise,X,U1,U2,V1T, andV2Tare stored in column-major order.SIGNSβSIGNSisCHARACTER. If it's'O', the lower-left block is made nonpositive (the convention); otherwise, the upper-right block is made nonpositive (the convention).MβMisINTEGER. The number of rows and columns inX.PβPisINTEGER. The number of rows inX11andX12.0 <= P <= M.QβQisINTEGER. The number of columns inX11andX21.0 <= Q <= M.X11βX11isCOMPLEXarray, dimension(LDX11,Q). On entry, part of the unitary matrix whose CSD is desired.LDX11βLDX11isINTEGER. The leading dimension ofX11.LDX11 >= MAX(1,P).X12βX12isCOMPLEXarray, dimension(LDX12,M-Q). On entry, part of the unitary matrix whose CSD is desired.LDX12βLDX12isINTEGER. The leading dimension ofX12.LDX12 >= MAX(1,P).X21βX21isCOMPLEXarray, dimension(LDX21,Q). On entry, part of the unitary matrix whose CSD is desired.LDX21βLDX21isINTEGER. The leading dimension ofX11.LDX21 >= MAX(1,M-P).X22βX22isCOMPLEXarray, dimension(LDX22,M-Q). On entry, part of the unitary matrix whose CSD is desired.LDX22βLDX22isINTEGER. The leading dimension ofX11.LDX22 >= MAX(1,M-P).THETAβTHETAisREALarray, dimension(R), in whichR = MIN(P,M-P,Q,M-Q).C = DIAG( COS(THETA(1)), ... , COS(THETA(R)) )andS = DIAG( SIN(THETA(1)), ... , SIN(THETA(R)) ).U1βU1isCOMPLEXarray, dimension(LDU1,P). IfJOBU1 = 'Y',U1contains theP-by-Punitary matrixU1.LDU1βLDU1isINTEGER. The leading dimension ofU1. IfJOBU1 = 'Y',LDU1 >= MAX(1,P).U2βU2isCOMPLEXarray, dimension(LDU2,M-P). IfJOBU2 = 'Y',U2contains the(M-P)-by-(M-P)unitary matrixU2.LDU2βLDU2isINTEGER. The leading dimension ofU2. IfJOBU2 = 'Y',LDU2 >= MAX(1,M-P).V1TβV1TisCOMPLEXarray, dimension(LDV1T,Q). IfJOBV1T = 'Y',V1Tcontains theQ-by-Qunitary matrixV1**H.LDV1TβLDV1TisINTEGER. The leading dimension ofV1T. IfJOBV1T = 'Y',LDV1T >= MAX(1,Q).V2TβV2TisCOMPLEXarray, dimension(LDV2T,M-Q). IfJOBV2T = 'Y',V2Tcontains the(M-Q)-by-(M-Q)unitary matrixV2**H.LDV2TβLDV2TisINTEGER. The leading dimension ofV2T. IfJOBV2T = 'Y',LDV2T >= MAX(1,M-Q).WORKβWORKisCOMPLEXarray, dimension(MAX(1,LWORK)). On exit, ifINFO = 0,WORK(1)returns the optimalLWORK.LWORKβLWORKisINTEGER. The dimension of the arrayWORK. IfLWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of theWORKarray, returns this value as the first entry of the work array, and no error message related toLWORKis issued byXERBLA.RWORKβRWORKisREALarray, dimensionMAX(1,LRWORK). On exit, ifINFO = 0,RWORK(1)returns the optimalLRWORK. IfINFO > 0on exit,RWORK(2:R)contains the valuesPHI(1), ...,PHI(R-1)that, together withTHETA(1), ...,THETA(R), define the matrix in intermediate bidiagonal-block form remaining after nonconvergence.INFOspecifies the number of nonzeroPHI's.LRWORKβLRWORKisINTEGER. The dimension of the arrayRWORK. IfLRWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of theRWORKarray, returns this value as the first entry of the work array, and no error message related toLRWORKis issued byXERBLA.IWORKβIWORKisINTEGERarray, dimension(M-MIN(P,M-P,Q,M-Q)).INFOβINFOisINTEGER.= 0: successful exit.< 0: ifINFO = -i, thei-th argument had an illegal value.> 0:CBBCSDdid not converge. See the description ofRWORKabove for details.
π References π
[1] Brian D. Sutton. Computing the complete CS decomposition. Numer. Algorithms, 50(1):33-65, 2009.
π Author π
- Univ. of Tennessee
- Univ. of California Berkeley
- Univ. of Colorado Denver
- NAG Ltd.
Definition at line 314 of file cuncsd.f. π
recursive subroutine dorcsd (character jobu1, character jobu2, character jobv1t, character jobv2t, character trans, character signs, integer m, integer p, integer q, double precision, dimension( ldx11, * ) x11, integer ldx11, double precision, dimension( ldx12, * ) x12, integer ldx12, double precision, dimension( ldx21, * ) x21, integer ldx21, double precision, dimension( ldx22, * ) x22, integer ldx22, double precision, dimension( * ) theta, double precision, dimension( ldu1, * ) u1, integer ldu1, double precision, dimension( ldu2, * ) u2, integer ldu2, double precision, dimension( ldv1t, * ) v1t, integer ldv1t, double precision, dimension( ldv2t, * ) v2t, integer ldv2t, double precision, dimension( * ) work, integer lwork, integer, dimension( * ) iwork, integer info)
recursive subroutine dorcsd (character jobu1, character jobu2, character
jobv1t, character jobv2t, character trans, character signs, integer m,
integer p, integer q, double precision, dimension( ldx11, * ) x11,
integer ldx11, double precision, dimension( ldx12, * ) x12, integer
ldx12, double precision, dimension( ldx21, * ) x21, integer ldx21,
double precision, dimension( ldx22, * ) x22,
integer ldx22, double precision, dimension( * ) theta, double precision,
dimension( ldu1, * ) u1, integer ldu1, double precision, dimension(
ldu2, * ) u2, integer ldu2, double precision, dimension( ldv1t, * ) v1t,
integer ldv1t, double precision, dimension( ldv2t, * ) v2t, integer
ldv2t, double precision, dimension( * ) work, integer lwork, integer,
dimension( * ) iwork, integer info)
DORCSD π₯
β¨ Purpose
π¦ DORCSD π¦
β¨ Purpose β¨
Okay bestie, so DORCSD computes the CS decomposition of an M-by-M partitioned orthogonal matrix X. Here's the whole lewk, and yes it's giving main character:
[ I 0 0 | 0 0 0 ]
[ 0 C 0 | 0 -S 0 ]
[ X11 | X12 ] [ U1 | ] [ 0 0 0 | 0 0 -I ] [ V1 | ]**T
X = [-----------] = [---------] [---------------------] [---------] .
[ X21 | X22 ] [ | U2 ] [ 0 0 0 | I 0 0 ] [ | V2 ]
[ 0 S 0 | 0 C 0 ]
[ 0 0 I | 0 0 0 ]
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).
Like, that's the whole vibe. C and S literally can't both be big at the same time because they'd blow past the identity β trigonometry said so π
π Parameters π
JOBU1βCHARACTER. Tells us ifU1is invited to the party:= 'Y':U1is computed;- otherwise:
U1is not computed.
JOBU2βCHARACTER. Same energy, but forU2:= 'Y':U2is computed;- otherwise:
U2is not computed.
JOBV1TβCHARACTER. And now forV1T:= 'Y':V1Tis computed;- otherwise:
V1Tis not computed.
JOBV2TβCHARACTER. Last of the job squad, forV2T:= 'Y':V2Tis computed;- otherwise:
V2Tis not computed.
TRANSβCHARACTER. Storage order check, iykyk:= 'T':X,U1,U2,V1T, andV2Tare stored in row-major order;- otherwise:
X,U1,U2,V1T, andV2Tare stored in column-major order.
SIGNSβCHARACTER. Which block gets the nonpositive treatment:= 'O': The lower-left block is made nonpositive (the convention);- otherwise: The upper-right block is made nonpositive (the convention).
MβINTEGER. The number of rows and columns inX. It's a square situation, periodt.PβINTEGER. The number of rows inX11andX12.0 <= P <= M.QβINTEGER. The number of columns inX11andX21.0 <= Q <= M.X11βDOUBLE PRECISION array, dimension (LDX11,Q). On entry, part of the orthogonal matrix whose CSD is desired. She's the top-left girly π«ΆLDX11βINTEGER. The leading dimension ofX11.LDX11 >= MAX(1,P).X12βDOUBLE PRECISION array, dimension (LDX12,M-Q). On entry, part of the orthogonal matrix whose CSD is desired.LDX12βINTEGER. The leading dimension ofX12.LDX12 >= MAX(1,P).X21βDOUBLE PRECISION array, dimension (LDX21,Q). On entry, part of the orthogonal matrix whose CSD is desired.LDX21βINTEGER. The leading dimension ofX11.LDX21 >= MAX(1,M-P). (Yeah it saysX11β that's what the page says, not me, don't come for me π)X22βDOUBLE PRECISION array, dimension (LDX22,M-Q). On entry, part of the orthogonal matrix whose CSD is desired.LDX22βINTEGER. The leading dimension ofX11.LDX22 >= MAX(1,M-P). (Same deal as above, bestie β verbatim.)THETAβDOUBLE PRECISION array, dimension (R), in whichR = MIN(P,M-P,Q,M-Q). The angles themselves:U1βDOUBLE PRECISION array, dimension (LDU1,P). IfJOBU1 = 'Y',U1contains the P-by-P orthogonal matrixU1.LDU1βINTEGER. The leading dimension ofU1. IfJOBU1 = 'Y',LDU1 >= MAX(1,P).U2βDOUBLE PRECISION array, dimension (LDU2,M-P). IfJOBU2 = 'Y',U2contains the (M-P)-by-(M-P) orthogonal matrixU2.LDU2βINTEGER. The leading dimension ofU2. IfJOBU2 = 'Y',LDU2 >= MAX(1,M-P).V1TβDOUBLE PRECISION array, dimension (LDV1T,Q). IfJOBV1T = 'Y',V1Tcontains the Q-by-Q matrix orthogonal matrixV1**T.LDV1TβINTEGER. The leading dimension ofV1T. IfJOBV1T = 'Y',LDV1T >= MAX(1,Q).V2TβDOUBLE PRECISION array, dimension (LDV2T,M-Q). IfJOBV2T = 'Y',V2Tcontains the (M-Q)-by-(M-Q) orthogonal matrixV2**T.LDV2TβINTEGER. The leading dimension ofV2T. IfJOBV2T = 'Y',LDV2T >= MAX(1,M-Q).WORKβDOUBLE PRECISION array, dimension (MAX(1,LWORK)). The scratch space, and she's kind of a diary:- On exit, if
INFO = 0,WORK(1)returns the optimalLWORK. - If
INFO > 0on exit,WORK(2:R)contains the valuesPHI(1), ...,PHI(R-1)that, together withTHETA(1), ...,THETA(R), define the matrix in intermediate bidiagonal-block form remaining after nonconvergence.INFOspecifies the number of nonzeroPHI's.
- On exit, if
LWORKβINTEGER. The dimension of the arrayWORK.- If
LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of theWORKarray, returns this value as the first entry of the work array, and no error message related toLWORKis issued byXERBLA. (So like,-1is not a crime, it's a question β¨)
- If
IWORKβINTEGER array, dimension (M-MIN(P, M-P, Q, M-Q)).INFOβINTEGER. The receipts:= 0: successful exit.< 0: ifINFO = -i, the i-th argument had an illegal value.> 0:DBBCSDdid not converge. See the description ofWORKabove for details.
π References π
[1] Brian D. Sutton. Computing the complete CS decomposition. Numer. Algorithms, 50(1):33-65, 2009.
π Author π
- Univ. of Tennessee
- Univ. of California Berkeley
- Univ. of Colorado Denver
- NAG Ltd.
Definition at line 295 of file dorcsd.f.
π recursive subroutine sorcsd β the REAL (single precision) version π
recursive subroutine sorcsd (character jobu1, character jobu2, character
jobv1t, character jobv2t, character trans, character signs, integer m,
integer p, integer q, real, dimension( ldx11, * ) x11, integer ldx11,
real, dimension( ldx12, * ) x12, integer ldx12, real, dimension( ldx21,
* ) x21, integer ldx21, real, dimension( ldx22,
* ) x22, integer ldx22, real, dimension( * ) theta, real, dimension(
ldu1, * ) u1, integer ldu1, real, dimension( ldu2, * ) u2, integer ldu2,
real, dimension( ldv1t, * ) v1t, integer ldv1t, real, dimension( ldv2t,
* ) v2t, integer ldv2t, real, dimension( * ) work, integer lwork,
integer, dimension( * ) iwork, integer info)
SORCSD
β¨ Purpose β¨
Girl, it's the exact same story, just in REAL. SORCSD computes the CS decomposition of an M-by-M partitioned orthogonal matrix X:
[ I 0 0 | 0 0 0 ]
[ 0 C 0 | 0 -S 0 ]
[ X11 | X12 ] [ U1 | ] [ 0 0 0 | 0 0 -I ] [ V1 | ]**T
X = [-----------] = [---------] [---------------------] [---------] .
[ X21 | X22 ] [ | U2 ] [ 0 0 0 | I 0 0 ] [ | V2 ]
[ 0 S 0 | 0 C 0 ]
[ 0 0 I | 0 0 0 ]
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).
Same decomposition, same drama, half the bytes π
π Parameters π
JOBU1βCHARACTER. Decides ifU1gets computed:= 'Y':U1is computed;- otherwise:
U1is not computed.
JOBU2βCHARACTER. Decides ifU2gets computed:= 'Y':U2is computed;- otherwise:
U2is not computed.
JOBV1TβCHARACTER. Decides ifV1Tgets computed:= 'Y':V1Tis computed;- otherwise:
V1Tis not computed.
JOBV2TβCHARACTER. Decides ifV2Tgets computed:= 'Y':V2Tis computed;- otherwise:
V2Tis not computed.
TRANSβCHARACTER. Storage order, once again:= 'T':X,U1,U2,V1T, andV2Tare stored in row-major order;- otherwise:
X,U1,U2,V1T, andV2Tare stored in column-major order.
SIGNSβCHARACTER. Picking which block goes nonpositive:= 'O': The lower-left block is made nonpositive (the convention);- otherwise: The upper-right block is made nonpositive (the convention).
MβINTEGER. The number of rows and columns inX.PβINTEGER. The number of rows inX11andX12.0 <= P <= M.QβINTEGER. The number of columns inX11andX21.0 <= Q <= M.X11βREAL array, dimension (LDX11,Q). On entry, part of the orthogonal matrix whose CSD is desired.LDX11βINTEGER. The leading dimension ofX11.LDX11 >= MAX(1,P).X12βREAL array, dimension (LDX12,M-Q). On entry, part of the orthogonal matrix whose CSD is desired.LDX12βINTEGER. The leading dimension ofX12.LDX12 >= MAX(1,P).
β¦and we are back in the SORCSD parameter roll-call, bestie, no time to waste π
LDX12βINTEGER. The leading dimension of X12, and the requirement isLDX12 >= MAX(1,P). That's the law, fr fr.X21βREAL array, dimension (LDX21,Q). On entry, part of the orthogonal matrix whose CSD is desired. She's a supporting character but she matters πLDX21βINTEGER. The leading dimension of X11.LDX21 >= MAX(1,M-P). (Yes, the docs really say X11 here β not my typo, I'm just the messenger π)X22βREAL array, dimension (LDX22,M-Q). On entry, part of the orthogonal matrix whose CSD is desired.LDX22βINTEGER. The leading dimension of X11.LDX22 >= MAX(1,M-P). (Again with the X11 β the source said it, so we say it π«Ά)THETAβREAL array, dimension (R), in whichR = MIN(P,M-P,Q,M-Q). And the vibes are:
C = DIAG( COS(THETA(1)), ... , COS(THETA(R)) ) and
S = DIAG( SIN(THETA(1)), ... , SIN(THETA(R)) ).
The angles literally become the C and S matrices. Iconic behaviour πΈ
U1βREAL array, dimension (LDU1,P). IfJOBU1 = 'Y', U1 contains the P-by-P orthogonal matrix U1.LDU1βINTEGER. The leading dimension of U1. IfJOBU1 = 'Y', thenLDU1 >= MAX(1,P).U2βREAL array, dimension (LDU2,M-P). IfJOBU2 = 'Y', U2 contains the (M-P)-by-(M-P) orthogonal matrix U2.LDU2βINTEGER. The leading dimension of U2. IfJOBU2 = 'Y', thenLDU2 >= MAX(1,M-P).V1TβREAL array, dimension (LDV1T,Q). IfJOBV1T = 'Y', V1T contains the Q-by-Q matrix orthogonal matrix V1**T. (They wrote "matrix orthogonal matrix", and honestly? same energy π)LDV1TβINTEGER. The leading dimension of V1T. IfJOBV1T = 'Y', thenLDV1T >= MAX(1,Q).V2TβREAL array, dimension (LDV2T,M-Q). IfJOBV2T = 'Y', V2T contains the (M-Q)-by-(M-Q) orthogonal matrix V2**T.LDV2TβINTEGER. The leading dimension of V2T. IfJOBV2T = 'Y', thenLDV2T >= MAX(1,M-Q).WORKβREAL array, dimension (MAX(1,LWORK)). On exit, ifINFO = 0,WORK(1)returns the optimal LWORK. And here's the spicy part: ifINFO > 0on exit,WORK(2:R)contains the valuesPHI(1), ..., PHI(R-1)that, together withTHETA(1), ..., THETA(R), define the matrix in intermediate bidiagonal-block form remaining after nonconvergence.INFOspecifies the number of nonzero PHI's. So yeah, if things go sideways, the leftovers are literally sitting in WORK πLWORKβINTEGER. The dimension of the array WORK.
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. Sneaky little query mode, we love her β¨
IWORKβINTEGER array, dimension (M-MIN(P, M-P, Q, M-Q)). That's the whole description. Short queen. πINFOβINTEGER.
= 0: successful exit.
< 0: if INFO = -i, the i-th argument had an illegal value.
> 0: SBBCSD did not converge. See the description of WORK
above for details.
That > 0 case is the "she didn't converge" moment β go reread the WORK entry, it's all up there π₯
π References
[1] Brian D. Sutton. Computing the complete CS decomposition. Numer. Algorithms, 50(1):33-65, 2009.
π Author
- Univ. of Tennessee
- Univ. of California Berkeley
- Univ. of Colorado Denver
- NAG Ltd.
π Definition
Definition at line 295 of file sorcsd.f.
π¦ ZUNCSD
Okay so now we go complex, bestie β literally. Here's the signature, copied exactly, no notes:
recursive subroutine zuncsd (character jobu1, character jobu2, character
jobv1t, character jobv2t, character trans, character signs, integer m,
integer p, integer q, complex*16, dimension( ldx11, * ) x11, integer
ldx11, complex*16, dimension( ldx12, * ) x12, integer ldx12, complex*16,
dimension( ldx21, * ) x21, integer ldx21, complex*16, dimension( ldx22,
* ) x22, integer ldx22, double precision, dimension( * ) theta,
complex*16, dimension( ldu1, * ) u1, integer ldu1, complex*16,
dimension( ldu2, * ) u2, integer ldu2, complex*16, dimension( ldv1t, * )
v1t, integer ldv1t, complex*16, dimension( ldv2t, * ) v2t, integer
ldv2t, complex*16, dimension( * ) work, integer lwork, double precision,
dimension( * ) rwork, integer lrwork, integer, dimension( * ) iwork,
integer info)
Yeah. That's the whole cast list. Deep breath π«Ά
β¨ Purpose
ZUNCSD computes the CS decomposition of an M-by-M partitioned unitary matrix X:
[ I 0 0 | 0 0 0 ]
[ 0 C 0 | 0 -S 0 ]
[ X11 | X12 ] [ U1 | ] [ 0 0 0 | 0 0 -I ] [ V1 | ]**H
X = [-----------] = [---------] [---------------------] [---------] .
[ X21 | X22 ] [ | U2 ] [ 0 0 0 | I 0 0 ] [ | V2 ]
[ 0 S 0 | 0 C 0 ]
[ 0 0 I | 0 0 0 ]
Look at that factorization. She's stunning. The way those identity blocks and C and S blocks just slot into place? Main character energy, no cap π
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).
So R is the little one β the minimum of the four block dimensions. She's small but she runs the whole show π
π Parameters
JOBU1βCHARACTER.
= 'Y': U1 is computed;
otherwise: U1 is not computed.
JOBU2βCHARACTER.
= 'Y': U2 is computed;
otherwise: U2 is not computed.
JOBV1TβCHARACTER.
= 'Y': V1T is computed;
otherwise: V1T is not computed.
JOBV2TβCHARACTER.
= 'Y': V2T is computed;
otherwise: V2T is not computed.
Four job flags, all the same deal: 'Y' or literally anything else. Pick your faves π
TRANSβCHARACTER.
= 'T': X, U1, U2, V1T, and V2T are stored in row-major
order;
otherwise: X, U1, U2, V1T, and V2T are stored in column-
major order.
Note it's all five of them that flip together β X, U1, U2, V1T, and V2T. No mixing and matching, bestie π
SIGNSβCHARACTER.
= 'O': The lower-left block is made nonpositive (the
convention);
otherwise: The upper-right block is made nonpositive (the
convention).
Both branches are described as "(the convention)", which is deeply funny to me and I refuse to edit it π
MβINTEGER. The number of rows and columns in X. Square, obviously, she's built like that.PβINTEGER. The number of rows in X11 and X12.0 <= P <= M.QβINTEGER. The number of columns in X11 and X21.0 <= Q <= M.X11βCOMPLEX*16 array, dimension (LDX11,Q). On entry, part of the unitary matrix whose CSD is desired.LDX11βINTEGER. The leading dimension of X11.LDX11 >= MAX(1,P).X12βCOMPLEX*16 array, dimension (LDX12,M-Q). On entry, part of the unitary matrix whose CSD is desired.LDX12βINTEGER. The leading dimension of X12.LDX12 >= MAX(1,P).X21βCOMPLEX*16 array, dimension (LDX21,Q). On entry, part of the unitary matrix whose CSD is desired.LDX21βINTEGER. The leading dimension of X11.LDX21 >= MAX(1,M-P). (The "X11" is in the original β I'm not out here renaming things π)X22βCOMPLEX*16 array, dimension (LDX22,M-Q). On entry, part of the unitary matrix whose CSD is desired.LDX22βINTEGER. The leading dimension of X11.LDX22 >= MAX(1,M-P). (Same deal. X11 again. The docs said it, so it's canon.)THETAβDOUBLE PRECISION array, dimension (R), in whichR = MIN(P,M-P,Q,M-Q).
C = DIAG( COS(THETA(1)), ... , COS(THETA(R)) ) and
S = DIAG( SIN(THETA(1)), ... , SIN(THETA(R)) ).
Same angles-to-matrices pipeline as before, but now the angles are DOUBLE PRECISION because the matrix is complex. Balance π
U1βCOMPLEX*16 array, dimension (LDU1,P). IfJOBU1 = 'Y', U1 contains the P-by-P unitary matrix U1.LDU1βINTEGER. The leading dimension of U1. IfJOBU1 = 'Y', thenLDU1 >= MAX(1,P).U2βCOMPLEX*16 array, dimension (LDU2,M-P). IfJOBU2 = 'Y', U2 contains the (M-P)-by-(M-P) unitary matrix U2.LDU2βINTEGER. The leading dimension of U2. IfJOBU2 = 'Y', thenLDU2 >= MAX(1,M-P).V1TβCOMPLEX*16 array, dimension (LDV1T,Q). IfJOBV1T = 'Y', V1T contains the Q-by-Q matrix unitary matrix V1**H. (Yes: "matrix unitary matrix". We keep it. We respect it. π«‘)LDV1TβINTEGER. The leading dimension of V1T. IfJOBV1T = 'Y', thenLDV1T >= MAX(1,Q).V2TβCOMPLEX*16 array, dimension (LDV2T,M-Q). IfJOBV2T = 'Y', V2T contains the (M-Q)-by-(M-Q) unitary matrix V2**H.LDV2TβINTEGER. The leading dimension of V2T. IfJOBV2T = 'Y', thenLDV2T >= MAX(1,M-Q).WORKβCOMPLEX*16 array, dimension (MAX(1,LWORK)). On exit, ifINFO = 0,WORK(1)returns the optimal LWORK.LWORKβINTEGER. The dimension of the array WORK.
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. Same trick as her real-valued sister β ask nicely, get the size back, no XERBLA shouting π
RWORKβ
RWORK πΈ
RWORK is a DOUBLE PRECISION 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.
LRWORK π
LRWORK is INTEGER β it's 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.
IWORK π
IWORK is an INTEGER array, dimension (M-MIN(P,M-P,Q,M-Q)).
INFO π₯
INFO is INTEGER:
INFO = 0β successful exit.INFO < 0β ifINFO = -i, thei-th argument had an illegal value.INFO > 0βZBBCSDdid not converge. See the description ofRWORKabove for details.
References π
[1] Brian D. Sutton. Computing the complete CS decomposition. Numer. Algorithms, 50(1):33-65, 2009.
Author π
- Univ. of Tennessee
- Univ. of California Berkeley
- Univ. of Colorado Denver
- NAG Ltd.
Definition at line 314 of file zuncsd.f.
Author (Doxygen edition) π«Ά
Generated automatically by Doxygen for LAPACK from the source code.
Bye bestie π β this page is from LAPACK Version 3.12.0, and it's the uncsd(3) page β¨π
π¦ where this page comes from
- arch rolling: lapack-doc 3.12.1-2 Β· custom
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms