Real(3pm)
π Real(3pm) β PDL::LinearAlgebra::Real π
User Contributed Perl Documentation β yes bestie, we're in the contributed docs section, come sit with me π«Ά
π NAME
PDL::LinearAlgebra::Real β it's the PDL interface to the real lapack linear algebra programming library. That's the whole vibe. Linear algebra. Real numbers. Lapack. Slay. β¨
π SYNOPSIS
okay so first things first, you gotta load it:
use PDL::LinearAlgebra::Real;
$a = random (100,100);
$s = zeroes(100);
$u = zeroes(100,100);
$v = zeroes(100,100);
$info = 0;
$job = 0;
gesdd($a, $job, $info, $s , $u, $v);
look at that. random to make a matrix, zeroes to make the outputs, then gesdd does the thing and drops the answers into $s, $u, $v. main character energy fr fr π
πΈ DESCRIPTION
This module is your lil doorway into parts of the real lapack library. Like, it's an interface. That's its whole job.
And here's the cute part: these routines are flexible, they accept either float or double ndarrays. So you don't gotta fight it, just feed it whichever precision you're feeling. π
π₯ FUNCTIONS
π¦ gtsv
Signature: ([phys]DL(n); [phys]D(n); [phys]DU(n); [io,phys]B(n,nrhs); int [o,phys]info())
So what does it do? It solves this equation right here:
A * X = B
...where A is an "n" by "n" tridiagonal matrix, solved by Gaussian elimination with partial pivoting, and B is an "n" by "nrhs" matrix. Iconic, honestly.
Pro tip bestie: you can solve A**T*X = B too β just swap the order of the arguments DU and DL. That's it. That's the trick. π€―
NB β this differs from the LINPACK functiondgtsl: hereDLstarts from its first element, whereas the LINPACK equivalent starts from its second element. Not me catching that off-by-one for you. π
π Arguments
DLβ On entry,DLmust contain the(n-1)sub-diagonal elements ofA. On exit,DLis overwritten by the(n-2)elements of the second super-diagonal of the upper triangular matrixUfrom the LU factorization ofA, sitting inDL(1), ..., DL(n-2).Dβ On entry,Dmust contain the diagonal elements ofA. On exit,Dgets overwritten by thendiagonal elements ofU.DUβ On entry,DUmust contain the(n-1)super-diagonal elements ofA. On exit,DUis overwritten by the(n-1)elements of the first super-diagonal of theU.Bβ On entry, thenbynrhsmatrix of right hand side matrixB. On exit, ifinfo = 0, thenbynrhssolution matrixX. πinfoβ the receipts, always the receipts:= 0: successful exit π< 0: ifinfo = -i, the i-th argument had an illegal value π> 0: ifinfo = i,U(i,i)is exactly zero, and the solution has not been computed. The factorization has not been completed unlessi = n.
$dl = random(float, 9);
$d = random(float, 10);
$du = random(float, 9);
$b = random(10,5);
gtsv($dl, $d, $du, $b, ($info=null));
print "X is:\n$b" unless $info;
And the bad-value tea β: gtsv ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. iykyk.
π§ gesvd
Signature: ([io]A(m,n); int jobu(); int jobvt(); [o]s(minmn); [o]U(p,p); [o]VT(s,s); int [o]info())
Computes the singular value decomposition (SVD) of a real M-by-N matrix A. The moment. The icon. π
The SVD is written like this:
A = U * SIGMA * V'
where SIGMA is an M-by-N matrix that's zero everywhere except for its min(m,n) diagonal elements, U is an M-by-M orthogonal matrix, and V is an N-by-N orthogonal matrix. The diagonal elements of SIGMA are the singular values of A β they're real and non-negative, and they come back in descending order. The first min(m,n) columns of U and V are the left and right singular vectors of A.
β οΈ heads up: the routine returnsVT = V', notV. Don't be fooled bestie, the transpose is the whole point.
π― Arguments
jobuβ Specifies options for computing all or part of the matrixU:= 0: no columns ofU(no left singular vectors) are computed.= 1: allMcolumns ofUare returned in arrayU:= 2: the firstmin(m,n)columns ofU(the left singular vectors) are returned in the arrayU;= 3: the firstmin(m,n)columns ofU(the left singular vectors) are overwritten on the arrayA;
jobvtβ Specifies options for computing all or part of the matrixV':= 0: no rows ofV'(no right singular vectors) are computed.= 1: allNrows ofV'are returned in the arrayVT;= 2: the firstmin(m,n)rows ofV'(the right singular vectors) are returned in the arrayVT;= 3: the firstmin(m,n)rows ofV'(the right singular vectors) are overwritten on the arrayA;
π¨ WARNING:jobvtandjobucannot both be 3. You cannot do both. Pick one. Periodt.
Aβ On entry, the M-by-N matrixA. On exit:- if
jobu = 3,Ais overwritten with the firstmin(m,n)columns ofU(the left singular vectors, stored columnwise); - if
jobvt = 3,Ais overwritten with the firstmin(m,n)rows ofV'(the right singular vectors, stored rowwise); - if
jobu != 3andjobvt != 3, the contents ofAare destroyed. π
- if
sβ The singular values ofA, sorted so thats(i) >= s(i+1).Uβ Ifjobu = 1,Ucontains the M-by-M orthogonal matrixU; ifjobu = 3,Ucontains the firstmin(m,n)columns ofU(the left singular vectors, stored columnwise); ifjobu = 0or3,Uis not referenced. Min size =[1,1].VTβ Ifjobvt = 1,VTcontains the N-by-N orthogonal matrixV'; ifjobvt = 2,VTcontains the firstmin(m,n)rows ofV'(the right singular vectors, stored rowwise); ifjobvt = 0or3,VTis not referenced. Min size =[1,1].infoβ= 0: successful exit.< 0: ifinfo = -i, the i-th argument had an illegal value.> 0: ifbdsqrdid not converge,infospecifies how many superdiagonals of an intermediate bidiagonal formBdid not converge to zero.
$a = random (float, 100,100);
$s = zeroes(float, 100);
$u = zeroes(float, 100,100);
$vt = zeroes(float, 100,100);
$info = pdl(long, 0);
gesvd($a, 2, 2, $s , $u, $vt, $info);
Bad-value behaviour, same as always: gesvd ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. πΈ
π gesdd
Signature: ([io]A(m,n); int jobz(); [o]s(minmn); [o]U(p,p); [o]VT(s,s); int [o]info(); int [t]iwork(iworkn))
Also computes the singular value decomposition (SVD) of a real M-by-N matrix A β but this one is built different.
This routine use the Coppen's divide and conquer algorithm. It is much faster than the simple driver for large matrices, but uses more workspace. Speed demon behaviour, but it wants its space. πββοΈπ¨
π― Arguments
jobzβ Specifies options for computing all or part of matrix:= 0: no columns ofUor rows ofV'are computed;= 1: allMcolumns ofUand allNrows ofV'are returned in the arraysUandVT;= 2: the firstmin(M,N)columns ofUand the firstmin(M,N)rows ofV'are returned in the arraysUandVT;= 3: IfM >= N, the firstNcolumns ofUare overwritten on the arrayAand all rows ofV'are returned in the arrayVT; otherwise, all columns ofUare returned in the arrayUand the firstMrows ofV'are overwritten on the arrayA.
Aβ On entry, the M-by-N matrixA. On exit:- if
jobz = 3,Ais overwritten with the firstNcolumns ofU(the left singular vectors, stored columnwise) ifM >= N;Ais overwritten with the firstMrows ofV'(the right singular vectors, stored rowwise) otherwise. - if
jobz != 3, the contents ofAare destroyed. π
- if
sβ The singular values ofA, sorted so thats(i) >= s(i+1).Uβ Ifjobz = 1orjobz = 3andM < N,Ucontains the M-by-M orthogonal matrixU; ifjobz = 2,Ucontains the firstmin(M,N)columns ofU(the left singular vectors, stored columnwise); ifjobz = 3andM >= N, orjobz = 0,Uis not referenced. Min size =[1,1].VTβ Ifjobz = 1orjobz = 3andM >= N,VTcontains the N-by-N orthogonal matrixV'; ifjobz = 2,VTcontains the firstmin(M,N)rows ofV'(the right singular vectors, stored rowwise); ifjobz = 3andM < N, orjobz = 0,VTis not referenced. Min size =[1,1].infoβ= 0: successful exit.< 0: ifinfo = -i, the i-th argument had an illegal value.> 0:bdsdcdid not converge, updating process failed. π
$lines = 50;
$columns = 100;
$a = random (float, $lines, $columns);
$min = $lines < $columns ? $lines : $columns;
$s = zeroes(float, $min);
$u = zeroes(float, $lines, $lines);
$vt = zeroes(float, $columns, $columns);
$info = long (0);
gesdd($a, 1, $s , $u, $vt, $info);
Bad-value behaviour, one more time for the people in the back: gesdd ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. β¨
π ggsvd
Signature: ([io]A(m,n); int jobu(); int jobv(); int jobq(); [io]B(p,n); int [o]k(); int [o]l();[o]alpha(n);[o]beta(n); [o]U(q,q); [o]V(r,r); [o]Q(s,s); int [o]iwork(n); int [o]info())
Computes the generalized singular value decomposition (GSVD) of an M-by-N real matrix A and a P-by-N real matrix B:
U'*A*Q = D1*( 0 R ), V'*B*Q = D2*( 0 R )
where U, V and Q are orthogonal matrices, and Z' is the transpose
of Z.
Let K+L = the effective numerical rank of the matrix (A',B')', then R is a K+L-by-K+L nonsingular upper triangular matrix, D1 and D2 are M-by-(K+L) and P-by-(K+L) "diagonal" matrices and of the following structures, respectively:
If M-K-L >= 0,
K L
D1 = K ( I 0 )
L ( 0 C )
M-K-L ( 0 0 )
K L
D2 = L ( 0 S )
P-L ( 0 0 )
N-K-L K L
( 0 R ) = K ( 0 R11 R12 )
L ( 0 0 R22 )
where
C = diag( ALPHA(K+1), ... , ALPHA(K+L) ),
S = diag( BETA(K+1), ... , BETA(K+L) ),
C**2 + S**2 = I.
R is stored in A(1:K+L,N-K-L+1:N) on exit.
If M-K-L < 0,
K M-K K+L-M
D1 = K ( I 0 0 )
M-K ( 0 C 0 )
K M-K K+L-M
D2 = M-K ( 0 S 0 )
K+L-M ( 0 0 I )
P-L ( 0 0 0 )
okay so this is the shape of the decomposition, bestie β it's giving triangular realness:
N-K-L K M-K K+L-M
( 0 R ) = K ( 0 R11 R12 R13 )
M-K ( 0 0 R22 R23 )
K+L-M ( 0 0 0 R33 )
where
C = diag( ALPHA(K+1), ... , ALPHA(M) ),
S = diag( BETA(K+1), ... , BETA(M) ),
C**2 + S**2 = I.
(R11 R12 R13 ) is stored in A(1:M, N-K-L+1:N), and R33 is stored
( 0 R22 R23 )
in B(M-K+1:L,N+M-K-L+1:N) on exit.
This routine is out here computing C, S, R, and optionally the orthogonal transformation matrices U, V and Q.
In particular, if B is an N-by-N nonsingular matrix, then the GSVD of A and B implicitly gives the SVD of A*inv(B):
A*inv(B) = U*(D1*inv(D2))*V'.
If ( A',B')' has orthonormal columns, then the GSVD of A and B is also equal to the CS decomposition of A and B. Furthermore, the GSVD can be used to derive the solution of the eigenvalue problem:
A'*A x = lambda* B'*B x.
In some literature, the GSVD of A and B is presented in the form
U'*A*X = ( 0 D1 ), V'*B*X = ( 0 D2 )
where U and V are orthogonal and X is nonsingular, D1 and D2 are "diagonal".
The former GSVD form can be converted to the latter form by taking the nonsingular matrix X as
X = Q*( I 0 )
( 0 inv(R) ).
Arguments β¨
jobuβ= 0:Uis not computed.= 1: Orthogonal matrixUis computed;jobvβ= 0:Vis not computed.= 1: Orthogonal matrixVis computed;jobqβ= 0:Qis not computed.= 1: Orthogonal matrixQis computed;k:lβ On exit,kandlspecify the dimension of the subblocks described in the Purpose section.k + l = effective numerical rank of (A',B')'.Aβ On entry, theM-by-NmatrixA. On exit,Acontains the triangular matrixR, or part ofR.Bβ On entry, theP-by-NmatrixB. On exit,Bcontains the triangular matrixRifM-k-l < 0.alpha:betaβ On exit,alphaandbetacontain the generalized singular value pairs ofAandB;alpha(1:k) = 1,beta(1:k) = 0,- and if
M-k-l >= 0,alpha(k+1:k+l) = C,beta(k+1:k+l) = S,
- or if
M-k-l < 0,alpha(k+1:M)=C, alpha(M+1:k+l)=0beta(k+1:M) =S, beta(M+1:k+l) =1
- and
alpha(k+l+1:N) = 0beta(k+l+1:N) = 0
Uβ Ifjobu = 1,Ucontains theM-by-Morthogonal matrixU. Ifjobu = 0,Uis not referenced. Need a minimum array of(1,1)ifjobu = 0;Vβ Ifjobv = 1,Vcontains theP-by-Porthogonal matrixV. Ifjobv = 0,Vis not referenced. Need a minimum array of(1,1)ifjobv = 0;Qβ Ifjobq = 1,Qcontains theN-by-Northogonal matrixQ. Ifjobq = 0,Qis not referenced. Need a minimum array of(1,1)ifjobq = 0;iworkβ On exit,iworkstores the sorting information. More precisely, the following loop will sortalpha
for I = k+1, min(M,k+l)
swap alpha(I) and alpha(iwork(I))
endfor
such that alpha(1) >= alpha(2) >= ... >= alpha(N).
infoβ= 0: successful exit.< 0: ifinfo = -i, thei-th argument had an illegal value.> 0: ifinfo = 1, the Jacobi-type procedure failed to converge. For further details, see subroutinetgsja.
$k = null;
$l = null;
$A = random(5,6);
$B = random(7,6);
$alpha = zeroes(6);
$beta = zeroes(6);
$U = zeroes(5,5);
$V = zeroes(7,7);
$Q = zeroes(6,6);
$iwork = zeroes(long, 6);
$info = null;
ggsvd($A,1,1,1,$B,$k,$l,$alpha, $beta,$U, $V, $Q, $iwork,$info);
ggsvd ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
geev π₯
(A(n,n); int jobvl(); int jobvr(); [o]wr(n); [o]wi(n); [o]vl(m,m); [o]vr(p,p); int [o]info())
Computes for an N-by-N real nonsymmetric matrix A, the eigenvalues and, optionally, the left and/or right eigenvectors.
The right eigenvector v(j) of A satisfies:
A * v(j) = lambda(j) * v(j) where lambda(j) is its eigenvalue.
The left eigenvector u(j) of A satisfies:
u(j)**H * A = lambda(j) * u(j)**H where u(j)**H denotes the conjugate
transpose of u(j).
The computed eigenvectors are normalized to have Euclidean norm equal to 1 and largest component real.
Arguments β¨
jobvlβ= 0: left eigenvectors ofAare not computed;= 1: left eigenvectors ofAare computed.jobvrβ= 0: right eigenvectors ofAare not computed;= 1: right eigenvectors ofAare computed.AβAis overwritten.wr:wiβwrandwicontain the real and imaginary parts, respectively, of the computed eigenvalues. Complex conjugate pairs of eigenvalues appear consecutively with the eigenvalue having the positive imaginary part first.vlβ Ifjobvl = 1, the left eigenvectorsu(j)are stored one after another in the columns ofvl, in the same order as their eigenvalues elsevlis not referenced. If thej-th eigenvalue is real, thenu(j) = vl(:,j), thej-th column ofvl. If thej-th and(j+1)-st eigenvalues form a complex conjugate pair, thenu(j) = vl(:,j) + i*vl(:,j+1)andu(j+1) = vl(:,j) - i*vl(:,j+1). Min size =[1].vrβ Ifjobvr = 1, the right eigenvectorsv(j)are stored one after another in the columns ofvr, in the same order as their eigenvalues elsevris not referenced. If thej-th eigenvalue is real, thenv(j) = vr(:,j), thej-th column ofvr. If thej-th and(j+1)-st eigenvalues form a complex conjugate pair, thenv(j) = vr(:,j) + i*vr(:,j+1)andv(j+1) = vr(:,j) - i*vr(:,j+1). Min size =[1].infoβ= 0: successful exit.< 0: ifinfo = -i, thei-th argument had an illegal value.> 0: ifinfo = i, the QR algorithm failed to compute all the eigenvalues, and no eigenvectors have been computed; elementsi+1:Nofwrandwicontain eigenvalues which have converged.
$a = random (5, 5);
$wr = zeroes(5);
$wi = zeroes($wr);
$vl = zeroes($a);
$vr = zeroes($a);
$info = null;
geev($a, 1, 1, $wr, $wi, $vl, $vr, $info);
geev ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
geevx β¨
([io]A(n,n); int jobvl(); int jobvr(); int balance(); int sense(); [o]wr(n); [o]wi(n); [o]vl(m,m); [o]vr(p,p); int [o]ilo(); int [o]ihi(); [o]scale(n); [o]abnrm(); [o]rconde(q); [o]rcondv(r); int [o]info(); int [t]iwork(iworkn))
Computes for an N-by-N real nonsymmetric matrix A, the eigenvalues and, optionally, the left and/or right eigenvectors.
Optionally also, it computes a balancing transformation to improve the conditioning of the eigenvalues and eigenvectors (ilo, ihi, scale, and abnrm), reciprocal condition numbers for the eigenvalues (rconde), and reciprocal condition numbers for the right eigenvectors (rcondv).
The right eigenvector v(j) of A satisfies:
A * v(j) = lambda(j) * v(j)
where lambda(j) is its eigenvalue.
The left eigenvector u(j) of A satisfies:
u(j)**H * A = lambda(j) * u(j)**H
where u(j)**H denotes the conjugate transpose of u(j).
The computed eigenvectors are normalized to have Euclidean norm equal to 1 and largest component real.
Balancing a matrix means permuting the rows and columns to make it more nearly upper triangular, and applying a diagonal similarity transformation D * A * D**(-1), where D is a diagonal matrix, to make its rows and columns closer in norm and the condition numbers of its eigenvalues and eigenvectors smaller. The computed reciprocal condition numbers correspond to the balanced matrix. Permuting rows and columns will not change the condition numbers (in exact arithmetic) but diagonal scaling will. For further explanation of balancing, see section 4.10.2 of the LAPACK Users' Guide.
Arguments β¨
balanceβ Indicates how the input matrix should be diagonally scaled and/or permuted to improve the conditioning of its eigenvalues.= 0: Do not diagonally scale or permute;= 1: Perform permutations to make the matrix more nearly upper triangular. Do not diagonally scale;= 2: Diagonally scale the matrix, i.e. replaceAbyD*A*D**(-1), whereDis a diagonal matrix chosen to make the rows and columns ofAmore equal in norm. Do not permute;= 3: Both diagonally scale and permuteA. Computed reciprocal condition numbers will be for the matrix after balancing and/or permuting. Permuting does not change condition numbers (in exact arithmetic), but balancing does.
jobvlβ= 0: left eigenvectors ofAare not computed;= 1: left eigenvectors ofAare computed. Ifsense = 1or3,jobvlmust= 1.jobvr;β= 0: right eigenvectors ofAare not computed;= 1: right eigenvectors ofAare computed. Ifsense = 1or3,jobvrmust= 1.senseβ Determines which reciprocal condition numbers are computed.= 0: None are computed;= 1: Computed for eigenvalues only;= 2: Computed for right eigenvectors only;= 3: Computed for eigenvalues and right eigenvectors. Ifsense = 1or3, both left and right eigenvectors must also be computed (jobvl = 1andjobvr = 1).
Aβ TheN-by-Nmatrix. It is overwritten. Ifjobvl = 1orjobvr = 1,Acontains the real Schur form of the balanced version of the input matrixA.wr,wiβ okay so these two hold the real and imaginary parts of the eigenvalues we computed, respectively π. Here's the tea: complex conjugate eigenvalue pairs show up back to back, and the one with the positive imaginary part comes first. Periodt.vlβ ifjobvl = 1, the left eigenvectorsu(j)get stored one after another in the columns ofvl, in the exact same order as their eigenvalues. If not,vlisn't referenced at all, she's just sitting there π.- If the j-th eigenvalue is real, then
u(j) = vl(:,j)β that's the j-th column ofvl, bestie. - If the j-th and (j+1)-st eigenvalues form a complex conjugate pair, then
u(j) = vl(:,j) + i*vl(:,j+1)andu(j+1) = vl(:,j) - i*vl(:,j+1)β¨. - Min size =
[1].
- If the j-th eigenvalue is real, then
vrβ ifjobvr = 1, the right eigenvectorsv(j)get stored one after another in the columns ofvr, same order as their eigenvalues. Otherwisevris not referenced, no cap π .- If the j-th eigenvalue is real, then
v(j) = vr(:,j), the j-th column ofvr. - If the j-th and (j+1)-st eigenvalues form a complex conjugate pair, then
v(j) = vr(:,j) + i*vr(:,j+1)andv(j+1) = vr(:,j) - i*vr(:,j+1). - Min size =
[1].
- If the j-th eigenvalue is real, then
ilo,ihiβ integer values that get determined whenAwas balanced π. The balancedA(i,j) = 0ifI > JandJ = 1,...,ilo-1orI = ihi+1,...,N.scaleβ all the deets on the permutations and scaling factors that got applied when balancingAπΈ. IfP(j)is the index of the row and column interchanged with row and columnj, andD(j)is the scaling factor applied to row and columnj, then:
scale(J) = P(J), for J = 1,...,ilo-1
= D(J), for J = ilo,...,ihi
= P(J) for J = ihi+1,...,N.
The order in which the interchanges are made is N to ihi+1, then 1 to ilo-1 β iconic little sequence, honestly π¦.
abnrmβ the one-norm of the balanced matrix, aka the maximum of the sum of absolute values of elements of any column. It's giving "biggest column energy" β.rcondeβrconde(j)is the reciprocal condition number of the j-th eigenvalue π.rcondvβrcondv(j)is the reciprocal condition number of the j-th right eigenvector π.infoβ the vibe check at the end:
= 0: successful exit
< 0: if info = -i, the i-th argument had an illegal value.
> 0: if info = i, the QR algorithm failed to compute all the
eigenvalues, and no eigenvectors or condition numbers
have been computed; elements 1:ilo-1 and i+1:N of wr
and wi contain eigenvalues which have converged.
Okay and here's how you'd actually call it, in all her glory:
$a = random (5,5);
$wr = zeroes(5);
$wi = zeroes(5);
$vl = zeroes(5,5);
$vr = zeroes(5,5);
$ilo = null;
$ihi = null;
$scale = zeroes(5);
$abnrm = null;
$rconde = zeroes(5);
$rcondv = zeroes(5);
$info = null;
geevx($a, 1,1,3,3,$wr, $wi, $vl, $vr, $ilo, $ihi, $scale, $abnrm,$rconde, $rcondv, $info);
geevx ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. Not her problem, she's just passing the vibe along π.
ggev π¦
Signature: (A(n,n); int [phys]jobvl();int [phys]jobvr();B(n,n);[o]alphar(n);[o]alphai(n);[o]beta(n);[o]VL(m,m);[o]VR(p,p);int [o]info())
So for a pair of N-by-N real nonsymmetric matrices (A,B), this girl computes the generalized eigenvalues, and optionally the left and/or right generalized eigenvectors π₯.
A generalized eigenvalue for a pair of matrices (A,B) is a scalar lambda, or a ratio alpha/beta = lambda, such that A - lambda*B is singular. It's usually represented as the pair (alpha,beta), because there's a reasonable interpretation for beta=0, and even for both of them being zero π. (Yeah. Both zero. She said what she said.)
The right eigenvector v(j) corresponding to the eigenvalue lambda(j) of (A,B) satisfies:
A * v(j) = lambda(j) * B * v(j).
The left eigenvector u(j) corresponding to the eigenvalue lambda(j) of (A,B) satisfies:
u(j)**H * A = lambda(j) * u(j)**H * B .
where u(j)**H is the conjugate-transpose of u(j) β¨.
Arguments π«
jobvlβ pick your fighter:
= 0: do not compute the left generalized eigenvectors;
= 1: compute the left generalized eigenvectors.
jobvrβ same energy, other side:
= 0: do not compute the right generalized eigenvectors;
= 1: compute the right generalized eigenvectors.
Aβ on entry, the matrixAin the pair(A,B). On exit? A has been overwritten. She took it, bestie, it's gone π«Ά.Bβ on entry, the matrixBin the pair(A,B). On exit, B has been overwritten too. No survivors π.alphar,alphai,betaβ on exit,(alphar(j) + alphai(j)*i)/beta(j), forj=1,...,N, will be the generalized eigenvalues. Ifalphai(j)is zero, then the j-th eigenvalue is real; if it's positive, then the j-th and (j+1)-st eigenvalues are a complex conjugate pair, withalphai(j+1)negative π.
Note: the quotientsalphar(j)/beta(j)andalphai(j)/beta(j)may easily over- or underflow, andbeta(j)may even be zero π. So please, the user should avoid naively computing the ratioalpha/beta. However β plot twist βalpharandalphaiwill always be less than and usually comparable withnorm(A)in magnitude, andbetaalways less than and usually comparable withnorm(B)π.
VLβ ifjobvl = 1, the left eigenvectorsu(j)are stored one after another in the columns ofVL, in the same order as their eigenvalues. If the j-th eigenvalue is real, thenu(j) = VL(:,j), the j-th column ofVL. If the j-th and (j+1)-th eigenvalues form a complex conjugate pair, thenu(j) = VL(:,j)+i*VL(:,j+1)andu(j+1) = VL(:,j)-i*VL(:,j+1)πΈ. Each eigenvector will be scaled so the largest component hasabs(real part)+abs(imag. part)=1. Not referenced ifjobvl = 0.VRβ ifjobvr = 1, the right eigenvectorsv(j)are stored one after another in the columns ofVR, in the same order as their eigenvalues. If the j-th eigenvalue is real, thenv(j) = VR(:,j), the j-th column ofVR. If the j-th and (j+1)-th eigenvalues form a complex conjugate pair, thenv(j) = VR(:,j)+i*VR(:,j+1)andv(j+1) = VR(:,j)-i*VR(:,j+1)π. Each eigenvector will be scaled so the largest component hasabs(real part)+abs(imag. part)=1. Not referenced ifjobvr = 0.infoβ the final report card:
= 0: successful exit
< 0: if info = -i, the i-th argument had an illegal value.
= 1,...,N:
The QZ iteration failed. No eigenvectors have been
calculated, but alphar(j), alphai(j), and beta(j)
should be correct for j=info+1,...,N.
> N: =N+1: other than QZ iteration failed in hgeqz.
=N+2: error return from tgevc.
And the call, nice and clean:
$a = random(5,5);
$b = random(5,5);
$alphar = zeroes(5);
$alphai = zeroes(5);
$beta = zeroes(5);
$vl = zeroes(5,5);
$vr = zeroes(5,5);
ggev($a, 1, 1, $b, $alphar, $alphai, $beta, $vl, $vr, ($info=null));
ggev ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. Same rules as always, she's consistent π .
ggevx π
Signature: ([io,phys]A(n,n);int balanc();int jobvl();int jobvr();int sense();[io,phys]B(n,n);[o]alphar(n);[o]alphai(n);[o]beta(n);[o]VL(m,m);[o]VR(p,p);int [o]ilo();int [o]ihi();[o]lscale(n);[o]rscale(n);[o]abnrm();[o]bbnrm();[o]rconde(r);[o]rcondv(s);int [o]info(); int [t]bwork(bworkn); int [t]iwork(iworkn))
Okay so for a pair of N-by-N real nonsymmetric matrices (A,B), this one computes the generalized eigenvalues, and optionally the left and/or right generalized eigenvectors π¦.
Optionally, also, she computes a balancing transformation to improve the conditioning of the eigenvalues and eigenvectors (ilo, ihi, lscale, rscale, abnrm, and bbnrm), reciprocal condition numbers for the eigenvalues (rconde), and reciprocal condition numbers for the right eigenvectors (rcondv) β¨. She's doing the most, and honestly? She ate.
A generalized eigenvalue for a pair of matrices (A,B) is a scalar lambda, or a ratio alpha/beta = lambda, such that A - lambda*B is singular. It's usually represented as the pair (alpha,beta), because there's a reasonable interpretation for beta=0, and even for both being zero π«Ά.
The right eigenvector v(j) corresponding to the eigenvalue lambda(j) of (A,B) satisfies:
A * v(j) = lambda(j) * B * v(j) .
The left eigenvector u(j) corresponding to the eigenvalue lambda(j) of (A,B) satisfies:
u(j)**H * A = lambda(j) * u(j)**H * B.
where u(j)**H is the conjugate-transpose of u(j) β.
Further Details π
Balancing a matrix pair (A,B) includes, first, permuting rows and columns to isolate eigenvalues, and second, applying diagonal similarity transformation to the rows and columns to make the rows and columns as close in norm as possible π. The computed reciprocal condition numbers correspond to the balanced matrix. Permuting rows and columns will not change the condition numbers (in exact arithmetic) but diagonal scaling will. For further explanation of balancing, see section 4.11.1.2 of LAPACK Users' Guide π.
An approximate error bound on the chordal distance between the i-th computed generalized eigenvalue w and the corresponding exact eigenvalue lambda is:
chord(w, lambda) <= EPS * norm(abnrm, bbnrm) / rconde(I)
An approximate error bound for the angle between the i-th computed eigenvector vl(i) or vr(i) is given by:
EPS * norm(abnrm, bbnrm) / DIF(i).
For further explanation of the reciprocal condition numbers rconde and rcondv, see section 4.11 of LAPACK User's Guide π.
Arguments π«
balancβ specifies the balance option to be performed:
= 0: do not diagonally scale or permute;
= 1: permute only;
= 2: scale only;
= 3: both permute and scale.
Computed reciprocal condition numbers will be for the matrices after permuting and/or balancing. Permuting does not change condition numbers (in exact arithmetic), but balancing does β important, don't skip that part π.
jobvlβ your pick:
= 0: do not compute the left generalized eigenvectors;
= 1: compute the left generalized eigenvectors.
jobvrβ and the other side:
= 0: do not compute the right generalized eigenvectors;
= 1: compute the right generalized eigenvectors.
senseβ okay so this decides which reciprocal condition numbers get computed, bestie. = 0: none are computed; = 1: computed for eigenvalues only; = 2: computed for eigenvectors only; = 3: computed for eigenvalues and eigenvectors. πAβ On entry, the matrix A in the pair (A,B). On exit, A has been overwritten. If jobvl=1 or jobvr=1 or both, then A contains the first part of the real Schur form of the "balanced" versions of the input A and B. β¨Bβ On entry, the matrix B in the pair (A,B). On exit, B has been overwritten. If jobvl=1 or jobvr=1 or both, then B contains the second part of the real Schur form of the "balanced" versions of the input A and B. π¦alphar,alphai,betaβ On exit, (alphar(j) + alphai(j)*i)/beta(j), j=1,...,N, will be the generalized eigenvalues. If alphai(j) is zero, then the j-th eigenvalue is real; if positive, then the j-th and (j+1)-st eigenvalues are a complex conjugate pair, with alphai(j+1) negative. πΈ
Note: the quotients alphar(j)/beta(j) and alphai(j)/beta(j) may easily over- or underflow, and beta(j) may even be zero. Thus, the user should avoid naively computing the ratio ALPHA/beta. However, alphar and alphai will be always less than and usually comparable with norm(A) in magnitude, and beta always less than and usually comparable with norm(B). π
vlβ If jobvl = 1, the left eigenvectors u(j) are stored one after another in the columns of vl, in the same order as their eigenvalues. If the j-th eigenvalue is real, then u(j) = vl(:,j), the j-th column of vl. If the j-th and (j+1)-th eigenvalues form a complex conjugate pair, then u(j) = vl(:,j)+i*vl(:,j+1) and u(j+1) = vl(:,j)-i*vl(:,j+1). Each eigenvector will be scaled so the largest component have abs(real part) + abs(imag. part) = 1. Not referenced if jobvl = 0. πvrβ If jobvr = 1, the right eigenvectors v(j) are stored one after another in the columns of vr, in the same order as their eigenvalues. If the j-th eigenvalue is real, then v(j) = vr(:,j), the j-th column of vr. If the j-th and (j+1)-th eigenvalues form a complex conjugate pair, then v(j) = vr(:,j)+i*vr(:,j+1) and v(j+1) = vr(:,j)-i*vr(:,j+1). Each eigenvector will be scaled so the largest component have abs(real part) + abs(imag. part) = 1. Not referenced if jobvr = 0. πilo,ihiβ ilo and ihi are integer values such that on exit A(i,j) = 0 and B(i,j) = 0 if i > j and j = 1,...,ilo-1 or i = ihi+1,...,N. If balanc = 0 or 2, ilo = 1 and ihi = N. πlscaleβ Details of the permutations and scaling factors applied to the left side of A and B. If PL(j) is the index of the row interchanged with row j, and DL(j) is the scaling factor applied to row j, then
lscale(j) = PL(j) for j = 1,...,ilo-1
= DL(j) for j = ilo,...,ihi
= PL(j) for j = ihi+1,...,N.
The order in which the interchanges are made is N to ihi+1, then 1 to ilo-1. π
rscaleβ Details of the permutations and scaling factors applied to the right side of A and B. If PR(j) is the index of the column interchanged with column j, and DR(j) is the scaling factor applied to column j, then
rscale(j) = PR(j) for j = 1,...,ilo-1
= DR(j) for j = ilo,...,ihi
= PR(j) for j = ihi+1,...,N
The order in which the interchanges are made is N to ihi+1, then 1 to ilo-1. β¨
abnrmβ The one-norm of the balanced matrix A. πbbnrmβ The one-norm of the balanced matrix B. π§rcondeβ If sense = 1 or 3, the reciprocal condition numbers of the selected eigenvalues, stored in consecutive elements of the array. For a complex conjugate pair of eigenvalues two consecutive elements of rconde are set to the same value. Thus rconde(j), rcondv(j), and the j-th columns of vl and vr all correspond to the same eigenpair (but not in general the j-th eigenpair, unless all eigenpairs are selected). If sense = 2, rconde is not referenced. πrcondvβ If sense = 2 or 3, the estimated reciprocal condition numbers of the selected eigenvectors, stored in consecutive elements of the array. For a complex eigenvector two consecutive elements of rcondv are set to the same value. If the eigenvalues cannot be reordered to compute rcondv(j), rcondv(j) is set to 0; this can only occur when the true value would be very small anyway. If sense = 1, rcondv is not referenced. π«Άinfoβ
= 0: successful exit
< 0: if info = -i, the i-th argument had an illegal value.
= 1,...,N:
The QZ iteration failed. No eigenvectors have been
calculated, but alphar(j), alphai(j), and beta(j)
should be correct for j=info+1,...,N.
> N: =N+1: other than QZ iteration failed in hgeqz.
=N+2: error return from tgevc.
Okay now the example, no cap:
$a = random(5,5);
$b = random(5,5);
$alphar = zeroes(5);
$alphai = zeroes(5);
$beta = zeroes(5);
$vl = zeroes(5,5);
$vr = zeroes(5,5);
$lscale = zeroes(5);
$rscale = zeroes(5);
$ilo = null;
$ihi = null;
$abnrm = null;
$bbnrm = null;
$rconde = zeroes(5);
$rcondv = zeroes(5);
ggevx($a, 3, 1, 1, 3, $b, $alphar, $alphai, $beta, $vl, $vr,
$ilo, $ihi, $lscale, $rscale, $abnrm, $bbnrm, $rconde,$rcondv,($info=null));
ggevx ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π
gees
Signature: ([io]A(n,n); int jobvs(); int sort(); [o]wr(n); [o]wi(n); [o]vs(p,p); int [o]sdim(); int [o]info(); int [t]bwork(bworkn); SV* select_func)
Computes for an N-by-N real nonsymmetric matrix A, the eigenvalues, the real Schur form T, and, optionally, the matrix of Schur vectors Z. This gives the Schur factorization A = Z*T*Z'. π₯
Optionally, it also orders the eigenvalues on the diagonal of the real Schur form so that selected eigenvalues are at the top left. The leading columns of Z then form an orthonormal basis for the invariant subspace corresponding to the selected eigenvalues. π
A matrix is in real Schur form if it is upper quasi-triangular with 1-by-1 and 2-by-2 blocks. 2-by-2 blocks will be standardized in the form
[ a b ]
[ c a ]
where b*c < 0.
The eigenvalues of such a block are a +- sqrt(bc). πΈ
Arguments
jobvsβ = 0: Schur vectors are not computed; = 1: Schur vectors are computed. β¨sortβ Specifies whether or not to order the eigenvalues on the diagonal of the Schur form. = 0: Eigenvalues are not ordered; = 1: Eigenvalues are ordered (see select_func). πselect_funcβ If sort = 1, select_func is used to select eigenvalues to sort to the top left of the Schur form. If sort = 0, select_func is not referenced. An eigenvalue wr(j)+sqrt(-1)*wi(j) is selected if select_func(SCALAR(wr(j)), SCALAR(wi(j))) is true; i.e., if either one of a complex conjugate pair of eigenvalues is selected, then both complex eigenvalues are selected. Note that a selected complex eigenvalue may no longer satisfy select_func(wr(j),wi(j)) = 1 after ordering, since ordering may change the value of complex eigenvalues (especially if the eigenvalue is ill-conditioned); in this case info is set to N+2 (see info below). π¦Aβ The N-by-N matrix A. On exit, A has been overwritten by its real Schur form T. πsdimβ If sort = 0, sdim = 0. If sort = 1, sdim = number of eigenvalues (after sorting) for which select_func is true. (Complex conjugate pairs for which select_func is true for either eigenvalue count as 2.) πwr,wiβ wr and wi contain the real and imaginary parts, respectively, of the computed eigenvalues in the same order that they appear on the diagonal of the output Schur form T. Complex conjugate pairs of eigenvalues will appear consecutively with the eigenvalue having the positive imaginary part first. πvsβ If jobvs = 1, vs contains the orthogonal matrix Z of Schur vectors else vs is not referenced. βinfoβ
= 0: successful exit
< 0: if info = -i, the i-th argument had an illegal value.
> 0: if info = i, and i is
<= N: the QR algorithm failed to compute all the
eigenvalues; elements 1:ILO-1 and i+1:N of wr and wi
contain those eigenvalues which have converged; if
jobvs = 1, vs contains the matrix which reduces A
to its partially converged Schur form.
= N+1: the eigenvalues could not be reordered because some
eigenvalues were too close to separate (the problem
is very ill-conditioned);
= N+2: after reordering, roundoff changed values of some
complex eigenvalues so that leading eigenvalues in
the Schur form no longer satisfy select_func = 1 This
could also be caused by underflow due to scaling.
Example time, bestie:
sub select_function{
my ($a, $b ) = @_;
# Stable "continuous time" eigenspace
return $a < 0 ? 1 : 0;
}
$A = random (5,5);
$wr= zeroes(5);
$wi = zeroes(5);
$vs = zeroes(5,5);
$sdim = null;
$info = null;
gees($A, 1,1, $wr, $wi, $vs, $sdim, $info,\&select_function);
gees ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π
π geesx π
Signature: ([io]A(n,n); int jobvs(); int sort(); int sense(); [o]wr(n); [o]wi(n); [o]vs(p,p); int [o]sdim(); [o]rconde();[o]rcondv(); int [o]info(); int [t]bwork(bworkn); SV* select_func)
okay bestie, geesx is the full-glam version of the Schur decomposition. For an N-by-N real nonsymmetric matrix A, it computes the eigenvalues, the real Schur form T, and β if you want it β the matrix of Schur vectors Z. That's the Schur factorization:
A = Z*T*Z'
and optionally it also orders the eigenvalues along the diagonal of the real Schur form so your selected ones get yeeted to the top left. On top of that it can compute a reciprocal condition number for the average of the selected eigenvalues (rconde) π
and a reciprocal condition number for the right invariant subspace that goes with those selected eigenvalues (rcondv). The leading columns of Z form an orthonormal basis for that invariant subspace. main character basis energy fr.
For the deeper lore on the reciprocal condition numbers rconde and rcondv, go look at Section 4.10 of the LAPACK Users' Guide β that's where these quantities are called s and sep respectively.
A real matrix is in real Schur form if it's upper quasi-triangular with 1-by-1 and 2-by-2 blocks. The 2-by-2 blocks get standardized into the form
[ a b ]
[ c a ]
where b*c < 0. The eigenvalues of such a block are a +- sqrt(bc). math but make it fashion. β¨
Arguments
jobvsβ decides if you're getting Schur vectors at all:= 0: Schur vectors are not computed;= 1: Schur vectors are computed. π
sortβ whether or not to order the eigenvalues on the diagonal of the Schur form:= 0: Eigenvalues are not ordered;= 1: Eigenvalues are ordered (seeselect_func).
select_funcβ ifsort = 1, this is what picks which eigenvalues get sorted to the top left of the Schur form; otherwiseselect_funcis not referenced. An eigenvaluewr(j)+sqrt(-1)*wi(j)is selected ifselect_func(wr(j),wi(j))is true β i.e., if either one of a complex conjugate pair of eigenvalues is selected, then both are. Heads up though: a selected complex eigenvalue may no longer satisfyselect_func(wr(j),wi(j)) = 1after ordering, since ordering may change the value of complex eigenvalues (especially if the eigenvalue is ill-conditioned); in that caseinfomay be set toN+3(seeinfobelow). no cap, that's a real thing that can happen.senseβ which reciprocal condition numbers get computed:= 0: None are computed;= 1: Computed for average of selected eigenvalues only;= 2: Computed for selected right invariant subspace only;= 3: Computed for both.
If sense = 1, 2 or 3, sort must equal 1. π«Ά
Aβ on entry, the N-by-N matrix A. On exit, A is overwritten by its real Schur form T. bye original A, you were cute.sdimβ ifsort = 0,sdim = 0. Ifsort = 1,sdim = number of eigenvalues (after sorting) for which select_func is 1. (Complex conjugate pairs for whichselect_funcis 1 for either eigenvalue count as 2.)wr,wiβ these two hold the real and imaginary parts, respectively, of the computed eigenvalues, in the same order that they appear on the diagonal of the output Schur form T. Complex conjugate pairs of eigenvalues appear consecutively with the eigenvalue having the positive imaginary part first. π«vsβ ifjobvs = 1,vscontains the orthogonal matrix Z of Schur vectors; elsevsis not referenced.rcondeβ ifsense = 1or3,rcondecontains the reciprocal condition number for the average of the selected eigenvalues. Not referenced ifsense = 0or2.rcondvβ ifsense = 2or3,rcondvcontains the reciprocal condition number for the selected right invariant subspace. Not referenced ifsense = 0or1.infoβ the receipts π:= 0: successful exit< 0: ifinfo = -i, the i-th argument had an illegal value.> 0: ifinfo = i, and i is<= N: the QR algorithm failed to compute all the eigenvalues; elements1:ilo-1andi+1:Nofwrandwicontain those eigenvalues which have converged; ifjobvs = 1,vscontains the transformation which reduces A to its partially converged Schur form.= N+1: the eigenvalues could not be reordered because some eigenvalues were too close to separate (the problem is very ill-conditioned);= N+2: after reordering, roundoff changed values of some complex eigenvalues so that leading eigenvalues in the Schur form no longer satisfyselect_func=1. This could also be caused by underflow due to scaling.
ok so here's the vibe in Perl, bestie:
sub select_function{
my ($a, $b) = @_;
# Stable "discrete time" eigenspace
return sqrt($a**2 + $b**2) < 1 ? 1 : 0;
}
$A = random (5,5);
$wr= zeroes(5);
$wi = zeroes(5);
$vs = zeroes(5,5);
$sdim = null;
$rconde = null;
$rcondv = null;
$info = null;
geesx($A, 1,1, 3, $wr, $wi, $vs, $sdim, $rconde, $rcondv, $info, \&select_function);
geesx ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. it's giving considerate, honestly.
π¦ gges π¦
Signature: ([io]A(n,n); int jobvsl();int jobvsr();int sort();[io]B(n,n);[o]alphar(n);[o]alphai(n);[o]beta(n);[o]VSL(m,m);[o]VSR(p,p);int [o]sdim();int [o]info(); int [t]bwork(bworkn); SV* select_func)
For a pair of N-by-N real nonsymmetric matrices (A,B), gges computes the generalized eigenvalues, the generalized real Schur form (S,T), and optionally the left and/or right matrices of Schur vectors (VSL and VSR). Which gives you the generalized Schur factorization:
(A,B) = ( (VSL)*S*(VSR)', (VSL)*T*(VSR)' )
Optionally it also orders the eigenvalues so that a selected cluster of eigenvalues appears in the leading diagonal blocks of the upper quasi-triangular matrix S and the upper triangular matrix T. The leading columns of VSL and VSR then form an orthonormal basis for the corresponding left and right eigenspaces (deflating subspaces). iconic behavior. π
(If you only need the generalized eigenvalues, use the driver ggev instead β it's faster. ngl, know your options.)
A generalized eigenvalue for a pair of matrices (A,B) is a scalar w or a ratio alpha/beta = w, such that A - w*B is singular. It's usually represented as the pair (alpha,beta), because there's a reasonable interpretation for beta=0 or both being zero.
A pair of matrices (S,T) is in generalized real Schur form if T is upper triangular with non-negative diagonal and S is block upper triangular with 1-by-1 and 2-by-2 blocks. The 1-by-1 blocks correspond to real generalized eigenvalues, while 2-by-2 blocks of S will be "standardized" by making the corresponding elements of T have the form:
[ a 0 ]
[ 0 b ]
and the pair of corresponding 2-by-2 blocks in S and T will have a complex conjugate pair of generalized eigenvalues. π«
Arguments
jobvslβ= 0: do not compute the left Schur vectors;= 1: compute the left Schur vectors.jobvsrβ= 0: do not compute the right Schur vectors;= 1: compute the right Schur vectors.sortβ whether or not to order the eigenvalues on the diagonal of the generalized Schur form:= 0: Eigenvalues are not ordered;= 1: Eigenvalues are ordered (seedelztg).
delztgβ ifsort = 0,delztgis not referenced. Ifsort = 1,delztgis used to select eigenvalues to sort to the top left of the Schur form. An eigenvalue(alphar(j)+alphai(j))/beta(j)is selected ifdelztg(alphar(j),alphai(j),beta(j))is true; i.e. if either one of a complex conjugate pair of eigenvalues is selected, then both complex eigenvalues are selected.
Note that in the ill-conditioned case, a selected complex eigenvalue may no longer satisfy delztg(alphar(j),alphai(j), beta(j)) = 1 after ordering. info is to be set to N+2 in this case. yes, that's a whole warning, take it seriously.
Aβ on entry, the first of the pair of matrices. On exit, A has been overwritten by its generalized Schur form S.Bβ on entry, the second of the pair of matrices. On exit, B has been overwritten by its generalized Schur form T.sdimβ ifsort = 0,sdim = 0. Ifsort = 1,sdim = number of eigenvalues (after sorting) for which delztg is true. (Complex conjugate pairs for whichdelztgis true for either eigenvalue count as 2.)alphar,alphai,betaβ on exit,(alphar(j) + alphai(j)*i)/beta(j),j=1,...,N, will be the generalized eigenvalues.alphar(j) + alphai(j)*i, andbeta(j),j=1,...,Nare the diagonals of the complex Schur form (S,T) that would result if the 2-by-2 diagonal blocks of the real Schur form of (A,B) were further reduced to triangular form using 2-by-2 complex unitary transformations. Ifalphai(j)is zero, then the j-th eigenvalue is real; if positive, then the j-th and (j+1)-st eigenvalues are a complex conjugate pair, withalphai(j+1)negative. π
Note: the quotientsalphar(j)/beta(j)andalphai(j)/beta(j)may easily over- or underflow, andbeta(j)may even be zero. Thus, the user should avoid naively computing the ratio. However,alpharandalphaiwill be always less than and usually comparable withnorm(A)in magnitude, andbetaalways less than and usually comparable withnorm(B). don't do the naive thing bestie, I'm begging.
VSLβ ifjobvsl = 1,VSLwill contain the left Schur vectors. Not referenced ifjobvsl = 0. The leading dimension must always be>=1.VSRβ ifjobvsr = 1,VSRwill contain the right Schur vectors. Not referenced ifjobvsr = 0. The leading dimension must always be>=1.infoβ the vibe check on how it went:= 0: slayed, successful exit β¨< 0: ifinfo = -i, the i-th argument had an illegal value (one of your inputs was giving nothing but red flags π©)= 1,...,N: the QZ iteration failed.(A,B)are not in Schur form, butalphar(j),alphai(j), andbeta(j)should still be correct forj=info+1,...,N. π> N:=N+1: something other than QZ iteration failed inhgeqz.=N+2: after reordering, roundoff changed values of some complex eigenvalues so that leading eigenvalues in the Generalized Schur form no longer satisfydelztg=1. This could also be caused due to scaling. π=N+3: reordering failed intgsen.
sub my_select{
my ($zr, $zi, $d) = @_;
# stable generalized eigenvalues for continuous time
return ( ($zr < 0 && $d > 0 ) || ($zr > 0 && $d < 0) ) ? 1 : 0;
}
$a = random(5,5);
$b = random(5,5);
$sdim = null;
$alphar = zeroes(5);
$alphai = zeroes(5);
$beta = zeroes(5);
$vsl = zeroes(5,5);
$vsr = zeroes(5,5);
gges($a, 1, 1, 1, $b, $alphar, $alphai, $beta, $vsl, $vsr, $sdim,($info=null), \&my_select);
gges ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. bestie it just does not care about your bad values, periodt.
π¦ ggesx π¦
Signature:
([io]A(n,n); int jobvsl();int jobvsr();int sort();int sense();[io]B(n,n);[o]alphar(n);[o]alphai(n);[o]beta(n);[o]VSL(m,m);[o]VSR(p,p);int [o]sdim();[o]rconde(q=2);[o]rcondv(q=2);int [o]info(); int [t]bwork(bworkn); int [t]iwork(iworkn); SV* select_func)
okay so this one computes, for a pair of N-by-N real nonsymmetric matrices (A,B), the generalized eigenvalues, the real Schur form (S,T), and, optionally, the left and/or right matrices of Schur vectors (VSL and VSR). That gives you the generalized Schur factorization:
(A,B) = ( (VSL) S (VSR)', (VSL) T (VSR)' )
Optionally, it also orders the eigenvalues so that a selected cluster of eigenvalues appears in the leading diagonal blocks of the upper quasi-triangular matrix S and the upper triangular matrix T; computes a reciprocal condition number for the average of the selected eigenvalues (RCONDE); and computes a reciprocal condition number for the right and left deflating subspaces corresponding to the selected eigenvalues (RCONDV). The leading columns of VSL and VSR then form an orthonormal basis for the corresponding left and right eigenspaces (deflating subspaces). iconic behavior honestly.
A generalized eigenvalue for a pair of matrices (A,B) is a scalar w or a ratio alpha/beta = w, such that A - w*B is singular. It is usually represented as the pair (alpha,beta), as there is a reasonable interpretation for beta=0 or for both being zero.
A pair of matrices (S,T) is in generalized real Schur form if T is upper triangular with non-negative diagonal and S is block upper triangular with 1-by-1 and 2-by-2 blocks. The 1-by-1 blocks correspond to real generalized eigenvalues, while 2-by-2 blocks of S will be "standardized" by making the corresponding elements of T have the form:
[ a 0 ]
[ 0 b ]
and the pair of corresponding 2-by-2 blocks in S and T will have a complex conjugate pair of generalized eigenvalues. it's giving structured, it's giving β¨organizedβ¨.
Further details
An approximate (asymptotic) bound on the average absolute error of the selected eigenvalues is
EPS * norm((A, B)) / RCONDE( 1 ).
An approximate (asymptotic) bound on the maximum angular error in the computed deflating subspaces is
EPS * norm((A, B)) / RCONDV( 2 ).
See LAPACK User's Guide, section 4.11 for more information.
Arguments
jobvslβ= 0: do not compute the left Schur vectors;= 1: compute the left Schur vectors.jobvsrβ= 0: do not compute the right Schur vectors;= 1: compute the right Schur vectors.sortβ specifies whether or not to order the eigenvalues on the diagonal of the generalized Schur form.= 0: eigenvalues are not ordered;= 1: eigenvalues are ordered (seedelztg).delztgβ ifsort = 0,delztgis not referenced. Ifsort = 1,delztgis used to select eigenvalues to sort to the top left of the Schur form. An eigenvalue(alphar(j)+alphai(j))/beta(j)is selected ifdelztg(alphar(j),alphai(j),beta(j))is true; i.e. if either one of a complex conjugate pair of eigenvalues is selected, then both complex eigenvalues are selected. π Note that in the ill-conditioned case, a selected complex eigenvalue may no longer satisfydelztg(alphar(j),alphai(j),beta(j)) = 1after ordering.infois to be set toN+2in this case. (yeah, she's messy, that's just the deal)senseβ determines which reciprocal condition numbers are computed.= 0: none are computed;= 1: computed for average of selected eigenvalues only;= 2: computed for selected deflating subspaces only;= 3: computed for both. Ifsense = 1,2, or3,sortmust equal1.Aβ on entry, the first of the pair of matrices. On exit,Ahas been overwritten by its generalized Schur formS.Bβ on entry, the second of the pair of matrices. On exit,Bhas been overwritten by its generalized Schur formT.sdimβ ifsort = 0,sdim = 0. Ifsort = 1,sdim = number of eigenvalues (after sorting) for which delztg is true. (Complex conjugate pairs for whichdelztgis true for either eigenvalue count as 2.) πalphar,alphai,betaβ on exit,(alphar(j) + alphai(j)*i)/beta(j),j=1,...,N, will be the generalized eigenvalues.alphar(j) + alphai(j)*i, andbeta(j),j=1,...,Nare the diagonals of the complex Schur form(S,T)that would result if the 2-by-2 diagonal blocks of the real Schur form of(A,B)were further reduced to triangular form using 2-by-2 complex unitary transformations. Ifalphai(j)is zero, then the j-th eigenvalue is real; if positive, then the j-th and (j+1)-st eigenvalues are a complex conjugate pair, withalphai(j+1)negative.
Note: the quotientsalphar(j)/beta(j)andalphai(j)/beta(j)may easily over- or underflow, andbeta(j)may even be zero. Thus, the user should avoid naively computing the ratio. However,alpharandalphaiwill be always less than and usually comparable withnorm(A)in magnitude, andbetaalways less than and usually comparable withnorm(B). so likeβ¦ don't do the naive ratio thing bestie, i'm begging π
VSLβ ifjobvsl = 1,VSLwill contain the left Schur vectors. Not referenced ifjobvsl = 0. The leading dimension must always be>=1.VSRβ ifjobvsr = 1,VSRwill contain the right Schur vectors. Not referenced ifjobvsr = 0. The leading dimension must always be>=1.rcondeβ ifsense = 1or3,rconde(1)andrconde(2)contain the reciprocal condition numbers for the average of the selected eigenvalues. Not referenced ifsense = 0or2.rcondvβ ifsense = 2or3,rcondv(1)andrcondv(2)contain the reciprocal condition numbers for the selected deflating subspaces. Not referenced ifsense = 0or1.infoβ the receipts:= 0: successful exit β¨< 0: ifinfo = -i, the i-th argument had an illegal value.= 1,...,N: the QZ iteration failed.(A,B)are not in Schur form, butalphar(j),alphai(j), andbeta(j)should be correct forj=info+1,...,N.> N:=N+1: other than QZ iteration failed inhgeqz.=N+2: after reordering, roundoff changed values of some complex eigenvalues so that leading eigenvalues in the Generalized Schur form no longer satisfydelztg=1. This could also be caused due to scaling.=N+3: reordering failed intgsen.
sub my_select{
my ($zr, $zi, $d) = @_;
# Eigenvalue : (ZR/D) + sqrt(-1)*(ZI/D)
# stable generalized eigenvalues for discrete time
return (sqrt($zr**2 + $zi**2) < abs($d) ) ? 1 : 0;
}
$a = random(5,5);
$b = random(5,5);
$sdim = null;
$alphar = zeroes(5);
$alphai = zeroes(5);
$beta = zeroes(5);
$vsl = zeroes(5,5);
$vsr = zeroes(5,5);
$rconde = zeroes(2);
$rcondv = zeroes(2);
ggesx($a, 1, 1, 1, 3,$b, $alphar, $alphai, $beta, $vsl, $vsr, $sdim, $rconde, $rcondv, ($info=null), \&my_select);
ggesx ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. same energy, different function, no cap. π«Ά
πΈ syev πΈ
Signature:
([io,phys]A(n,n); int jobz(); int uplo(); [o,phys]w(n); int [o,phys]info())
Computes all eigenvalues and, optionally, eigenvectors of a real symmetric matrix A. the full set, every single one, no crumbs left behind π
Arguments
jobzβ= 0: compute eigenvalues only;= 1: compute eigenvalues and eigenvectors.uploβ= 0: upper triangle ofAis stored;= 1: lower triangle ofAis stored.Aβ on entry, the symmetric matrixA. Ifuplo = 0, the leading N-by-N upper triangular part ofAcontains the upper triangular part of the matrixA. Ifuplo = 1, the leading N-by-N lower triangular part ofAcontains the lower triangular part of the matrixA. On exit, ifjobz = 1, then ifinfo = 0,Acontains the orthonormal eigenvectors of the matrixA. Ifjobz = 0, then on exit the lower triangle (ifuplo=1) or the upper triangle (ifuplo=0) ofA, including the diagonal, is destroyed. π gone, reduced to atoms, do not look for it.wβ ifinfo = 0, the eigenvalues in ascending order. sorted, cute, organized β¨infoβ= 0: successful exit;< 0: ifinfo = -i, the i-th argument had an illegal value;> 0: ifinfo = i, the algorithm failed to converge; i off-diagonal elements of an intermediate tridiagonal form did not converge to zero. π
# Assume $a is symmetric ;)
$a = random (5,5);
syev($a, 1,1, (my $w = zeroes(5)), (my $info=null));
syev ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π
π¦ syevd
Signature:
([io,phys]A(n,n); int jobz(); int uplo(); [o,phys]w(n); int [o,phys]info())
okay so bestie, this one computes all the eigenvalues β and, if you want them, the eigenvectors too β of a real symmetric matrix A. When eigenvectors are desired it goes with a divide and conquer algorithm. slay. π
Now that divide and conquer algorithm makes very mild assumptions about floating point arithmetic. It'll work on machines with a guard digit in add/subtract, or on those binary machines without guard digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or Cray-2. It could conceivably fail on hexadecimal or decimal machines without guard digits β but ngl, we know of none. π«Ά
And because it's out here using BLAS of level 3 like it's nothing, syevd needs N**2 more workspace than syevx. it's giving "more room, more power" β¨
π Arguments π
jobzβ= 0: compute eigenvalues only;= 1: compute eigenvalues and eigenvectors.uploβ= 0: upper triangle ofAis stored;= 1: lower triangle ofAis stored.Aβ on entry, the symmetric matrixA. Ifuplo = 0, the leading N-by-N upper triangular part ofAcontains the upper triangular part of the matrixA. Ifuplo = 1, the leading N-by-N lower triangular part ofAcontains the lower triangular part of the matrixA. On exit, ifjobz = 1, then ifinfo = 0,Acontains the orthonormal eigenvectors of the matrixA. Ifjobz = 0, then on exit the lower triangle (ifuplo=1) or the upper triangle (ifuplo=0) ofA, including the diagonal, is destroyed. πwβ ifinfo = 0, the eigenvalues in ascending order. πinfoβ= 0: successful exit;< 0: ifinfo = -i, the i-th argument had an illegal value;> 0: ifinfo = i, the algorithm failed to converge;ioff-diagonal elements of an intermediate tridiagonal form did not converge to zero.
Example time:
# Assume $a is symmetric ;)
$a = random (5,5);
syevd($a, 1,1, (my $w = zeroes(5)), (my $info=null));
syevd ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
πΈ syevx
Signature:
(A(n,n); int jobz(); int range(); int uplo(); vl(); vu(); int il(); int iu(); abstol(); int [o]m(); [o]w(n); [o]z(p,p);int [o]ifail(n); int [o]info(); int [t]iwork(iworkn))
so this one computes selected eigenvalues and, optionally, eigenvectors of a real symmetric matrix A. and the selection? iconic behaviour, honestly β you can pick either a range of values or a range of indices for the eigenvalues you want. choosing your own destiny fr fr π
π Arguments π
jobzβ= 0: compute eigenvalues only;= 1: compute eigenvalues and eigenvectors.rangeβ= 0: all eigenvalues will be found;= 1: all eigenvalues in the half-open interval(vl,vu]will be found;= 1: theil-th throughiu-th eigenvalues will be found. (and yes, the page really does say= 1for both of those β i'm just the messenger π)uploβ= 0: upper triangle ofAis stored;= 1: lower triangle ofAis stored.Aβ on entry, the symmetric matrixA. Ifuplo = 0, the leading N-by-N upper triangular part ofAcontains the upper triangular part of the matrixA. Ifuplo = 1, the leading N-by-N lower triangular part ofAcontains the lower triangular part of the matrixA. On exit, the lower triangle (ifuplo=1) or the upper triangle (ifuplo=0) ofA, including the diagonal, is destroyed. πvl,vuβ ifrange=1, the lower and upper bounds of the interval to be searched for eigenvalues.vl < vu. Not referenced ifrange = 0or2.il,iuβ ifrange=2, the indices (in ascending order) of the smallest and largest eigenvalues to be returned.1 <= il <= iu <= N, ifN > 0;il = 1andiu = 0ifN = 0. Not referenced ifrange = 0or1.abstolβ the absolute error tolerance for the eigenvalues. An approximate eigenvalue is accepted as converged when it is determined to lie in an interval[a,b]of width less than or equal to
abstol + EPS * max( |a|,|b| ) ,
where EPS is the machine precision. If abstol is less than or equal to zero, then EPS*|T| will be used in its place, where |T| is the 1-norm of the tridiagonal matrix obtained by reducing A to tridiagonal form. Eigenvalues will be computed most accurately when abstol is set to twice the underflow threshold 2*lamch(1), not zero. If this routine returns with info>0, indicating that some eigenvectors did not converge, try setting abstol to 2*lamch(1). See "Computing Small Singular Values of Bidiagonal Matrices with Guaranteed High Relative Accuracy," by Demmel and Kahan, LAPACK Working Note #3.
mβ the total number of eigenvalues found.0 <= m <= N. Ifrange = 0,m = N, and ifrange = 2,m = iu-il+1.wβ on normal exit, the firstMelements contain the selected eigenvalues in ascending order.zβ ifjobz = 1, then ifinfo = 0, the firstmcolumns ofzcontain the orthonormal eigenvectors of the matrixAcorresponding to the selected eigenvalues, with the i-th column ofzholding the eigenvector associated withw(i). If an eigenvector fails to converge, then that column ofzcontains the latest approximation to the eigenvector, and the index of the eigenvector is returned inifail. Ifjobz = 0, thenzis not referenced.
Note: the user must ensure that at leastmax(1,m)columns are supplied in the arrayz; ifrange = 1, the exact value ofmis not known in advance and an upper bound must be used. no cap, plan ahead bestie π«Ά
ifailβ ifjobz = 1, then ifinfo = 0, the firstmelements ofifailare zero. Ifinfo > 0, thenifailcontains the indices of the eigenvectors that failed to converge. Ifjobz = 0, thenifailis not referenced.infoβ= 0: successful exit;< 0: ifinfo = -i, the i-th argument had an illegal value;> 0: ifinfo = i, thenieigenvectors failed to converge. Their indices are stored in arrayifail.
Example, look at this whole setup:
# Assume $a is symmetric ;)
$a = random (5,5);
$unfl = lamch(1);
$ovfl = lamch(9);
labad($unfl, $ovfl);
$abstol = $unfl + $unfl;
$m = null;
$info = null;
$ifail = zeroes(5);
$w = zeroes(5);
$z = zeroes(5,5);
syevx($a, 1,0,1,0,0,0,0,$abstol, $m, $w, $z ,$ifail, $info);
syevx ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
π§ syevr
Signature:
([phys]A(n,n); int jobz(); int range(); int uplo(); [phys]vl(); [phys]vu(); int [phys]il(); int [phys]iu();[phys]abstol();int [o,phys]m();[o,phys]w(n); [o,phys]z(p,q);int [o,phys]isuppz(r); int [o,phys]info())
okay this one computes selected eigenvalues and, optionally, eigenvectors of a real symmetric matrix T. And again, you get to choose β either a range of values or a range of indices for the eigenvalues you're chasing. π
Whenever it can, syevr calls stegr to compute the eigenspectrum using Relatively Robust Representations. stegr computes eigenvalues by the dqds algorithm, while orthogonal eigenvectors are computed from various "good" L D L^T representations (also known as Relatively Robust Representations). Gram-Schmidt orthogonalization is avoided as far as possible. More specifically, the various steps of the algorithm are as follows. For the i-th unreduced block of T:
(a) Compute T - sigma_i = L_i D_i L_i^T, such that L_i D_i L_i^T
is a relatively robust representation,
(b) Compute the eigenvalues, lambda_j, of L_i D_i L_i^T to high
relative accuracy by the dqds algorithm,
(c) If there is a cluster of close eigenvalues, "choose" sigma_i
close to the cluster, and go to step (a),
(d) Given the approximate eigenvalue lambda_j of L_i D_i L_i^T,
compute the corresponding eigenvector by forming a
rank-revealing twisted factorization.
The desired accuracy of the output can be specified by the input parameter abstol.
For more details, see "A new O(n^2) algorithm for the symmetric tridiagonal eigenvalue/eigenvector problem", by Inderjit Dhillon, Computer Science Division Technical Report No. UCB//CSD-97-971, UC Berkeley, May 1997. π
Note 1:syevrcallsstegrwhen the full spectrum is requested on machines which conform to the ieee-754 floating point standard.syevrcallsstebzandsteinon non-ieee machines and when partial spectrum requests are made.
Normal execution of stegr may create NaNs and infinities and hence may abort due to a floating point exception in environments which do not handle NaNs and infinities in the ieee standard default manner. β οΈ like, be aware bestie.
β Arguments β
jobzβ= 0: compute eigenvalues only;= 1: compute eigenvalues and eigenvectors.rangeβ= 0: all eigenvalues will be found;= 1: all eigenvalues in the half-open interval(vl,vu]will be found;= 2: theil-th throughiu-th eigenvalues will be found.
********* For range = 1 or 2 and iu - il < N - 1, stebz and********* stein are called
uploβ= 0: upper triangle ofAis stored;= 1: lower triangle ofAis stored.Aβ on entry, the symmetric matrixA. Ifuplo = 0, the leading N-by-N upper triangular part ofAcontains the upper triangular part of the matrixA. Ifuplo = 1, the leading N-by-N lower triangular part ofAcontains the lower triangular part of the matrixA. On exit, the lower triangle (ifuplo=1) or the upper triangle (ifuplo=0) ofA, including the diagonal, is destroyed. πvl,vuβ ifrange=1, the lower and upper bounds of the interval to be searched for eigenvalues.vl < vu. Not referenced ifrange = 0or2.il,iuβ ifrange=2, the indices (in ascending order) of the smallest and largest eigenvalues to be returned.1 <= il <= iu <= N, ifN > 0;il = 1andiu = 0ifN = 0. Not referenced ifrange = 0or1.abstolβ the absolute error tolerance for the eigenvalues</p>, okay bestie? An approximate eigenvalue gets accepted as converged when it's determined to lie in an interval[a,b]of width less than or equal to
abstol + EPS * max( |a|,|b| ) ,
where EPS is the machine precision. If abstol is less than or equal to zero, then EPS*|T| will be used in its place, where |T| is the 1-norm of the tridiagonal matrix obtained by reducing A to tridiagonal form. π«Ά
See "Computing Small Singular Values of Bidiagonal Matrices with Guaranteed High Relative Accuracy," by Demmel and Kahan, LAPACK Working Note #3.
If high relative accuracy is important, set abstol to lamch(1). Doing so will guarantee that eigenvalues are computed to high relative accuracy when possible in future releases. The current code does not make any guarantees about high relative accuracy, but future releases will. See J. Barlow and J. Demmel, "Computing Accurate Eigensystems of Scaled Diagonally Dominant Matrices", LAPACK Working Note #7, for a discussion of which matrices define their eigenvalues to high relative accuracy.
mβ the total number of eigenvalues found.0 <= m <= N. Ifrange = 0, thenm = N, and ifrange = 2, thenm = iu-il+1. β¨wβ the firstmelements contain the selected eigenvalues in ascending order. sorted, we love to see it πzβ ifjobz = 1, then ifinfo = 0, the firstmcolumns ofzcontain the orthonormal eigenvectors of the matrixAcorresponding to the selected eigenvalues, with thei-th column ofzholding the eigenvector associated withw(i). Ifjobz = 0, thenzis not referenced. Note: the user must ensure that at leastmax(1,m)columns are supplied in the arrayz; ifrange = 1, the exact value ofmis not known in advance and an upper bound must be used. πisuppzβ array of int, dimension( 2*max(1,m) ). The support of the eigenvectors inz, i.e., the indices indicating the nonzero elements inz. Thei-th eigenvector is nonzero only in elementsisuppz( 2*i-1 )throughisuppz( 2*i ). πΈ
********* Implemented only for range = 0 or 2 and iu - il = N - 1
infoβ= 0: successful exit π< 0: ifinfo = -i, thei-th argument had an illegal value π> 0: Internal error
okay now the lil demo, and bestie you know I love a demo:
# Assume $a is symmetric ;)
$a = random (5,5);
$unfl = lamch(1);
$ovfl = lamch(9);
labad($unfl, $ovfl);
$abstol = $unfl + $unfl;
$m = null;
$info = null;
$isuppz = zeroes(10);
$w = zeroes(5);
$z = zeroes(5,5);
syevr($a, 1,0,1,0,0,0,0,$abstol, $m, $w, $z ,$isuppz, $info);
syevr ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. no cap β¨
π¦ sygv π¦
Signature: ([io,phys]A(n,n);int [phys]itype();int jobz(); int uplo();[io,phys]B(n,n);[o,phys]w(n); int [o,phys]info())
Computes all the eigenvalues, and optionally, the eigenvectors of a real generalized symmetric-definite eigenproblem, of the form A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A and B are assumed to be symmetric and B is also positive definite. π«Ά
Arguments
itypeβ specifies the problem type to be solved:= 1:A*x = (lambda)*B*x= 2:A*B*x = (lambda)*x= 3:B*A*x = (lambda)*x
jobzβ= 0: compute eigenvalues only;= 1: compute eigenvalues and eigenvectors.
uploβ= 0: upper triangles ofAandBare stored;= 1: lower triangles ofAandBare stored.
Aβ on entry, the symmetric matrixA. Ifuplo = 0, the leading N-by-N upper triangular part ofAcontains the upper triangular part of the matrixA. Ifuplo = 1, the leading N-by-N lower triangular part ofAcontains the lower triangular part of the matrixA.
On exit, if jobz = 1, then if info = 0, A contains the matrix Z of eigenvectors. The eigenvectors are normalized as follows:
- if
itype = 1or2,Z'*B*Z = I; - if
itype = 3,Z'*inv(B)*Z = I.
If jobz = 0, then on exit the upper triangle (if uplo=0) or the lower triangle (if uplo=1) of A, including the diagonal, is destroyed. π she's gone, bestie, don't look back
Bβ on entry, the symmetric positive definite matrixB. Ifuplo = 0, the leading N-by-N upper triangular part ofBcontains the upper triangular part of the matrixB. Ifuplo = 1, the leading N-by-N lower triangular part ofBcontains the lower triangular part of the matrixB.
On exit, if info <= N, the part of B containing the matrix is overwritten by the triangular factor U or L from the Cholesky factorization B = U'*U or B = L*L'. π
Wβ ifinfo = 0, the eigenvalues in ascending order. β¨infoβ= 0: successful exit π< 0: ifinfo = -i, thei-th argument had an illegal value> 0:potrforsyevreturned an error code:<= N: ifinfo = i,syevfailed to converge;ioff-diagonal elements of an intermediate tridiagonal form did not converge to zero;> N: ifinfo = N + i, for1 <= i <= N, then the leading minor of orderiofBis not positive definite. The factorization ofBcould not be completed and no eigenvalues or eigenvectors were computed. π
demo time, lowkey iconic:
# Assume $a is symmetric ;)
$a = random (5,5);
# Assume $a is symmetric and positive definite ;)
$b = random (5,5);
sygv($a, 1,1, 0, $b, (my $w = zeroes(5)), (my $info=null));
sygv ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. fr fr π
πΈ sygvd πΈ
Signature: ([io,phys]A(n,n);int [phys]itype();int jobz(); int uplo();[io,phys]B(n,n);[o,phys]w(n); int [o,phys]info())
Computes all the eigenvalues, and optionally, the eigenvectors of a real generalized symmetric-definite eigenproblem, of the form A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A and B are assumed to be symmetric and B is also positive definite. π«Ά
The divide and conquer algorithm makes very mild assumptions about floating point arithmetic. It will work on machines with a guard digit in add/subtract, or on those binary machines without guard digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or Cray-2. It could conceivably fail on hexadecimal or decimal machines without guard digits, but we know of none. π§
Arguments
itypeβ specifies the problem type to be solved:= 1:A*x = (lambda)*B*x= 2:A*B*x = (lambda)*x= 3:B*A*x = (lambda)*x
jobzβ= 0: compute eigenvalues only;= 1: compute eigenvalues and eigenvectors.
uploβ= 0: upper triangles ofAandBare stored;= 1: lower triangles ofAandBare stored.
Aβ on entry, the symmetric matrixA. Ifuplo = 0, the leading N-by-N upper triangular part ofAcontains the upper triangular part of the matrixA. Ifuplo = 1, the leading N-by-N lower triangular part ofAcontains the lower triangular part of the matrixA.
On exit, if jobz = 1, then if info = 0, A contains the matrix Z of eigenvectors. The eigenvectors are normalized as follows:
- if
itype = 1or2,Z'*B*Z = I; - if
itype = 3,Z'*inv(B)*Z = I.
If jobz = 0, then on exit the upper triangle (if uplo=0) or the lower triangle (if uplo=1) of A, including the diagonal, is destroyed. π
Bβ on entry, the symmetric positive definite matrixB. Ifuplo = 0, the leading N-by-N upper triangular part ofBcontains the upper triangular part of the matrixB. Ifuplo = 1, the leading N-by-N lower triangular part ofBcontains the lower triangular part of the matrixB.
On exit, if info <= N, the part of B containing the matrix is overwritten by the triangular factor U or L from the Cholesky factorization B = U'*U or B = L*L'. π
Wβ ifinfo = 0, the eigenvalues in ascending order. β¨infoβ= 0: successful exit π< 0: ifinfo = -i, thei-th argument had an illegal value> 0:potrforsyevreturned an error code:<= N: ifinfo = i,syevdfailed to converge;ioff-diagonal elements of an intermediate tridiagonal form did not converge to zero;> N: ifinfo = N + i, for1 <= i <= N, then the leading minor of orderiofBis not positive definite. The factorization ofBcould not be completed and no eigenvalues or eigenvectors were computed. π
and another demo, because we're thriving:
# Assume $a is symmetric ;)
$a = random (5,5);
# Assume $b is symmetric positive definite ;)
$b = random (5,5);
sygvd($a, 1,1, 0, $b, (my $w = zeroes(5)), (my $info=null));
sygvd ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. periodt π
π sygvx π
Signature: ([io]A(n,n); int itype(); int jobz(); int range();
int uplo(); [io]B(n,n); vl(); vu(); int il(); int iu(); abstol();
int [o]m(); [o]w(n); [o]Z(p,p); int [o]ifail(n); int [o]info();
int [t]iwork(iworkn);
)
Computes selected eigenvalues, and optionally, eigenvectors of a real generalized symmetric-definite eigenproblem, of the form A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A and B are assumed to be symmetric and B is also positive definite. Eigenvalues and eigenvectors can be selected by specifying either a range of values or a range of indices for the desired eigenvalues. π
Arguments
itypeβ specifies the problem type to be solved:= 1:A*x = (lambda)*B*x= 2:A*B*x = (lambda)*x= 3:B*A*x = (lambda)*x
jobzβ= 0: compute eigenvalues only;= 1: compute eigenvalues and eigenvectors.
rangeβ which eigenvalues we're even looking for, bestie:= 0: all eigenvalues will be found.= 1: all eigenvalues in the half-open interval(vl,vu]will be found.= 2: theil-th throughiu-th eigenvalues will be found.
uploβ where the tea is stored:= 0: Upper triangle ofAandBare stored;= 1: Lower triangle ofAandBare stored.
Aβ on entry, the symmetric matrixA. Ifuplo = 0, the leading N-by-N upper triangular part ofAcontains the upper triangular part of the matrixA. Ifuplo = 1, the leading N-by-N lower triangular part ofAcontains the lower triangular part of the matrixA.
On exit, the lower triangle (if uplo=1) or the upper triangle (if uplo=0) of A, including the diagonal, is destroyed. π yeah she's gone, that's just how it is.
Bβ on entry, the symmetric matrixB. Ifuplo = 0, the leading N-by-N upper triangular part ofBcontains the upper triangular part of the matrixB. Ifuplo = 1, the leading N-by-N lower triangular part ofBcontains the lower triangular part of the matrixB.
On exit, if info <= N, the part of B containing the matrix is overwritten by the triangular factor U or L from the Cholesky factorization B = U'*U or B = L*L'.
vl,vuβ ifrange=1, these are the lower and upper bounds of the interval to be searched for eigenvalues.vl < vu. Not referenced ifrange = 0or2. π―il,iuβ ifrange=2, the indices (in ascending order) of the smallest and largest eigenvalues to be returned.1 <= il <= iu <= N, ifN > 0;il = 1andiu = 0ifN = 0. Not referenced ifrange = 0or1.abstolβ the absolute error tolerance for the eigenvalues. An approximate eigenvalue is accepted as converged when it is determined to lie in an interval[a,b]of width less than or equal to
abstol + EPS * max( |a|,|b| ) ,
where EPS is the machine precision. If abstol is less than or equal to zero, then EPS*|T| will be used in its place, where |T| is the 1-norm of the tridiagonal matrix obtained by reducing A to tridiagonal form.
Eigenvalues will be computed most accurately when abstol is set to twice the underflow threshold 2*lamch(1), not zero. If this routine returns with info>0, indicating that some eigenvectors did not converge, try setting abstol to 2* lamch(1). (yes that space is real, copy it exactly pls π)
mβ the total number of eigenvalues found.0 <= m <= N. Ifrange = 0,m = N, and ifrange = 2,m = iu-il+1.wβ on normal exit, the firstmelements contain the selected eigenvalues in ascending order. slay, sorted. β¨Zβ ifjobz = 0, thenZis not referenced.
If jobz = 1, then if info = 0, the first m columns of Z contain the orthonormal eigenvectors of the matrix A corresponding to the selected eigenvalues, with the i-th column of Z holding the eigenvector associated with w(i). The eigenvectors are normalized as follows: if itype = 1 or 2, Z'*B*Z = I; if itype = 3, Z'*inv(B)*Z = I.
If an eigenvector fails to converge, then that column of Z contains the latest approximation to the eigenvector, and the index of the eigenvector is returned in ifail.
Note: the user must ensure that at leastmax(1,m)columns are supplied in the arrayZ; ifrange = 1, the exact value ofmis not known in advance and an upper bound must be used. no pressure or anything π
ifailβ ifjobz = 1, then ifinfo = 0, the firstMelements ofifailare zero. Ifinfo > 0, thenifailcontains the indices of the eigenvectors that failed to converge. Ifjobz = 0, thenifailis not referenced.infoβ the vibe report:= 0: successful exit π< 0: ifinfo = -i, thei-th argument had an illegal value> 0:potrforsyevxreturned an error code:<= N: ifinfo = i,syevxfailed to converge;ieigenvectors failed to converge. Their indices are stored in arrayifail.> N: ifinfo = N + i, for1 <= i <= N, then the leading minor of orderiofBis not positive definite. The factorization ofBcould not be completed and no eigenvalues or eigenvectors were computed. π
# Assume $a is symmetric ;)
$a = random (5,5);
# Assume $b is symmetric positive definite ;)
$b = random (5,5);
$unfl = lamch(1);
$ovfl = lamch(9);
labad($unfl, $ovfl);
$abstol = $unfl + $unfl;
$m = null;
$w=zeroes(5);
$z = zeroes(5,5);
$ifail = zeroes(5);
sygvx($a, 1,1, 0,0, $b, 0, 0, 0, 0, $abstol, $m, $w, $z,$ifail,(my $info=null));
sygvx ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
gesv π
Signature: [io,phys]A(n,n); [io,phys]B(n,m); int [o,phys]ipiv(n); int [o,phys]info()
Computes the solution to a real system of linear equations
A * X = B,
where A is an N-by-N matrix and X and B are N-by-NRHS matrices.
The LU decomposition with partial pivoting and row interchanges is used to factor A as
A = P * L * U,
where P is a permutation matrix, L is unit lower triangular, and U is
upper triangular.
The factored form of A is then used to solve the system of equations A * X = B. iconic behaviour tbh β¨
Arguments
Aβ on entry, the N-by-N coefficient matrixA. On exit, the factorsLandUfrom the factorizationA = P*L*U; the unit diagonal elements ofLare not stored.ipivβ the pivot indices that define the permutation matrixP; rowiof the matrix was interchanged with rowipiv(i).Bβ on entry, the N-by-NRHS matrix of right hand side matrixB. On exit, ifinfo = 0, the N-by-NRHS solution matrixX. π«Άinfoβ the receipts:= 0: successful exit< 0: ifinfo = -i, thei-th argument had an illegal value> 0: ifinfo = i,U(i,i)is exactly zero. The factorization has been completed, but the factorUis exactly singular, so the solution could not be computed. π
$a = random (5,5);
$a = transpose($a);
$b = random (5,5);
$b = transpose($b);
gesv($a,$b, (my $ipiv=zeroes(5)),(my $info=null));
print "The solution matrix X is :". transpose($b)."\n" unless $info;
gesv ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
gesvx π¦
Signature: [io]A(n,n); int trans(); int fact(); [io]B(n,m); [io]af(n,n); int [io]ipiv(n); int [io]equed(); [o]r(p); [o]c(q); [o]X(n,m); [o]rcond(); [o]ferr(m); [o]berr(m);[o]rpvgrw();int [o]info(); [t]work(workn); int [t]iwork(n)
Uses the LU factorization to compute the solution to a real system of linear equations
A * X = B,
where A is an N-by-N matrix and X and B are N-by-NRHS matrices.
Error bounds on the solution and a condition estimate are also provided. she does the most, and honestly? we love her for it. π
The following steps are performed:
- If
fact = 2, real scaling factors are computed to equilibrate the system:
trans = 0: diag(r)*A*diag(c) *inv(diag(c))*X = diag(c)*B
trans = 1: (diag(r)*A*diag(c))' *inv(diag(r))*X = diag(c)*B
trans = 2: (diag(r)*A*diag(c))**H *inv(diag(r))*X = diag(c)*B
Whether or not the system will be equilibrated depends on the scaling of the matrix A, but if equilibration is used, A is overwritten by diag(r)*A*diag(c) and B by diag(r)*B (if trans=0) or diag(c)*B (if trans = 1 or 2).
- If
fact = 1or2, the LU decomposition is used to factor the matrixA(after equilibration iffact = 2) as
A = P * L * U,
where P is a permutation matrix, L is a unit lower triangular
matrix, and U is upper triangular.
- If some
U(i,i)=0, so thatUis exactly singular, then the routine returns withinfo = i. Otherwise, the factored form ofAis used to estimate the condition number of the matrixA. If the reciprocal of the condition number is less than machine precision,info = N+1is returned as a warning, but the routine still goes on to solve forXand compute error bounds as described below. - The system of equations is solved for
Xusing the factored form ofA. - Iterative refinement is applied to improve the computed solution matrix and calculate error bounds and backward error estimates for it.
- If equilibration was used, the matrix
Xis premultiplied bydiag(c)(iftrans = 0) ordiag(r)(iftrans = 1or2) so that it solves the original system before equilibration. π
Arguments
factβ specifies whether or not the factored form of the matrixAis supplied on entry, and if not, whether the matrixAshould be equilibrated before it is factored.= 0: On entry,afandipivcontain the factored form ofA. Ifequedis not0, the matrixAhas been equilibrated with scaling factors given byrandc.A,af, andipivare not modified.= 1: The matrixAwill be copied toafand factored.= 2: The matrixAwill be equilibrated if necessary, then copied toafand factored.
transβ specifies the form of the system of equations:= 0:A * X = B(No transpose)= 1:A' * X = B(Transpose)= 2:A**H * X = B(Transpose)
Aβ on entry, the N-by-N matrixA. Iffact = 0andequedis not0, thenAmust have been equilibrated by the scaling factors inrand/orc.Ais not modified iffact = 0or1, or iffact = 2andequed = 0on exit.
On exit, if equed != 0, A is scaled as follows:
equed = 1:A := diag(r) * Aequed = 2:A := A * diag(c)equed = 3:A := diag(r) * A * diag(c).
afβ iffact = 0, thenafis an input argument and on entry contains the factorsLandUfrom the factorizationA = P*L*Uas computed bygetrf. Ifequed != 0, thenafis the factored form of the equilibrated matrixA.afβ okay so iffact = 1,afis an output argument, and when you come back out it hands you the factorsLandUfrom the factorizationA = P*L*Uof the original matrixA. β¨
And if fact = 2? Then af is also an output argument, and on exit it gives you the factors L and U from the factorization A = P*L*U of the equilibrated matrix A (go peek at the description of A for what the equilibrated matrix actually looks like). π
ipivβ the pivot tea, and it depends onfact:- If
fact = 0, thenipivis an input argument, and on entry it contains the pivot indices from the factorizationA = P*L*Uas computed bygetrf; rowiof the matrix was interchanged with rowipiv(i). π«Ά - If
fact = 1, thenipivis an output argument, and on exit it contains the pivot indices from the factorizationA = P*L*Uof the original matrixA. - If
fact = 2, thenipivis an output argument, and on exit it contains the pivot indices from the factorizationA = P*L*Uof the equilibrated matrixA.
- If
equedβ tells you what form of equilibration happened, bestie:= 0: no equilibration (always true iffact = 1)= 1: row equilibration, i.e.,Ahas been premultiplied bydiag(r)= 2: column equilibration, i.e.,Ahas been postmultiplied bydiag(c)= 3: both row and column equilibration, i.e.,Ahas been replaced bydiag(r) * A * diag(c)
equed is an input argument if fact = 0; otherwise, it's an output argument. Lowkey important to know which way it's flowing. π
rβ the row scale factors forA. Ifequed = 1or3,Ais multiplied on the left bydiag(r); ifequed = 0or2,ris not accessed at all (ghosted, honestly).ris an input argument iffact = 0; otherwise,ris an output argument. And heads up: iffact = 0andequed = 1or3, every single element ofrmust be positive. πcβ the column scale factors forA. Ifequed = 2or3,Ais multiplied on the right bydiag(c); ifequed = 0or1,cis not accessed.cis an input argument iffact = 0; otherwise,cis an output argument. Same rule asr: iffact = 0andequed = 2or3, each element ofcmust be positive. πBβ on entry, the N-by-NRHS right hand side matrixB. On exit, it depends:- if
equed = 0,Bis not modified (untouched, iconic) - if
trans = 0andequed = 1or3,Bis overwritten bydiag(r)*B - if
trans = 1or2andequed = 2or3,Bis overwritten bydiag(c)*B
- if
Xβ ifinfo = 0orinfo = N+1, this is the N-by-NRHS solution matrixXto the original system of equations. But real talk: note thatAandBare modified on exit ifequed != 0, and the solution to the equilibrated system isinv(diag(c))*Xiftrans = 0andequed = 2or3, orinv(diag(r))*Xiftrans = 1or2andequed = 1or3. β¨rcondβ the estimate of the reciprocal condition number of the matrixAafter equilibration (if equilibration was done). Ifrcondis less than the machine precision (and especially ifrcond = 0), the matrix is singular to working precision. That situation gets flagged by a return code ofinfo > 0. π¨ferrβ the estimated forward error bound for each solution vectorX(j)(thej-th column of the solution matrixX). IfXTRUEis the true solution corresponding toX(j), thenferr(j)is an estimated upper bound for the magnitude of the largest element in(X(j) - XTRUE)divided by the magnitude of the largest element inX(j). The estimate is as reliable as the estimate forrcond, and it's almost always a slight overestimate of the true error. Overachiever energy, honestly. πberrβ the componentwise relative backward error of each solution vectorX(j)(i.e., the smallest relative change in any element ofAorBthat makesX(j)an exact solution).rpvgrwβ contains the reciprocal pivot growth factornorm(A)/norm(U). The"max absolute element"norm is used. If it's much less than 1, then the stability of the LU factorization of the (equilibrated) matrixAcould be poor. This also means that the solutionX, the condition estimatorrcond, and the forward error boundferrcould all be unreliable. π And if factorization fails with0<info<=N, then it contains the reciprocal pivot growth factor for the leadinginfocolumns ofA.infoβ the final vibe check:= 0: successful exit π< 0: ifinfo = -i, thei-th argument had an illegal value> 0: ifinfo = i, andiis<= N:U(i,i)is exactly zero. The factorization has been completed, but the factorUis exactly singular, so the solution and error bounds could not be computed.rcond = 0is returned.= N+1:Uis nonsingular, butrcondis less than machine precision, meaning that the matrix is singular to working precision. Nevertheless, the solution and error bounds are computed, because there are a number of situations where the computed solution can be more accurate than the value ofrcondwould suggest. Plot twist, but a good one. π¦
Example time, bestie β copy this exactly:
$a= random(5,5);
$b = random(5,5);
$a = transpose($a);
$b = transpose($b);
$rcond = pdl(0);
$rpvgrw = pdl(0);
$equed = pdl(long,0);
$info = pdl(long,0);
$berr = zeroes(5);
$ipiv = zeroes(5);
$ferr = zeroes(5);
$r = zeroes(5);
$c = zeroes(5);
$X = zeroes(5,5);
$af = zeroes(5,5);
gesvx($a,0, 2, $b, $af, $ipiv, $equed, $r, $c, $X, $rcond, $ferr, $berr, $rpvgrw, $info);
print "The solution matrix X is :". transpose($X)."\n" unless $info;
gesvx ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. β¨
π¦ sysv π¦
Signature: ([io,phys]A(n,n); int uplo(); [io,phys]B(n,m); int [o]ipiv(n); int [o]info())
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', if uplo = 0, or
A = L * D * L', if uplo = 1,
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. π
The factored form of A is then used to solve the system of equations A * X = B.
π Arguments π
uploβ which triangle are we even using:= 0: Upper triangle ofAis stored= 1: Lower triangle ofAis stored
Aβ on entry, the symmetric matrixA. Ifuplo = 0, the leading N-by-N upper triangular part ofAcontains the upper triangular part of the matrixA, and the strictly lower triangular part ofAis not referenced. Ifuplo = 1, the leading N-by-N lower triangular part ofAcontains the lower triangular part of the matrixA, and the strictly upper triangular part ofAis not referenced. π
On exit, if info = 0, you get the block diagonal matrix D and the multipliers used to obtain the factor U or L from the factorization A = U*D*U' or A = L*D*L' as computed by sytrf.
ipivβ the details of the interchanges and the block structure ofD, as determined bysytrf. Here's the tea:- If
ipiv(k) > 0, then rows and columnskandipiv(k)were interchanged, andD(k,k)is a 1-by-1 diagonal block. - If
uplo = 0andipiv(k) = ipiv(k-1) < 0, then rows and columnsk-1and-ipiv(k)were interchanged, andD(k-1:k,k-1:k)is a 2-by-2 diagonal block. - If
uplo = 1andipiv(k) = ipiv(k+1) < 0, then rows and columnsk+1and-ipiv(k)were interchanged, andD(k:k+1,k:k+1)is a 2-by-2 diagonal block.
- If
Bβ on entry, the N-by-NRHS right hand side matrixB. On exit, ifinfo = 0, the N-by-NRHS solution matrixX. Slay. β¨infoβ the receipts:= 0: successful exit< 0: ifinfo = -i, thei-th argument had an illegal value> 0: ifinfo = i,D(i,i)is exactly zero. The factorization has been completed, but the block diagonal matrixDis exactly singular, so the solution could not be computed. π
Example, and yes the comment is part of it:
# Assume $a is symmetric ;)
$a = random (5,5);
$a = transpose($a);
$b = random(4,5);
$b = transpose($b);
sysv($a, 1, $b, (my $ipiv=zeroes(5)),(my $info=null));
print "The solution matrix X is :". transpose($b)."\n" unless $info;
sysv ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. πΈ
π§ sysvx π§
Signature: ([phys]A(n,n); int uplo(); int fact(); [phys]B(n,m); [io,phys]af(n,n); int [io,phys]ipiv(n); [o]X(n,m); [o]rcond(); [o]ferr(m); [o]berr(m); int [o]info(); int [t]iwork(n))
Uses the diagonal pivoting factorization to compute 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.
Error bounds on the solution and a condition estimate are also provided. She's thorough like that. π
The following steps are performed:
- If
fact = 0, the diagonal pivoting method is used to factorA. The form of the factorization is
A = U * D * U', if uplo = 0, or
A = L * D * L', if uplo = 1,
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.
- If some
D(i,i)=0, so thatDis exactly singular, then the routine returns withinfo = i. Otherwise, the factored form ofAis used to estimate the condition number of the matrixA. If the reciprocal of the condition number is less than machine precision,info = N+1is returned as a warning, but the routine still goes on to solve forXand compute error bounds as described below. π - The system of equations is solved for
Xusing the factored form ofA. - Iterative refinement is applied to improve the computed solution matrix and calculate error bounds and backward error estimates for it.
β¨ Arguments β¨
factβ tells the routine whether you're handing it the factored form ofAon entry or not. choose wisely bestie= 0: the matrixAwill be copied toafand factored. (she does the work herself π )= 1: on entry,afandipivcontain the factored form ofA.afandipivwill not be modified.
uploβ which triangle ofAis stored. pick a side, any side= 0: upper triangle ofAis stored= 1: lower triangle ofAis stored
Aβ the symmetric matrixA, the moment. Ifuplo = 0, the leading N-by-N upper triangular part ofAcontains the upper triangular part of the matrixA, and the strictly lower triangular part ofAis not referenced. Ifuplo = 1, the leading N-by-N lower triangular part ofAcontains the lower triangular part of the matrixA, and the strictly upper triangular part ofAis not referenced. only half of her is doing the talking, and that's validafβ iffact = 1, thenafis an input argument and on entry contains the block diagonal matrixDand the multipliers used to obtain the factorUorLfrom the factorizationA = U*D*U'orA = L*D*L'as computed bysytrf.
If fact = 0, then af is an output argument and on exit returns the block diagonal matrix D and the multipliers used to obtain the factor U or L from the factorization A = U*D*U' or A = L*D*L'.
ipivβ iffact = 1, thenipivis an input argument and on entry contains details of the interchanges and the block structure ofD, as determined bysytrf. the receipts π
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 = 0 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 = 1 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 fact = 0, then ipiv is an output argument and on exit contains details of the interchanges and the block structure of D, as determined by sytrf.
Bβ the N-by-NRHS right hand side matrixB. the whole entire plotXβ ifinfo = 0orinfo = N+1, the N-by-NRHS solution matrixX. the moment we've all been waiting for β¨rcondβ the estimate of the reciprocal condition number of the matrixA. Ifrcondis less than the machine precision (in particular, ifrcond = 0), the matrix is singular to working precision. This condition is indicated by a return code ofinfo > 0. β οΈ she's unwellferrβ the estimated forward error bound for each solution vectorX(j)(the j-th column of the solution matrixX). IfXTRUEis the true solution corresponding toX(j),ferr(j)is an estimated upper bound for the magnitude of the largest element in(X(j) - XTRUE)divided by the magnitude of the largest element inX(j). The estimate is as reliable as the estimate forrcond, and is almost always a slight overestimate of the true error. a lil dramatic, but honestberrβ the componentwise relative backward error of each solution vectorX(j)(i.e., the smallest relative change in any element ofAorBthat makesX(j)an exact solution).infoβ the vibe check at the end:= 0: successful exit slay< 0: ifinfo = -i, the i-th argument had an illegal value bestie who passed that> 0: ifinfo = i, andiis<= N:D(i,i)is exactly zero. The factorization has been completed but the factorDis exactly singular, so the solution and error bounds could not be computed.rcond = 0is returned.= N+1:Dis nonsingular, butrcondis less than machine precision, meaning that the matrix is singular to working precision. Nevertheless, the solution and error bounds are computed because there are a number of situations where the computed solution can be more accurate than the value ofrcondwould suggest.
Ok now the little demo, and no cap this is copy-paste exact:
$a= random(5,5);
$b = random(10,5);
$a = transpose($a);
$b = transpose($b);
$X = zeroes($b);
$af = zeroes($a);
$ipiv = zeroes(long, 5);
$rcond = pdl(0);
$ferr = zeroes(10);
$berr = zeroes(10);
$info = pdl(long, 0);
# Assume $a is symmetric
sysvx($a, 0, 0, $b,$af, $ipiv, $X, $rcond, $ferr, $berr,$info);
print "The solution matrix X is :". transpose($X)."\n";
sysvx ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. it's giving "we match energies"
πΈ posv πΈ
Signature: ([io,phys]A(n,n); int uplo(); [io,phys]B(n,m); int [o,phys]info())
Computes the solution to a real system of linear equations
A * X = B,
where A is an N-by-N symmetric positive definite matrix and X and B
are N-by-NRHS matrices.
The Cholesky decomposition is used to factor A as
A = U'* U, if uplo = 0, or
A = L * L', if uplo = 1,
where U is an upper triangular matrix and L is a lower triangular
matrix.
The factored form of A is then used to solve the system of equations A * X = B. iconic behavior honestly
π Arguments π
uploβ pick your triangle, bestie:= 0: upper triangle ofAis stored= 1: lower triangle ofAis stored
Aβ on entry, the symmetric matrixA. Ifuplo = 0, the leading N-by-N upper triangular part ofAcontains the upper triangular part of the matrixA, and the strictly lower triangular part ofAis not referenced. Ifuplo = 1, the leading N-by-N lower triangular part ofAcontains the lower triangular part of the matrixA, and the strictly upper triangular part ofAis not referenced.
On exit, if info = 0, the factor U or L from the Cholesky factorization A = U'*U or A = L*L'. she got transformed, glow up era
Bβ on entry, the N-by-NRHS right hand side matrixB. On exit, ifinfo = 0, the N-by-NRHS solution matrixX. in goes the problem, out comes the answerinfoβ the final report:= 0: successful exit periodt< 0: ifinfo = -i, the i-th argument had an illegal value> 0: ifinfo = i, the leading minor of orderiofAis not positive definite, so the factorization could not be completed, and the solution has not been computed. π she said no
Example time, verbatim:
# Assume $a is symmetric positive definite ;)
$a = random (5,5);
$a = transpose($a);
$b = random(4,5);
$b = transpose($b);
posv($a, 1, $b, (my $info=null));
print "The solution matrix X is :". transpose($b)."\n" unless $info;
posv ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
π¦ posvx π¦
Signature: ([io,phys]A(n,n); int uplo(); int fact(); [io,phys]B(n,m); [io,phys]af(n,n); int [io]equed(); [o]s(p); [o,phys]X(n,m); [o,phys]rcond(); [o,phys]ferr(m); [o,phys]berr(m); int [o,phys]info(); int [t]iwork(n); [t]work(workn))
Uses the Cholesky factorization A = U'*U or A = L*L' to compute the solution to a real system of linear equations
A * X = B,
where A is an N-by-N symmetric positive definite matrix and X and B
are N-by-NRHS matrices.
Error bounds on the solution and a condition estimate are also provided. she does the math AND the therapy
The following steps are performed:
- If
fact = 2, real scaling factors are computed to equilibrate the system:
diag(s) * A * diag(s) * inv(diag(s)) * X = diag(s) * B
Whether or not the system will be equilibrated depends on the scaling of the matrix A, but if equilibration is used, A is overwritten by diag(s)*A*diag(s) and B by diag(s)*B.
- If
fact = 1or2, the Cholesky decomposition is used to factor the matrixA(after equilibration iffact = 2) as
A = U'* U, if uplo = 0, or
A = L * L', if uplo = 1,
where U is an upper triangular matrix and L is a lower triangular
matrix.
- If the leading i-by-i principal minor is not positive definite, then the routine returns with
info = i. Otherwise, the factored form ofAis used to estimate the condition number of the matrixA. If the reciprocal of the condition number is less than machine precision,info = N+1is returned as a warning, but the routine still goes on to solve forXand compute error bounds as described below. she's flagging a warning but she is NOT stopping, main character energy - The system of equations is solved for
Xusing the factored form ofA. - Iterative refinement is applied to improve the computed solution matrix and calculate error bounds and backward error estimates for it.
- If equilibration was used, the matrix
Xis premultiplied bydiag(s)so that it solves the original system before equilibration. putting her back the way she was
β¨ Arguments β¨
factβ specifies whether or not the factored form of the matrixAis supplied on entry, and if not, whether the matrixAshould be equilibrated before it is factored. three moods, three paths= 0: on entry,afcontains the factored form ofA. Ifequed = 1, the matrixAhas been equilibrated with scaling factors given bys.Aandafwill not be modified.= 1: the matrixAwill be copied toafand factored.= 2: the matrixAwill be equilibrated if necessary, then copied toafand factored.
uploβ the triangle situation, same as ever:= 0: upper triangle ofAis stored= 1: lower triangle ofAis stored
Aβ on entry, the symmetric matrixA, except iffact = 0andequed = 1, thenAmust contain the equilibrated matrixdiag(s)*A*diag(s). plot twist Ifuplo = 0, the leading N-by-N upper triangular part ofAcontains the upper triangular part of the matrixA, and the strictly lower triangular part ofAis not referenced. Ifuplo = 1, the leading N-by-N lower triangular part ofAcontains the lower triangular part of the matrixA, and the strictly upper triangular part ofAis not referenced.Ais not modified iffact = 0or1, or iffact = 2andequed = 0on exit.
On exit, if fact = 2 and equed = 1, A is overwritten by diag(s)*A*diag(s). glow up complete
afβ okay so this one's whole personality depends onfact:
If fact = 0, then af is an input argument, and on entry it holds the triangular factor U or L from the Cholesky factorization A = U'*U or A = L*L', stored in the same format as A. And if equed != 0? Then af is the factored form of the equilibrated matrix diag(s)*A*diag(s). π
If fact = 1, then af is an output argument and on exit it returns the triangular factor U or L from the Cholesky factorization A = U'*U or A = L*L' of the original matrix A.
If fact = 2, then af is an output argument and on exit it returns the triangular factor U or L from the Cholesky factorization A = U'*U or A = L*L' of the equilibrated matrix A (peep the description of A for what the equilibrated matrix looks like).
equedβ tells you which form of equilibration went down:= 0: no equilibration (and this is always true iffact = 1).= 1: equilibration was done, i.e.Ahas been replaced bydiag(s) * A * diag(s).
equed is an input argument if fact = 0; otherwise it's an output argument. slay, it does both π
sβ the scale factors forA; not accessed ifequed = 0.sis an input argument iffact = 0; otherwisesis an output argument. And iffact = 0andequed = 1, every single element ofsmust be positive. no exceptions bestie π«ΆBβ on entry, the N-by-NRHS right hand side matrixB. On exit, ifequed = 0,Bis not modified; ifequed = 1,Bis overwritten bydiag(s) * B.Xβ ifinfo = 0orinfo = N+1, this is the N-by-NRHS solution matrixXto the original system of equations. Note that ifequed = 1,AandBare modified on exit, and the solution to the equilibrated system isinv(diag(s))*X. yes that's a whole extra matrix inversion in your brain, iykyk πrcondβ the estimate of the reciprocal condition number of the matrixAafter equilibration (if it happened). Ifrcondis less than the machine precision (in particular, ifrcond = 0), the matrix is singular to working precision. This condition is flagged by a return code ofinfo > 0.ferrβ the estimated forward error bound for each solution vectorX(j)(that's the j-th column of the solution matrixX). IfXTRUEis the true solution corresponding toX(j), thenFERR(j)is an estimated upper bound for the magnitude of the largest element in(X(j) - XTRUE)divided by the magnitude of the largest element inX(j). The estimate is as reliable as the estimate forrcond, and it is almost always a slight overestimate of the true error. generous queen β¨berrβ the componentwise relative backward error of each solution vectorX(j)(i.e., the smallest relative change in any element ofAorBthat makesX(j)an exact solution).infoβ the receipts:= 0: successful exit π< 0: ifinfo = -i, the i-th argument had an illegal value> 0: ifinfo = i, andiis<= N: the leading minor of orderiofAis not positive definite, so the factorization could not be completed, and the solution has not been computed.rcond = 0is returned.= N+1:Uis nonsingular, butrcondis less than machine precision, meaning the matrix is singular to working precision. Nevertheless, the solution and error bounds are computed, because there are a number of situations where the computed solution can be more accurate than the value ofrcondwould suggest. plot twist but make it math π¦
okay vibe check, here's the example:
$a= random(5,5);
$b = random(5,5);
$a = transpose($a);
$b = transpose($b);
# Assume $a is symmetric positive definite
$rcond = pdl(0);
$equed = pdl(long,0);
$info = pdl(long,0);
$berr = zeroes(5);
$ferr = zeroes(5);
$s = zeroes(5);
$X = zeroes(5,5);
$af = zeroes(5,5);
posvx($a,0,2,$b,$af, $equed, $s, $X, $rcond, $ferr, $berr,$info);
print "The solution matrix X is :". transpose($X)."\n" unless $info;
posvx ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. so if one's messy, they all match energy π
gels
Signature: ([io,phys]A(m,n); int trans(); [io,phys]B(p,q);int [o,phys]info())
Solves overdetermined or underdetermined real linear systems involving an M-by-N matrix A, or its transpose, using a QR or LQ factorization of A. It is assumed that A has full rank. (yes bestie, assumed β no refunds if it doesn't π)
The following options are provided:
- If
trans = 0andm >= n: find the least squares solution of an overdetermined system, i.e., solve the least squares problem minimize|| B - A*X ||. - If
trans = 0andm < n: find the minimum norm solution of an underdetermined systemA * X = B. - If
trans = 1andm >= n: find the minimum norm solution of an undetermined systemA' * X = B. - If
trans = 1andm < n: find the least squares solution of an overdetermined system, i.e., solve the least squares problem minimize|| B - A' * X ||.
Several right hand side vectors b and solution vectors x can be handled in a single call; they're stored as the columns of the M-by-NRHS right hand side matrix B and the N-by-NRHS solution matrix X. bulk queen behavior fr fr πΈ
Arguments
transβ= 0: the linear system involvesA;= 1: the linear system involvesA'.Aβ on entry, the M-by-N matrixA. On exit:- if
M >= N,Ais overwritten by details of its QR factorization as returned bygeqrf; - if
M < N,Ais overwritten by details of its LQ factorization as returned bygelqf.
- if
Bβ on entry, the matrixBof right hand side vectors, stored columnwise;Bis M-by-NRHS iftrans = 0, or N-by-NRHS iftrans = 1.
On exit, B is overwritten by the solution vectors, stored columnwise:
- if
trans = 0andm >= n, rows 1 tonofBcontain the least squares solution vectors; the residual sum of squares for the solution in each column is given by the sum of squares of elements N+1 to M in that column; - if
trans = 0andm < n, rows 1 toNofBcontain the minimum norm solution vectors; - if
trans = 1andm >= n, rows 1 toMofBcontain the minimum norm solution vectors; - if
trans = 1andm < n, rows 1 toMofBcontain the least squares solution vectors; the residual sum of squares for the solution in each column is given by the sum of squares of elements M+1 to N in that column.
The leading dimension of the array B >= max(1,M,N).
infoβ= 0: successful exit;< 0: ifinfo = -i, the i-th argument had an illegal value.
$a= random(7,5);
# $b will contain X
# TODO better example with slice
$b = random(7,6);
gels($a, 1, $b, ($info = null));
gels ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
gelsy
Signature: ([io,phys]A(m,n); [io,phys]B(p,q); [phys]rcond(); int [io,phys]jpvt(n); int [o,phys]rank();int [o,phys]info())
Computes the minimum-norm solution to a real linear least squares problem:
minimize || A * X - B ||
using a complete orthogonal factorization of A. π
A is an M-by-N matrix which may be rank-deficient. (unlike gels, this one doesn't need A to be full rank β glow up β¨)
Several right hand side vectors b and solution vectors x can be handled in a single call; they're stored as the columns of the M-by-NRHS right hand side matrix B and the N-by-NRHS solution matrix X.
The routine first computes a QR factorization with column pivoting:
A * P = Q * [ R11 R12 ]
[ 0 R22 ]
with R11 defined as the largest leading submatrix whose estimated condition number is less than 1/rcond. The order of R11, rank, is the effective rank of A.
Then, R22 is considered to be negligible, and R12 is annihilated by orthogonal transformations from the right, arriving at the complete orthogonal factorization:
A * P = Q * [ T11 0 ] * Z
[ 0 0 ]
The minimum-norm solution is then
X = P * Z' [ inv(T11)*Q1'*B ]
[ 0 ]
where Q1 consists of the first rank columns of Q. iconic math tbh π
Arguments
Aβ on entry, the M-by-N matrixA. On exit,Ahas been overwritten by details of its complete orthogonal factorization.Bβ on entry, the M-by-NRHS right hand side matrixB. On exit, the N-by-NRHS solution matrixX. The leading dimension of the arrayB >= max(1,M,N).jpvtβ on entry, ifjpvt(i) != 0, the i-th column ofAis permuted to the front ofAP, otherwise columniis a free column. On exit, ifjpvt(i) = k, then the i-th column ofAPwas the k-th column ofA.rcondβrcondis used to determine the effective rank ofA, which is defined as the order of the largest leading triangular submatrixR11in the QR factorization with pivoting ofA, whose estimated condition number< 1/rcond.rankβ the effective rank ofA, i.e., the order of the submatrixR11. This is the same as the order of the submatrixT11in the complete orthogonal factorization ofA.infoβ= 0: successful exit;< 0: ifinfo = -i, the i-th argument had an illegal value.
$a= random(7,5);
# $b will contain X
# TODO better example with slice
$b = random(7,6);
$jpvt = zeroes(long, 5);
$eps = lamch(0);
#Threshold for rank estimation
$rcond = sqrt($eps) - (sqrt($eps) - $eps) / 2;
gelsy($a, $b, $rcond, $jpvt,($rank=null),($info = null));
gelsy ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
gelss
Signature: ([io,phys]A(m,n); [io,phys]B(p,q); [phys]rcond(); [o,phys]s(r); int [o,phys]rank();int [o,phys]info())
Computes the minimum norm solution to a real linear least squares problem:
Minimize 2-norm(| b - A*x |).
using the singular value decomposition (SVD) of A. A is an M-by-N matrix which may be rank-deficient. bestie went straight to SVD, that's main character energy π
Several right hand side vectors b and solution vectors x can be handled in a single call β they're stored as the columns of the M-by-NRHS right hand side matrix B and the N-by-NRHS solution matrix X. So basically you can batch the whole squad instead of running them one at a time. π
The effective rank of A is determined by treating as zero those singular values which are less than rcond times the largest singular value.
Arguments
- A β On entry, the M-by-N matrix A. On exit, the first min(m,n) rows of A are overwritten with its right singular vectors, stored rowwise. (so yeah, she's getting rewritten, bestie)
- B β On entry, the M-by-NRHS right hand side matrix B. On exit, B is overwritten by the N-by-NRHS solution matrix X. If m >= n and rank = n, the residual sum-of-squares for the solution in the i-th column is given by the sum of squares of elements n+1:m in that column. The leading dimension of the array B >= max(1,M,N).
- s β The singular values of A in decreasing order. The condition number of A in the 2-norm = s(1)/s(min(m,n)).
- rcond β rcond is used to determine the effective rank of A. Singular values s(i) <= rcond*s(1) are treated as zero. If rcond < 0, machine precision is used instead.
- rank β The effective rank of A, i.e., the number of singular values which are greater than rcond*s(1).
- info β the receipts, and she has three moods:
= 0: successful exit β¨< 0: if info = -i, the i-th argument had an illegal value. π©> 0: the algorithm for computing the SVD failed to converge; if info = i, i off-diagonal elements of an intermediate bidiagonal form did not converge to zero. π
$a= random(7,5);
# $b will contain X
# TODO better example with slice
$b = random(7,6);
$eps = lamch(0);
$s =zeroes(5);
#Threshold for rank estimation
$rcond = sqrt($eps) - (sqrt($eps) - $eps) / 2;
gelss($a, $b, $rcond, $s, ($rank=null),($info = null));
gelss ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. no cap.
gelsd
Signature: ([io]A(m,n); [io]B(p,q); rcond(); [o]s(minmn); int [o]rank();int [o]info(); int [t]iwork(iworkn))
Computes the minimum-norm solution to a real linear least squares problem:
minimize 2-norm(| b - A*x |)
using the singular value decomposition (SVD) of A. A is an M-by-N matrix which may be rank-deficient. (rank-deficient is valid and we support her π«Ά)
Several right hand side vectors b and solution vectors x can be handled in a single call; they are stored as the columns of the M-by-NRHS right hand side matrix B and the N-by-NRHS solution matrix X.
The problem is solved in three steps:
- Reduce the coefficient matrix A to bidiagonal form with Householder transformations, reducing the original problem into a "bidiagonal least squares problem" (BLS)
- Solve the BLS using a divide and conquer approach.
- Apply back all the Householder transformations to solve the original least squares problem.
The effective rank of A is determined by treating as zero those singular values which are less than rcond times the largest singular value.
The divide and conquer algorithm makes very mild assumptions about floating point arithmetic. It will work on machines with a guard digit in add/subtract, or on those binary machines without guard digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or Cray-2. It could conceivably fail on hexadecimal or decimal machines without guard digits, but we know of none. so likeβ¦ she's chill on basically everything, Cray girlies included. π
Arguments
- A β On entry, the M-by-N matrix A. On exit, A has been destroyed. π (that's just how it is)
- B β On entry, the M-by-NRHS right hand side matrix B. On exit, B is overwritten by the N-by-NRHS solution matrix X. If m >= n and rank = n, the residual sum-of-squares for the solution in the i-th column is given by the sum of squares of elements n+1:m in that column. The leading dimension of the array B >= max(1,M,N).
- s β The singular values of A in decreasing order. The condition number of A in the 2-norm = s(1)/s(min(m,n)).
- rcond β rcond is used to determine the effective rank of A. Singular values s(i) <= rcond*s(1) are treated as zero. If rcond < 0, machine precision is used instead.
- rank β The effective rank of A, i.e., the number of singular values which are greater than rcond*s(1).
- info β bestie check this before you trust the answer:
= 0: successful exit β¨< 0: if info = -i, the i-th argument had an illegal value. π©> 0: the algorithm for computing the SVD failed to converge; if info = i, i off-diagonal elements of an intermediate bidiagonal form did not converge to zero. π
$a= random(7,5);
# $b will contain X
# TODO better example with slice
$b = random(7,6);
$eps = lamch(0);
$s =zeroes(5);
#Threshold for rank estimation
$rcond = sqrt($eps) - (sqrt($eps) - $eps) / 2;
gelsd($a, $b, $rcond, $s, ($rank=null),($info = null));
gelsd ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
gglse
Signature: ([phys]A(m,n); [phys]B(p,n);[io,phys]c(m);[phys]d(p);[o,phys]x(n);int [o,phys]info())
Solves the linear equality-constrained least squares (LSE) problem:
minimize || c - A*x ||_2 subject to B*x = d
where A is an M-by-N matrix, B is a P-by-N matrix, c is a given
M-vector, and d is a given P-vector. It is assumed that
P <= N <= M+P, and
rank(B) = P and rank( ( A ) ) = N.
( ( B ) )
These conditions ensure that the LSE problem has a unique solution, which is obtained using a GRQ factorization of the matrices B and A. one answer only, she's monogamous like that π
Arguments
- A β On entry, the M-by-N matrix A. On exit, A is destroyed.
- B β On entry, the P-by-N matrix B. On exit, B is destroyed.
- c β On entry, c contains the right hand side vector for the least squares part of the LSE problem. On exit, the residual sum of squares for the solution is given by the sum of squares of elements N-P+1 to M of vector c.
- d β On entry, d contains the right hand side vector for the constrained equation. On exit, d is destroyed.
- x β On exit, x is the solution of the LSE problem. π
- info β the vibe check:
= 0: successful exit. β¨< 0: if info = -i, the i-th argument had an illegal value. π©
$a = random(7,5);
$b = random(4,5);
$c = random(7);
$d = random(4);
$x = zeroes(5);
gglse($a, $b, $c, $d, $x, ($info=null));
gglse ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
ggglm
Signature: ([phys]A(n,m); [phys]B(n,p);[phys]d(n);[o,phys]x(m);[o,phys]y(p);int [o,phys]info())
Solves a general Gauss-Markov linear model (GLM) problem:
minimize || y ||_2 subject to d = A*x + B*y
x
where A is an N-by-M matrix, B is an N-by-P matrix, and d is a
given N-vector. It is assumed that M <= N <= M+P, and
rank(A) = M and rank( A B ) = N.
Under these assumptions, the constrained equation is always consistent, and there is a unique solution x and a minimal 2-norm solution y, which is obtained using a generalized QR factorization of A and B.
In particular, if matrix B is square nonsingular, then the problem GLM is equivalent to the following weighted linear least squares problem
minimize || inv(B)*(d-A*x) ||_2
x
where inv(B) denotes the inverse of B.
Arguments
- A β On entry, the N-by-M matrix A. On exit, A is destroyed.
- B β On entry, the N-by-P matrix B. On exit, B is destroyed.
- d β On entry, d is the left hand side of the GLM equation. On exit, d is destroyed.
- x β (paired with y below π)
- y β On exit, x and y are the solutions of the GLM problem. π«Ά
- info β checking in:
= 0: successful exit. β¨< 0: if info = -i, the i-th argument had an illegal value. π©
$a = random(7,5);
$b = random(7,4);
$d = random(7);
$x = zeroes(5);
$y = zeroes(4);
ggglm($a, $b, $d, $x, $y,($info=null));
ggglm ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
getrf
Signature: ([io]A(m,n); int [o]ipiv(p); int [o]info())
Computes an LU factorization of a general M-by-N matrix A using partial pivoting with row interchanges.
The factorization has the form
A = P * L * U
where P is a permutation matrix, L is lower triangular with unit
diagonal elements (lower trapezoidal if m > n), and U is upper
triangular (upper trapezoidal if m < n).
This is the right-looking Level 3 BLAS version of the algorithm. highkey the fancy one π₯
Arguments
- A β On entry, the M-by-N matrix to be factored. On exit, the factors L and U from the factorization A = P*L*U; the unit diagonal elements of L are not stored.
- ipiv β The pivot indices; for 1 <= i <= min(M,N), row i of the matrix was interchanged with row ipiv(i).
- info β the tea:
= 0: successful exit β¨< 0: if info = -i, the i-th argument had an illegal value π©> 0: if info = i, U(i,i) is exactly zero. The factorization has been completed, but the factor U is exactly singular, and division by zero will occur if it is used to solve a system of equations. π
$a = random (float, 100,50);
$ipiv = zeroes(long, 50);
$info = null;
getrf($a, $ipiv, $info);
getrf ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
getf2
Signature: ([io]A(m,n); int [o]ipiv(p); int [o]info())
Computes an LU factorization of a general M-by-N matrix A using partial pivoting with row interchanges.
The factorization has the form
A = P * L * U
where P is a permutation matrix, L is lower triangular with unit
diagonal elements (lower trapezoidal if m > n), and U is upper
triangular (upper trapezoidal if m < n).
This is the right-looking Level 2 BLAS version of the algorithm.
π Arguments π
Aβ on entry, the M-by-N matrix to be factored. On exit, the factorsLandUfrom the factorizationA = P*L*U; the unit diagonal elements ofLare not stored (they're literally all1, we're not wasting memory on that π ).ipivβ the pivot indices; for1 <= i <= min(M,N), rowiof the matrix was interchanged with rowipiv(i).infoβ the vibe report:= 0: successful exit β¨< 0: ifinfo = -i, the i-th argument had an illegal value> 0: ifinfo = i,U(i,i)is exactly zero. The factorization has been completed, but the factorUis exactly singular, and division by zero will occur if it is used to solve a system of equations. π
$a = random (float, 100,50);
$ipiv = zeroes(long, 50);
$info = null;
getf2($a, $ipiv, $info);
getf2 ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
π¦ sytrf π¦
Signature: ([io,phys]A(n,n); int uplo(); int [o,phys]ipiv(n); int [o,phys]info())
Computes the factorization of a real symmetric matrix A using the Bunch-Kaufman diagonal pivoting method. The form of the factorization is
A = U*D*U' or A = L*D*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.
This is the blocked version of the algorithm, calling Level 3 BLAS. no cap.
π Arguments π
uploβ= 0: Upper triangle ofAis stored;= 1: Lower triangle ofAis stored.
Aβ on entry, the symmetric matrixA. Ifuplo = 0, the leading N-by-N upper triangular part ofAcontains the upper triangular part of the matrixA, and the strictly lower triangular part ofAis not referenced. Ifuplo = 1, the leading N-by-N lower triangular part ofAcontains the lower triangular part of the matrixA, and the strictly upper triangular part ofAis 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 π).
ipivβ details of the interchanges and the block structure ofD.- If
ipiv(k) > 0, then rows and columnskandipiv(k)were interchanged andD(k,k)is a 1-by-1 diagonal block. - If
uplo = 0andipiv(k) = ipiv(k-1) < 0, then rows and columnsk-1and-ipiv(k)were interchanged andD(k-1:k,k-1:k)is a 2-by-2 diagonal block. - If
uplo = 1andipiv(k) = ipiv(k+1) < 0, then rows and columnsk+1and-ipiv(k)were interchanged andD(k:k+1,k:k+1)is a 2-by-2 diagonal block.
- If
infoβ the receipts:= 0: successful exit β¨< 0: ifinfo = -i, the i-th argument had an illegal value> 0: ifinfo = i,D(i,i)is exactly zero. The factorization has been completed, but the block diagonal matrixDis exactly singular, and division by zero will occur if it is used to solve a system of equations. π¨
π Further Details π
If uplo = 0, then A = U*D*U', 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 = 1, then A = L*D*L', 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).
$a = random(100,100);
$ipiv = zeroes(100);
$info = null;
# Assume $a is symmetric
sytrf($a, 0, $ipiv, $info);
sytrf ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
πΈ sytf2 πΈ
Signature: ([io,phys]A(n,n); int uplo(); int [o,phys]ipiv(n); int [o,phys]info())
Computes the factorization of a real symmetric matrix A using the Bunch-Kaufman diagonal pivoting method. The form of the factorization is
A = U*D*U' or A = L*D*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.
This is the unblocked version of the algorithm, calling Level 2 BLAS. it's giving smaller-scale but still iconic π
π Arguments π
uploβ= 0: Upper triangle ofAis stored;= 1: Lower triangle ofAis stored.
Aβ on entry, the symmetric matrixA. Ifuplo = 0, the leading N-by-N upper triangular part ofAcontains the upper triangular part of the matrixA, and the strictly lower triangular part ofAis not referenced. Ifuplo = 1, the leading N-by-N lower triangular part ofAcontains the lower triangular part of the matrixA, and the strictly upper triangular part ofAis 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).
ipivβ details of the interchanges and the block structure ofD.- If
ipiv(k) > 0, then rows and columnskandipiv(k)were interchanged andD(k,k)is a 1-by-1 diagonal block. - If
uplo = 0andipiv(k) = ipiv(k-1) < 0, then rows and columnsk-1and-ipiv(k)were interchanged andD(k-1:k,k-1:k)is a 2-by-2 diagonal block. - If
uplo = 1andipiv(k) = ipiv(k+1) < 0, then rows and columnsk+1and-ipiv(k)were interchanged andD(k:k+1,k:k+1)is a 2-by-2 diagonal block.
- If
infoβ the receipts:= 0: successful exit β¨< 0: ifinfo = -i, the i-th argument had an illegal value> 0: ifinfo = i,D(i,i)is exactly zero. The factorization has been completed, but the block diagonal matrixDis exactly singular, and division by zero will occur if it is used to solve a system of equations. π
For further details see sytrf.
$a = random(100,100);
$ipiv = zeroes(100);
$info = null;
# Assume $a is symmetric
sytf2($a, 0, $ipiv, $info);
sytf2 ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
π potrf π
Signature: ([io,phys]A(n,n); int uplo(); int [o,phys]info())
Computes the Cholesky factorization of a real symmetric positive definite matrix A.
The factorization has the form
A = U' * U, if uplo = 0, or
A = L * L', if uplo = 1,
where U is an upper triangular matrix and L is lower triangular.
This is the block version of the algorithm, calling Level 3 BLAS. main character energy fr fr π₯
π Arguments π
uploβ= 0: Upper triangle ofAis stored;= 1: Lower triangle ofAis stored.
Aβ on entry, the symmetric matrixA. Ifuplo = 0, the leading N-by-N upper triangular part ofAcontains the upper triangular part of the matrixA, and the strictly lower triangular part ofAis not referenced. Ifuplo = 1, the leading N-by-N lower triangular part ofAcontains the lower triangular part of the matrixA, and the strictly upper triangular part ofAis not referenced.
On exit, if info = 0, the factor U or L from the Cholesky factorization A = U'*U or A = L*L'.
infoβ the receipts:= 0: successful exit β¨< 0: ifinfo = -i, the i-th argument had an illegal value> 0: ifinfo = i, the leading minor of order i is not positive definite, and the factorization could not be completed. π
$a = random(100,100);
# Assume $a is symmetric positive definite
potrf($a, 0, ($info = null));
potrf ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
π§ potf2 π§
Signature: ([io,phys]A(n,n); int uplo(); int [o,phys]info())
Computes the Cholesky factorization of a real symmetric positive definite matrix A.
The factorization has the form
A = U' * U, if uplo = 0, or
A = L * L', if uplo = 1,
where U is an upper triangular matrix and L is lower triangular.
This is the unblocked version of the algorithm, calling Level 2 BLAS.
π Arguments π
uploβ= 0: Upper triangle ofAis stored;= 1: Lower triangle ofAis stored.
Aβ on entry, the symmetric matrixA. Ifuplo = 0, the leading N-by-N upper triangular part ofAcontains the upper triangular part of the matrixA, and the strictly lower triangular part ofAis not referenced. Ifuplo = 1, the leading N-by-N lower triangular part ofAcontains the lower triangular part of the matrixA, and the strictly upper triangular part ofAis not referenced.
On exit, if info = 0, the factor U or L from the Cholesky factorization A = U'*U or A = L*L'.
infoβ the vibe check on how it went, bestie:= 0: successful exit, we ate π< 0: ifinfo = -i, then the i-th argument had an illegal value (like, no)> 0: ifinfo = i, the leading minor of order i is not positive definite, and the factorization could not be completed π
$a = random(100,100);
# Assume $a is symmetric positive definite
potf2($a, 0, ($info = null));
potf2 ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π
getri
Signature: ([io,phys]A(n,n); int [phys]ipiv(n); int [o,phys]info())
Okay so this one computes the inverse of a matrix using the LU factorization computed by getrf. π¦
It inverts U and then computes inv(A) by solving the system
inv(A)*L = inv(U) for inv(A).
Arguments
Aβ On entry: the factors L and U from the factorization A = P*L*U as computed bygetrf. On exit: ifinfo = 0, the inverse of the original matrix A. β¨ipivβ The pivot indices fromgetrf; for1<=i<=N, row i of the matrix was interchanged with rowipiv(i).infoβ the group chat update:= 0: successful exit< 0: ifinfo = -i, the i-th argument had an illegal value> 0: ifinfo = i,U(i,i)is exactly zero; the matrix is singular and its inverse could not be computed π
$a = random (float, 100, 100);
$ipiv = zeroes(long, 100);
$info = null;
getrf($a, $ipiv, $info);
if ($info == 0){
getri($a, $ipiv, $info);
}
print "Inverse of \$a is :\n $a" unless $info;
getri ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. πΈ
sytri
Signature: ([io]A(n,n); int uplo(); int ipiv(n); int [o]info(); [t]work(n))
Computes the inverse of a real symmetric indefinite matrix A using the factorization A = U*D*U' or A = L*D*L' computed by sytrf. π
Arguments
uploβ Specifies whether the details of the factorization are stored as an upper or lower triangular matrix.= 0: Upper triangular, form is A = U*D*U';= 1: Lower triangular, form is A = L*D*L'.
Aβ On entry: the block diagonal matrix D and the multipliers used to obtain the factor U or L as computed bysytrf. On exit: ifinfo = 0, the (symmetric) inverse of the original matrix. Ifuplo = 0, the upper triangular part of the inverse is formed and the part of A below the diagonal is not referenced; ifuplo = 1the lower triangular part of the inverse is formed and the part of A above the diagonal is not referenced. πipivβ Details of the interchanges and the block structure of D as determined bysytrf.infoβ= 0: successful exit< 0: ifinfo = -i, the i-th argument had an illegal value> 0: ifinfo = i,D(i,i) = 0; the matrix is singular and its inverse could not be computed π
$a = random (float, 100, 100);
# assume $a is symmetric
$ipiv = zeroes(long, 100);
sytrf($a, 0, $ipiv, ($info=null));
if ($info == 0){
sytri($a, 0, $ipiv, $info);
}
print "Inverse of \$a is :\n $a" unless $info;
sytri ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π
potri
Signature: ([io,phys]A(n,n); int uplo(); int [o,phys]info())
Computes the inverse of a real symmetric positive definite matrix A using the Cholesky factorization A = U'*U or A = L*L' computed by potrf. π
Arguments
uploβ= 0: Upper triangle of A is stored;= 1: Lower triangle of A is stored.
Aβ On entry: the triangular factor U or L from the Cholesky factorization A = U'*U or A = L*L', as computed bypotrf. On exit: the upper or lower triangle of the (symmetric) inverse of A, overwriting the input factor U or L. π«infoβ= 0: successful exit< 0: ifinfo = -i, the i-th argument had an illegal value> 0: ifinfo = i, the(i,i)element of the factor U or L is zero, and the inverse could not be computed π
$a = random (float, 100, 100);
# Assume $a is symmetric positive definite
potrf($a, 0, ($info = null));
if ($info == 0){ # Hum... is it positive definite????
potri($a, 0,$info);
}
print "Inverse of \$a is :\n $a" unless $info;
potri ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. β
trtri
Signature: ([io,phys]A(n,n); int uplo(); int diag(); int [o,phys]info())
Computes the inverse of a real upper or lower triangular matrix A. π₯
This is the Level 3 BLAS version of the algorithm.
Arguments
uploβ= 0: A is upper triangular;= 1: A is lower triangular.
diagβ= 0: A is non-unit triangular;= 1: A is unit triangular.
Aβ On entry: the triangular matrix A. Ifuplo = 0, the leading N-by-N upper triangular part of the array A contains the upper triangular matrix, and the strictly lower triangular part of A is not referenced. Ifuplo = 1, the leading N-by-N lower triangular part of the array A contains the lower triangular matrix, and the strictly upper triangular part of A is not referenced. Ifdiag = 1, the diagonal elements of A are also not referenced and are assumed to be 1. On exit: the (triangular) inverse of the original matrix, in the same storage format. β¨infoβ= 0: successful exit< 0: ifinfo = -i, the i-th argument had an illegal value> 0: ifinfo = i,A(i,i)is exactly zero. The triangular matrix is singular and its inverse can not be computed π
$a = random (float, 100, 100);
# assume $a is upper triangular
trtri($a, 1, ($info=null));
print "Inverse of \$a is :\n transpose($a)" unless $info;
trtri ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π§
trti2
Signature: ([io,phys]A(n,n); int uplo(); int diag(); int [o,phys]info())
Computes the inverse of a real upper or lower triangular matrix A. π¦
This is the Level 2 BLAS version of the algorithm.
Arguments
uploβ= 0: A is upper triangular;= 1: A is lower triangular.
diagβ= 0: A is non-unit triangular;= 1: A is unit triangular.
Aβ On entry: the triangular matrix A. Ifuplo = 0, the leading N-by-N upper triangular part of the array A contains the upper triangular matrix, and the strictly lower triangular part of A is not referenced. Ifuplo = 1, the leading N-by-N lower triangular part of the array A contains the lower triangular matrix, and the strictly upper triangular part of A is not referenced. Ifdiag = 1, the diagonal elements of A are also not referenced and are assumed to be 1. On exit: the (triangular) inverse of the original matrix, in the same storage format. πinfoβ= 0: successful exit< 0: ifinfo = -i, the i-th argument had an illegal value
$a = random (float, 100, 100);
# assume $a is upper triangular
trtri2($a, 1, ($info=null));
print "Inverse of \$a is :\n transpose($a)" unless $info;
trti2 ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. πΈ
getrs
Signature: ([phys]A(n,n); int trans(); [io,phys]B(n,m); int [phys]ipiv(n); int [o,phys]info())
Solves a system of linear equations
A * X = B or A' * X = B
with a general N-by-N matrix A using the LU factorization computed by getrf. π₯
Arguments
transβ Specifies the form of the system of equations:= 0: A * X = B (No transpose)= 1: A'* X = B (Transpose)
Aβ The factors L and U from the factorization A = P*L*U as computed bygetrf.ipivβ The pivot indices fromgetrf; for1<=i<=N, row i of the matrix was interchanged with rowipiv(i).Bβ On entry: the right hand side matrix B. On exit: the solution matrix X. β¨infoβ= 0: successful exit< 0: ifinfo = -i, the i-th argument had an illegal value
$a = random (float, 100, 100);
$ipiv = zeroes(long, 100);
$b = random(100,50);
getrf($a, $ipiv, ($info=null));
if ($info == 0){
getrs($a, 0, $b, $ipiv, $info);
}
print "X is :\n $b" unless $info;
getrs ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π
sytrs
Signature: ([phys]A(n,n); int uplo();[io,phys]B(n,m); int [phys]ipiv(n); int [o,phys]info())
Solves a system of linear equations A*X = B with a real symmetric matrix A using the factorization A = U*D*U' or A = L*D*L' computed by sytrf. π
Arguments
uploβ Specifies whether the details of the factorization are stored as an upper or lower triangular matrix.= 0: Upper triangular, form is A = U*D*U';= 1: Lower triangular, form is A = L*D*L'.
Aβ The block diagonal matrix D and the multipliers used to obtain the factor U or L as computed bysytrf.ipivβ Details of the interchanges and the block structure of D as determined bysytrf.Bβ On entry: the right hand side matrix B. On exit: the solution matrix X. πinfoβ= 0: successful exit< 0: ifinfo = -i, the i-th argument had an illegal value
$a = random (float, 100, 100);
$b = random(50,100);
$a = transpose($a);
$b = transpose($b);
# Assume $a is symmetric
sytrf($a, 0, ($ipiv=zeroes(100)), ($info=null));
if ($info == 0){
sytrs($a, 0, $b, $ipiv, $info);
}
print("X is :\n".transpose($b))unless $info;
okay so real quick bestie β sytrs literally ignores the bad-value flag of the input ndarrays π
. But it will set the bad-value flag on all the output ndarrays if the flag is set for any of the input ndarrays. no cap, that's the whole deal.
πΈ potrs πΈ
Signature: ([phys]A(n,n); int uplo(); [io,phys]B(n,m); int [o,phys]info())
Solves a system of linear equations A*X = B where A is a symmetric positive definite matrix, using the Cholesky factorization A = U'*U or A = L*L' that potrf already computed for you. it's giving "reuse the homework you already did" β¨
Arguments
uploβ which triangle ofAwe're actually storing:= 0: Upper triangle ofAis stored;= 1: Lower triangle ofAis stored.
Aβ the triangular factorUorLfrom the Cholesky factorizationA = U'*UorA = L*L', as computed bypotrf. yes, the same one. don't go making a new one πBβ on entry, the right hand side matrixB. on exit, the solution matrix X. glow-up arc fr fr π¦infoβ the vibe check:= 0: successful exit π< 0: ifinfo = -i, the i-th argument had an illegal value π
$a = random (float, 100, 100);
$b = random(50,100);
$a = transpose($a);
$b = transpose($b);
# Assume $a is symmetric positive definite
potrf($a, 0, ($info=null));
if ($info == 0){
potrs($a, 0, $b, $info);
}
print("X is :\n".transpose($b))unless $info;
potrs ignores the bad-value flag of the input ndarrays. it will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. same energy as always, you know the drill π
π trtrs π
Signature: ([phys]A(n,n); int uplo(); int trans(); int diag();[io,phys]B(n,m); int [o,phys]info())
Solves a triangular system of the form
A * X = B or A' * X = B,
where A is a triangular matrix of order N, and B is an N-by-NRHS
matrix.
and bestie, it literally checks that A is nonsingular. it does the work so you don't have to π
Arguments
uploβ which triangleAis:= 0:Ais upper triangular;= 1:Ais lower triangular.
transβ what form of the system we're solving:= 0:A * X = B(No transpose)= 1:A**T * X = B(Transpose)
diagβ is the diagonal doing anything or not:= 0:Ais non-unit triangular;= 1:Ais unit triangular.
Aβ the triangular matrixA. ifuplo = 0, the leading N-by-N upper triangular part of the arrayAcontains the upper triangular matrix, and the strictly lower triangular part ofAis not referenced. ifuplo = 1, the leading N-by-N lower triangular part of the arrayAcontains the lower triangular matrix, and the strictly upper triangular part ofAis not referenced. and ifdiag = 1, the diagonal elements ofAare also not referenced and are assumed to be1. iconic, honestly β half the array is just vibing in the background π§Bβ on entry, the right hand side matrixB. on exit, ifinfo = 0, the solution matrix X.infoβ the receipts:= 0: successful exit β¨< 0: ifinfo = -i, the i-th argument had an illegal value π> 0: ifinfo = i, the i-th diagonal element ofAis zero, indicating that the matrix is singular and the solutionsXhave not been computed. so like, no solution, no X, nothing. tragic. π
# Assume $a is upper triangular
$a = random (float, 100, 100);
$b = random(50,100);
$a = transpose($a);
$b = transpose($b);
$info = null;
trtrs($a, 0, 0, 0, $b, $info);
print("X is :\n".transpose($b))unless $info;
trtrs ignores the bad-value flag of the input ndarrays. it will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π
π¦ latrs π¦
Signature: ([phys]A(n,n); int uplo(); int trans(); int diag(); int normin();[io,phys]x(n); [o,phys]scale();[io,phys]cnorm(n);int [o,phys]info())
Solves one of the triangular systems
A *x = s*b or A'*x = s*b
with scaling to prevent overflow. here A is an upper or lower triangular matrix, A' denotes the transpose of A, x and b are n-element vectors, and s is a scaling factor β usually less than or equal to 1, chosen so that the components of x will be less than the overflow threshold. if the unscaled problem won't cause overflow, the Level 2 BLAS routine trsv gets called. and if the matrix A is singular (A(j,j) = 0 for some j), then s is set to 0 and a non-trivial solution to A*x = 0 is returned. main character move honestly π
Further Details
a rough bound on x is computed; if that's less than overflow, trsv is called, otherwise, specific code is used which checks for possible overflow or divide-by-zero at every operation. vigilance π
a columnwise scheme is used for solving A*x = b. the basic algorithm if A is lower triangular is
x[1:n] := b[1:n]
for j = 1, ..., n
x(j) := x(j) / A(j,j)
x[j+1:n] := x[j+1:n] - x(j) * A[j+1:n,j]
end
define bounds on the components of x after j iterations of the loop:
M(j) = bound on x[1:j]
G(j) = bound on x[j+1:n]
initially, let M(0) = 0 and G(0) = max{x(i), i=1,...,n}.
then for iteration j+1 we have
M(j+1) <= G(j) / | A(j+1,j+1) |
G(j+1) <= G(j) + M(j+1) * | A[j+2:n,j+1] |
<= G(j) ( 1 + cnorm(j+1) / | A(j+1,j+1) | )
where cnorm(j+1) is greater than or equal to the infinity-norm of column j+1 of A, not counting the diagonal.
hence
G(j) <= G(0) product ( 1 + cnorm(i) / | A(i,i) | )
1<=i<=j
and
|x(j)| <= ( G(0) / |A(j,j)| ) product ( 1 + cnorm(i) / |A(i,i)| )
1<=i< j
since |x(j)| <= M(j), we use the Level 2 BLAS routine DTRSV if the reciprocal of the largest M(j), j=1,..,n, is larger than max(underflow, 1/overflow).
the bound on x(j) is also used to determine when a step in the columnwise method can be performed without fear of overflow. if the computed bound is greater than a large constant, x is scaled to prevent overflow β but if the bound overflows, x is set to 0, x(j) to 1, and scale to 0, and a non-trivial solution to A*x = 0 is found. so yeah, it doesn't just give up, it finds you a whole other answer. π
similarly, a row-wise scheme is used to solve A'*x = b. the basic algorithm for A upper triangular is
for j = 1, ..., n
x(j) := ( b(j) - A[1:j-1,j]' * x[1:j-1] ) / A(j,j)
end
we simultaneously compute two bounds
G(j) = bound on ( b(i) - A[1:i-1,i]' * x[1:i-1] ), 1<=i<=j
M(j) = bound on x(i), 1<=i<=j
the initial values are G(0) = 0, M(0) = max{b(i), i=1,..,n}, and we add the constraint G(j) >= G(j-1) and M(j) >= M(j-1) for j >= 1. then the bound on x(j) is
M(j) <= M(j-1) * ( 1 + cnorm(j) ) / | A(j,j) |
<= M(0) * product ( ( 1 + cnorm(i) ) / |A(i,i)| )
1<=i<=j
and we can safely call trsv if 1/M(n) and 1/G(n) are both greater than max(underflow, 1/overflow). β¨
Arguments
uploβ specifies whether the matrixAis upper or lower triangular.= 0: Upper triangular= 1: Lower triangular
transβ specifies the operation applied toA.= 0: SolveA * x = s*b(No transpose)= 1: SolveA'* x = s*b(Transpose)
diagβ specifies whether or not the matrixAis unit triangular.= 0: Non-unit triangular= 1: Unit triangular
norminβ specifies whethercnormhas been set or not.= 1:cnormcontains the column norms on entry= 0:cnormis not set on entry. on exit, the norms will be computed and stored incnorm.
Aβ the triangular matrixA. ifuplo = 0, the leading n by n upper triangular part of the arrayAcontains the upper triangular matrix, and the strictly lower triangular part ofAis not referenced. ifuplo = 1, the leading n by n lower triangular part of the arrayAcontains the lower triangular matrix, and the strictly upper triangular part ofAis not referenced. ifdiag = 1, the diagonal elements ofAare also not referenced and are assumed to be1.xβ on entry, the right hand sidebof the triangular system. on exit,xis overwritten by the solution vector x. bye b, hello x πscaleβ the scaling factorsfor the triangular systemA * x = s*borA'* x = s*b. ifscale = 0, the matrixAis singular or badly scaled, and the vectorxis an exact or approximate solution toA*x = 0. that's a whole situation, so watch for it.cnormβ ifnormin = 0,cnormis an output argument andcnorm(j)returns the 1-norm of the offdiagonal part of the j-th column ofA. ifnormin = 1,cnormis an input argument andcnorm(j)contains the norm of the off-diagonal part of the j-th column ofA. iftrans = 0,cnorm(j)must be greater than or equal to the infinity-norm, and iftrans = 1,cnorm(j)must be greater than or equal to the 1-norm. input or output depending onnormin, so like, read the room. πinfoβ the classic:= 0: successful exit π< 0: ifinfo = -k, the k-th argument had an illegal value π
# Assume $a is upper triangular
$a = random (float, 100, 100);
$b = random(100);
$a = transpose($a);
$info = null;
$scale= null;
$cnorm = zeroes(100);
latrs($a, 0, 0, 0, 0,$b, $scale, $cnorm,$info);
latrs ignores the bad-value flag of the input ndarrays. it will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π«Ά
π gecon π
Signature: (A(n,n); int norm(); anorm(); [o]rcond();int [o]info(); int [t]iwork(n); [t]work(workn))
Estimates the reciprocal of the condition number of a general real matrix A, in either the 1-norm or the infinity-norm, using the LU factorization computed by getrf.
an estimate is obtained for norm(inv(A)), and the reciprocal of the condition number is computed as
rcond = 1 / ( norm(A) * norm(inv(A)) ).
it's giving "how sketchy is this matrix, on a scale" and honestly we love a matrix that knows itself π
Arguments
normβ specifies whether the 1-norm condition number or the infinity-norm condition number is required:= 0: Infinity-norm.= 1: 1-norm;
Aβ the factorsLandUfrom the factorizationA = P*L*Uas computed bygetrf.anormβ ifnorm = 0, the infinity-norm of the original matrixA. ifnorm = 1, the 1-norm of the original matrixA. note: the original matrix, not the factors, iykykrcondβ the reciprocal of the condition number of the matrixA, computed asrcond = 1/(norm(A) * norm(inv(A))). the moment of truth β¨infoβ you already know:= 0: successful exit π< 0: ifinfo = -i, the i-th argument had an illegal value π
$a = random (float, 100, 100);
$anorm = $a->lange(1);
$ipiv = zeroes(long, 100);
$info = null;
getrf($a, $ipiv, $info);
($rcond, $info) = gecon($a, 1, $anorm) unless $info != 0;
and that's where this part lands bestie ππ
Also, real quick, one last thing about <code>gecon</code>: it ignores the bad-value flag of the input ndarrays π. But it will set the bad-value flag on all the output ndarrays if the flag is set for any of the input ndarrays. That's just how it do π
πΈ sycon πΈ
Signature: ([phys]A(n,n); int uplo(); int ipiv(n); [phys]anorm(); [o,phys]rcond();int [o,phys]info(); int [t]iwork(n); [t]work(workn))
So what it does is estimate the reciprocal of the condition number (in the 1-norm, bestie) of a real symmetric matrix A, using the factorization A = U*D*U' or A = L*D*L' that sytrf already computed for you β¨
It gets an estimate for norm(inv(A)), and then the reciprocal of the condition number is literally just rcond = 1 / (anorm * norm(inv(A))). Math girl summer π
π« Arguments π«
uploβ tells you whether the factorization details are stored as an upper or lower triangular matrix.= 0: Upper triangular, form isA = U*D*U';= 1: Lower triangular, form isA = L*D*L'.
Aβ the block diagonal matrix D and the multipliers used to get the factor U or L, exactly as computed bysytrf.ipivβ the details of the interchanges and the block structure of D, as determined bysytrf.anormβ the 1-norm of the original matrix A. iconic.rcondβ the reciprocal of the condition number of the matrix A, computed asrcond = 1/(anorm * aimvnm), whereainvnmis an estimate of the 1-norm ofinv(A)computed in this routine.infoβ the exit status:= 0: successful exit π< 0: ifinfo = -i, the i-th argument had an illegal value.
# Assume $a is symmetric
$a = random (float, 100, 100);
$anorm = $a->lansy(1,1);
$ipiv = zeroes(long, 100);
$info = null;
sytrf($a, 1,$ipiv, $info);
($rcond, $info) = sycon($a, 1, $anorm) unless $info != 0;
sycon ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. no cap π«Ά
π pocon π
Signature: (A(n,n); int uplo(); anorm(); [o]rcond();int [o]info(); int [t]iwork(n); [t]work(workn))
Estimates the reciprocal of the condition number (again in the 1-norm, we stay consistent) of a real symmetric positive definite matrix, using the Cholesky factorization A = U'*U or A = L*L' that potrf computed. obsessed with her honestly π
An estimate is obtained for norm(inv(A)), and the reciprocal of the condition number comes out as rcond = 1 / (anorm * norm(inv(A))). periodt.
π« Arguments π«
uploβ which triangle we're working with:= 0: Upper triangle of A is stored;= 1: Lower triangle of A is stored.
Aβ the triangular factor U or L from the Cholesky factorizationA = U'*UorA = L*L', as computed bypotrf.anormβ the 1-norm of the matrix A.rcondβ the reciprocal of the condition number of the matrix A, computed asrcond = 1/(anorm * ainvnm), whereainvnmis an estimate of the 1-norm ofinv(A)computed in this routine.infoβ the exit status:= 0: successful exit π< 0: ifinfo = -i, the i-th argument had an illegal value
# Assume $a is symmetric positive definite
$a = random (float, 100, 100);
$anorm = $a->lansy(1,1);
$info = null;
potrf($a, 0, $info);
($rcond, $info) = pocon($a, 1, $anorm) unless $info != 0;
pocon ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π
π¦ trcon π¦
Signature: (A(n,n); int norm();int uplo();int diag(); [o]rcond();int [o]info(); int [t]iwork(n); [t]work(workn))
Estimates the reciprocal of the condition number of a triangular matrix A β and you get to pick, either the 1-norm or the infinity-norm, main character choice fr fr β¨
The norm of A gets computed, an estimate is obtained for norm(inv(A)), and then the reciprocal of the condition number is computed as
rcond = 1 / ( norm(A) * norm(inv(A)) ).
π« Arguments π«
normβ picks whether you want the 1-norm condition number or the infinity-norm condition number:= 0: Infinity-norm.= 1: 1-norm;
uploβ where the triangle lives:= 0: A is upper triangular;= 1: A is lower triangular.
diagβ whether the diagonal is part of the deal:= 0: A is non-unit triangular;= 1: A is unit triangular.
Aβ the triangular matrix A. Ifuplo = 0, the leading N-by-N upper triangular part of the array A contains the upper triangular matrix, and the strictly lower triangular part of A is not referenced. Ifuplo = 1, the leading N-by-N lower triangular part of the array A contains the lower triangular matrix, and the strictly upper triangular part of A is not referenced. Ifdiag = 1, the diagonal elements of A are also not referenced and are assumed to be1. lowkey so much going on but we love her π«Άrcondβ the reciprocal of the condition number of the matrix A, computed asrcond = 1/(norm(A) * norm(inv(A))).infoβ the exit status:= 0: successful exit π< 0: ifinfo = -i, the i-th argument had an illegal value
# Assume $a is upper triangular
$a = random (float, 100, 100);
$info = null;
($rcond, $info) = trcon($a, 1, 1, 0) unless $info != 0;
trcon ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π
β geqp3 β
Signature: ([io,phys]A(m,n); int [io,phys]jpvt(n); [o,phys]tau(k); int [o,phys]info())
geqp3 computes a QR factorization using Level 3 BLAS with column pivoting of a matrix A:
A*P = Q*R
The matrix Q is represented as a product of elementary reflectors
Q = H(1) H(2) . . . H(k), where k = min(m,n).
Each H(i) has the form
H(i) = I - tau * v * v'
where tau is a real/complex scalar, and v is a real/complex vector
with v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in
A(i+1:m,i), and tau in tau(i).
π« Arguments π«
Aβ on entry, the M-by-N matrix A. On exit, the upper triangle of the array contains themin(M,N)-by-N upper trapezoidal matrix R; the elements below the diagonal, together with the arraytau, represent the orthogonal matrix Q as a product ofmin(M,N)elementary reflectors. glow up β¨jpvtβ on entry, ifjpvt(J)!=0, the J-th column of A is permuted to the front ofA*P(a leading column); ifjpvt(J)=0, the J-th column of A is a free column. On exit, ifjpvt(J)=K, then the J-th column ofA*Pwas the the K-th column of A. (yes, "the the" β we keep it exactly as written, iykyk π)tauβ the scalar factors of the elementary reflectors.infoβ the exit status:= 0: successful exit.< 0: ifinfo = -i, the i-th argument had an illegal value.
$a = random (float, 100, 50);
$info = null;
$tau = zeroes(float, 50);
$jpvt = zeroes(long, 50);
geqp3($a, $jpvt, $tau, $info);
geqp3 ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π
π geqrf π
Signature: ([io,phys]A(m,n); [o,phys]tau(k); int [o,phys]info())
geqrf computes a QR factorization of a matrix A:
A = Q * R
The matrix Q is represented as a product of elementary reflectors
Q = H(1) H(2) . . . H(k), where k = min(m,n).
Each H(i) has the form
H(i) = I - tau * v * v'
where tau is a real/complex scalar, and v is a real/complex vector
with v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in
A(i+1:m,i), and tau in tau(i).
π« Arguments π«
Aβ on exit, the elements on and above the diagonal of the array contain themin(M,N)-by-N upper trapezoidal matrix R (R is upper triangular ifm >= n); the elements below the diagonal, with the arrayTAU, represent the orthogonal matrix Q as a product ofmin(m,n)elementary reflectors. she ate π₯tauβ the scalar factors of the elementary reflectors.infoβ the exit status:= 0: successful exit.< 0: ifinfo = -i, the i-th argument had an illegal value.
$a = random (float, 100, 50);
$info = null;
$tau = zeroes(float, 50);
geqrf($a, $tau, $info);
geqrf ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π«Ά
π§ orgqr π§
Signature: ([io,phys]A(m,n); [phys]tau(k); int [o,phys]info())
Generates an M-by-N real matrix Q with orthonormal columns, defined as the first N columns of a product of K elementary reflectors of order M
Q = H(1) H(2) . . . H(k)
as returned by geqrf or geqp3.
π« Arguments π«
Aβ on entry, the i-th column must contain the vector which defines the elementary reflector H(i), fori = 1,2,...,k, as returned bygeqrforgeqp3in the first k columns of its array argument A. On exit, the M-by-N matrix Q. the glow up is real πtauβtau(i)must contain the scalar factor of the elementary reflector H(i), as returned bygeqrforgeqp3.infoβ the exit status:= 0: successful exit< 0: ifinfo = -i, the i-th argument has an illegal value
$a = random (float, 100, 50);
$info = null;
$tau = zeroes(float, 50);
geqrf($a, $tau, $info);
orgqr($a, $tau, $info) unless $info != 0;
orgqr ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. β¨
π ormqr π
Signature: ([phys]A(p,k); int side(); int trans(); [phys]tau(k); [io,phys]C(m,n);int [o,phys]info())
Overwrites the general real M-by-N matrix C with
side = 0 side = 1
trans = 0: Q * C C * Q
trans = 1: Q' * C C * Q'
where Q is a real orthogonal matrix defined as the product of k elementary reflectors
Q = H(1) H(2) . . . H(k)
as returned by geqrf or geqp3.
Q is of order M if side = 0 and of order N if side = 1. know the difference bestie, it matters π
π« Arguments π«
sideβ which side we're applying from:= 0: apply Q or Q' from the Left;= 1: apply Q or Q' from the Right.
transβ transpose or nah:= 0: No transpose, apply Q;= 1: Transpose, apply Q'.
Aβ the i-th column must contain the vector which defines the elementary reflector H(i), fori = 1,2,...,k, as returned bygeqrforgeqp3in the first k columns of its array argument A. A is modified by the routine but restored on exit. she's changed but she comes back, growth π±tauβtau(i)must contain the scalar factor of the elementary reflector H(i), as returned bygeqrforgeqp3.Cβ ok so on the way in, this is your M-by-N matrix C π«Ά. On the way out? It's been fully overwritten byQ*CorQ'*CorC*Q'orC*Q. No takebacks, bestie, C is a β¨changed matrixβ¨ now.infoβ the receipts, pls read them:= 0: successful exit π< 0: ifinfo = -i, the i-th argument had an illegal value π
Like, here's the whole vibe in code, bestie:
$a = random (float, 50, 100);
$a = transpose($a);
$info = null;
$tau = zeroes(float, 50);
geqrf($a, $tau, $info);
$c = random(70,50);
# $c will contain the result
$c->reshape(70,100);
$c = transpose($c);
ormqr($a, $tau, $c, $info);
And one thing you gotta know: ormqr ignores the bad-value flag of the input ndarrays. But it will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. So it's giving "I don't check, but I do tell" energy, lowkey iconic π
πΈ gelqf πΈ
Signature: ([io,phys]A(m,n); [o,phys]tau(k); int [o,phys]info())
Bestie, this one computes an LQ factorization of a real M-by-N matrix A:
A = L * Q.
The matrix Q is represented as a product of elementary reflectors
Q = H(k) . . . H(2) H(1), where k = min(m,n).
Each H(i) has the form
H(i) = I - tau * v * v'
where tau is a real scalar, and v is a real vector with v(1:i-1) = 0 and v(i) = 1; v(i+1:n) is stored on exit in A(i,i+1:n), and tau in tau(i). Periodt π
π Arguments
Aβ on entry, the M-by-N matrix A. On exit, the elements on and below the diagonal of the array contain them-by-min(m,n)lower trapezoidal matrix L (L is lower triangular ifm <= n); the elements above the diagonal, with the arraytau, represent the orthogonal matrix Q as a product of elementary reflectors. So basically A gets a β¨glow-upβ¨.tauβ the scalar factors of the elementary reflectors.infoβ the receipts:= 0: successful exit< 0: ifinfo = -i, the i-th argument had an illegal value
Here's how you'd actually call it, no cap:
$a = random (float, 100, 50);
$info = null;
$tau = zeroes(float, 50);
gelqf($a, $tau, $info);
gelqf ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. Same energy as before, fr fr π¦
π orglq π
Signature: ([io,phys]A(m,n); [phys]tau(k); int [o,phys]info())
This one generates an M-by-N real matrix Q with orthonormal rows π, defined as the first M rows of a product of K elementary reflectors of order N
Q = H(k) . . . H(2) H(1)
as returned by gelqf.
π Arguments
Aβ on entry, the i-th row must contain the vector which defines the elementary reflectorH(i), fori = 1,2,...,k, as returned bygelqfin the first k rows of its array argumentA. On exit, the M-by-N matrix Q. Main character transformation, honestly β¨tauβtau(i)must contain the scalar factor of the elementary reflectorH(i), as returned bygelqf.infoβ the receipts:= 0: successful exit< 0: ifinfo = -i, the i-th argument has an illegal value
Watch how these two team up, it's giving collab:
$a = random (float, 100, 50);
$info = null;
$tau = zeroes(float, 50);
gelqf($a, $tau, $info);
orglq($a, $tau, $info) unless $info != 0;
orglq ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π
π ormlq π
Signature: ([phys]A(k,p); int side(); int trans(); [phys]tau(k); [io,phys]C(m,n);int [o,phys]info())
Overwrites the general real M-by-N matrix C with
side = 0 side = 1
trans = 0: Q * C C * Q
trans = 1: Q' * C C * Q'
where Q is a real orthogonal matrix defined as the product of k elementary reflectors
Q = H(k) . . . H(2) H(1)
as returned by gelqf.
Q is of order M if "side" = 0 and of order N if "side" = 1. Slay π
π Arguments
sideβ which way we're applying it:= 0: apply Q or Q' from the Left;= 1: apply Q or Q' from the Right.
transβ transpose or nah:= 0: No transpose, apply Q;= 1: Transpose, apply Q'.
Aβ the i-th row must contain the vector which defines the elementary reflectorH(i), fori = 1,2,...,k, as returned bygelqfin the first k rows of its array argumentA. Heads up tho: A is modified by the routine but restored on exit π so don't panic, it comes back.tauβtau(i)must contain the scalar factor of the elementary reflectorH(i), as returned bygelqf.Cβ on entry, the M-by-N matrix C. On exit, C is overwritten byQ*CorQ'*CorC*Q'orC*Q.infoβ the receipts:= 0: successful exit< 0: ifinfo = -i, the i-th argument had an illegal value
Example time, bestie:
$a = random (float, 50, 100);
$a = transpose($a);
$info = null;
$tau = zeroes(float, 50);
gelqf($a, $tau, $info);
$c = random(70,50);
# $c will contain the result
$c->reshape(70,100);
$c = transpose($c);
ormlq($a, $tau, $c, $info);
ormlq ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π
β geqlf β
Signature: ([io,phys]A(m,n); [o,phys]tau(k); int [o,phys]info())
Computes a QL factorization of a real M-by-N matrix A:
A = Q * L
The matrix Q is represented as a product of elementary reflectors
Q = H(k) . . . H(2) H(1), where k = min(m,n).
Each H(i) has the form
H(i) = I - tau * v * v'
where tau is a real scalar, and v is a real vector with v(m-k+i+1:m) = 0 and v(m-k+i) = 1; v(1:m-k+i-1) is stored on exit in A(1:m-k+i-1,n-k+i), and tau in TAU(i). Yes, the capitalization switched, that's literally how it's written, don't come for me π
π Arguments
Aβ on entry, the M-by-N matrix A. On exit:- if
m >= n, the lower triangle of the subarrayA(m-n+1:m,1:n)contains the N-by-N lower triangular matrix L; - if
m <= n, the elements on and below the (n-m)-th superdiagonal contain the M-by-N lower trapezoidal matrix L; - the remaining elements, with the array
tau, represent the orthogonal matrix Q as a product of elementary reflectors.
- if
tauβ the scalar factors of the elementary reflectors.infoβ the receipts:= 0: successful exit< 0: ifinfo = -i, the i-th argument had an illegal value
Run it like this:
$a = random (float, 100, 50);
$info = null;
$tau = zeroes(float, 50);
geqlf($a, $tau, $info);
geqlf ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. πΈ
π orgql π
Signature: ([io,phys]A(m,n); [phys]tau(k); int [o,phys]info())
Generates an M-by-N real matrix Q with orthonormal columns, defined as the last N columns of a product of K elementary reflectors of order M
Q = H(k) . . . H(2) H(1)
as returned by geqlf.
π Arguments
Aβ on entry, the(n-k+i)-th column must contain the vector which defines the elementary reflectorH(i), fori = 1,2,...,k, as returned bygeqlfin the last k columns of its array argumentA. On exit, the M-by-N matrix Q. Glow up, babes β¨tauβtau(i)must contain the scalar factor of the elementary reflectorH(i), as returned bygeqlf.infoβ the receipts:= 0: successful exit< 0: ifinfo = -i, the i-th argument has an illegal value
Bestie duo behaviour:
$a = random (float, 100, 50);
$info = null;
$tau = zeroes(float, 50);
geqlf($a, $tau, $info);
orgql($a, $tau, $info) unless $info != 0;
orgql ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π§
π₯ ormql π₯
Signature: ([phys]A(p,k); int side(); int trans(); [phys]tau(k); [io,phys]C(m,n);int [o,phys]info())
Overwrites the general real M-by-N matrix C with
side = 0 side = 1
trans = 0: Q * C C * Q
trans = 1: Q' * C C * Q'
where Q is a real orthogonal matrix defined as the product of k elementary reflectors
Q = H(k) . . . H(2) H(1)
as returned by geqlf.
Q is of order M if "side" = 0 and of order N if "side" = 1. Same deal as ormlq, just a different parent routine, iykyk π«Ά
π Arguments
sideβ pick a side:= 0: apply Q or Q' from the Left;= 1: apply Q or Q' from the Right.
transβ transpose check:= 0: No transpose, apply Q;= 1: Transpose, apply Q'.
Aβ the i-th row must contain the vector which defines the elementary reflectorH(i), fori = 1,2,...,k, as returned bygeqlfin the last k rows of its array argumentA. And again: A is modified by the routine but restored on exit, so it's fine, it's fine πtauβtau(i)must contain the scalar factor of the elementary reflectorH(i), as returned bygeqlf.Cβ on entry, the M-by-N matrix C. On exit, C is overwritten byQ*CorQ'*CorC*Q'orC*Q.infoβ the receipts:= 0: successful exit< 0: ifinfo = -i, the i-th argument had an illegal value
Example incoming:
$a = random (float, 50, 100);
$a = transpose($a);
$info = null;
$tau = zeroes(float, 50);
geqlf($a, $tau, $info);
$c = random(70,50);
# $c will contain the result
$c->reshape(70,100);
$c = transpose($c);
ormql($a, $tau, $c, $info);
ormql ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π
π¦ gerqf π¦
Signature: ([io,phys]A(m,n); [o,phys]tau(k); int [o,phys]info())
Computes an RQ factorization of a real M-by-N matrix A:
A = R * Q.
The matrix Q is represented as a product of elementary reflectors
Q = H(1) H(2) . . . H(k), where k = min(m,n).
Notice the order flipped? Yeah. It's H(1) H(2) . . . H(k) this time, not the other way round. The way this routine said "we do things differently here" π
Each H(i) has the form
H(i) = I - tau * v * v'
where tau is a real scalar, and v is a real vector with v(n-k+i+1:n) = 0 and v(n-k+i) = 1; v(1:n-k+i-1) is stored on exit in A(m-k+i,1:n-k+i-1), and tau in TAU(i).
π Arguments
Aβ on entry, the M-by-N matrix A. On exit:- if
m <= n, the upper triangle of the subarrayA(1:m,n-m+1:n)contains the M-by-M upper triangular matrix R; - if
m >= n, the elements on and above the (m-n)-th subdiagonal contain the M-by-N upper trapezoidal matrix R; - the remaining elements, with the array
tau, represent the orthogonal matrix Q as a product ofmin(m,n)elementary reflectors (see Further Details).
- if
tauβ the scalar factors of the elementary reflectors.infoβ the receipts:= 0: successful exit< 0: ifinfo = -i, the i-th argument had an illegal value
$a = random (float, 100, 50);
$info = null;
$tau = zeroes(float, 50);
gerqf($a, $tau, $info);
and yeah β gerqf ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π
π¦ orgrq π¦
Signature: ([io,phys]A(m,n); [phys]tau(k); int [o,phys]info())
okay so this one generates an M-by-N real matrix Q with orthonormal rows, and it's defined as the last M rows of a product of K elementary reflectors of order N, bestie:
Q = H(1) H(2) . . . H(k)
as returned by gerqf. β¨
π Arguments π
Aβ On entry, the(m-k+i)-th row must contain the vector which defines the elementary reflectorH(i), fori = 1,2,...,k, as returned bygerqfin the lastkrows of its array argumentA. On exit, the M-by-N matrixQ. πtauβtau(i)must contain the scalar factor of the elementary reflectorH(i), as returned bygerqf.infoβ= 0: successful exit.< 0: ifinfo = -i, thei-th argument has an illegal value. π
$a = random (float, 100, 50);
$info = null;
$tau = zeroes(float, 50);
gerqf($a, $tau, $info);
orgrq($a, $tau, $info) unless $info != 0;
orgrq ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π«Ά
πΈ ormrq πΈ
Signature: ([phys]A(k,p); int side(); int trans(); [phys]tau(k); [io,phys]C(m,n);int [o,phys]info())
this one overwrites the general real M-by-N matrix C with β vibe check the little grid:
side = 0 side = 1
trans = 0: Q * C C * Q
trans = 1: Q' * C C * Q'
where Q is a real orthogonal matrix defined as the product of k elementary reflectors
Q = H(1) H(2) . . . H(k)
as returned by gerqf. β¨
Q is of order M if "side" = 0 and of order N if "side" = 1. periodt.
π Arguments π
sideβ= 0: applyQorQ'from the Left;= 1: applyQorQ'from the Right. πtransβ= 0: No transpose, applyQ;= 1: Transpose, applyQ'. πAβ Thei-th row must contain the vector which defines the elementary reflectorH(i), fori = 1,2,...,k, as returned bygerqfin the lastkrows of its array argumentA.Ais modified by the routine but restored on exit. πtauβtau(i)must contain the scalar factor of the elementary reflectorH(i), as returned bygerqf.Cβ On entry, the M-by-N matrixC. On exit,Cis overwritten byQ*CorQ'*CorC*Q'orC*Q. π¦infoβ= 0: successful exit.< 0: ifinfo = -i, thei-th argument had an illegal value. π
$a = random (float, 50, 100);
$a = transpose($a);
$info = null;
$tau = zeroes(float, 50);
gerqf($a, $tau, $info);
$c = random(70,50);
# $c will contain the result
$c->reshape(70,100);
$c = transpose($c);
ormrq($a, $tau, $c, $info);
ormrq ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π
β tzrzf β
Signature: ([io,phys]A(m,n); [o,phys]tau(k); int [o,phys]info())
so basically this one reduces the M-by-N ( M <= N ) real upper trapezoidal matrix A to upper triangular form by means of orthogonal transformations. π
The upper trapezoidal matrix A is factored as
A = ( R 0 ) * Z,
where Z is an N-by-N orthogonal matrix and R is an M-by-M upper triangular matrix. slay.
The factorization is obtained by Householder's method. The kth transformation matrix, Z( k ), which is used to introduce zeros into the ( m - k + 1 )th row of A, is given in the form
Z( k ) = ( I 0 ),
( 0 T( k ) )
where
T( k ) = I - tau*u( k )*u( k )', u( k ) = ( 1 ),
( 0 )
( z( k ) )
tau is a scalar and z( k ) is an ( n - m ) element vector. tau and z( k ) are chosen to annihilate the elements of the kth row of X. π
The scalar tau is returned in the kth element of "tau" and the vector u( k ) in the kth row of A, such that the elements of z( k ) are in a( k, m + 1 ), ..., a( k, n ). The elements of R are returned in the upper triangular part of A. π
Z is given by
Z = Z( 1 ) * Z( 2 ) * ... * Z( m ).
π Arguments π
Aβ On entry, the leading M-by-N upper trapezoidal part of the arrayAmust contain the matrix to be factorized. On exit, the leading M-by-M upper triangular part ofAcontains the upper triangular matrixR, and elementsM+1toNof the firstMrows ofA, with the arraytau, represent the orthogonal matrixZas a product ofMelementary reflectors. πtauβ The scalar factors of the elementary reflectors.infoβ= 0: successful exit.< 0: ifinfo = -i, thei-th argument had an illegal value. π
$a = random (float, 50, 100);
$info = null;
$tau = zeroes(float, 50);
tzrzf($a, $tau, $info);
tzrzf ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π«Ά
π ormrz π
Signature: ([phys]A(k,p); int side(); int trans(); [phys]tau(k); [io,phys]C(m,n);int [o,phys]info())
okay bestie, this one overwrites the general real M-by-N matrix C with
side = 0 side = 1
trans = 0: Q * C C * Q
trans = 1: Q' * C C * Q'
where Q is a real orthogonal matrix defined as the product of k elementary reflectors
Q = H(1) H(2) . . . H(k)
as returned by tzrzf. β¨
Q is of order M if "side" = 0 and of order N if "side" = 1. no cap.
π Arguments π
sideβ= 0: applyQorQ'from the Left;= 1: applyQorQ'from the Right. πtransβ= 0: No transpose, applyQ;= 1: Transpose, applyQ'. πAβ Thei-th row must contain the vector which defines the elementary reflectorH(i), fori = 1,2,...,k, as returned bytzrzfin the lastkrows of its array argumentA.Ais modified by the routine but restored on exit. πtauβtau(i)must contain the scalar factor of the elementary reflectorH(i), as returned bytzrzf.Cβ On entry, the M-by-N matrixC. On exit,Cis overwritten byQ*CorQ'*CorC*Q'orC*Q. π¦infoβ= 0: successful exit.< 0: ifinfo = -i, thei-th argument had an illegal value. π
$a = random (float, 50, 100);
$a = transpose($a);
$info = null;
$tau = zeroes(float, 50);
tzrzf($a, $tau, $info);
$c = random(70,50);
# $c will contain the result
$c->reshape(70,100);
$c = transpose($c);
ormrz($a, $tau, $c, $info);
ormrz ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π
π gehrd π
Signature: ([io,phys]A(n,n); int [phys]ilo();int [phys]ihi();[o,phys]tau(k); int [o,phys]info())
this one reduces a real general matrix A to upper Hessenberg form H by an orthogonal similarity transformation:
Q' * A * Q = H .
iconic behaviour honestly. β¨
π Further Details π
The matrix Q is represented as a product of (ihi-ilo) elementary reflectors
Q = H(ilo) H(ilo+1) . . . H(ihi-1).
Each H(i) has the form
H(i) = I - tau * v * v'
where tau is a real scalar, and v is a real vector with
v(1:i) = 0, v(i+1) = 1 and v(ihi+1:n) = 0; v(i+2:ihi) is stored on
exit in A(i+2:ihi,i), and tau in tau(i).
The contents of A are illustrated by the following example, with n = 7, ilo = 2 and ihi = 6:
on entry, on exit,
( a a a a a a a ) ( a a h h h h a )
( a a a a a a ) ( a h h h h a )
( a a a a a a ) ( h h h h h h )
( a a a a a a ) ( v2 h h h h h )
( a a a a a a ) ( v2 v3 h h h h )
( a a a a a a ) ( v2 v3 v4 h h h )
( a ) ( a )
where a denotes an element of the original matrix A, h denotes a
modified element of the upper Hessenberg matrix H, and vi denotes an
element of the vector defining H(i).
π Arguments π
ilo,ihiβ It is assumed thatAis already upper triangular in rows and columns1:ilo-1andihi+1:N.iloandihiare normally set by a previous call togebal; otherwise they should be set to1andNrespectively. See Further Details.1 <= ilo <= ihi <= N, if N > 0; ilo=1 and ihi=0, if N=0.πΈAβ On entry, the N-by-N general matrix to be reduced. On exit, the upper triangle and the first subdiagonal ofAare overwritten with the upper Hessenberg matrixH, and the elements below the first subdiagonal, with the arraytau, represent the orthogonal matrixQas a product of elementary reflectors. See Further Details. πtauβ The scalar factors of the elementary reflectors (see Further Details). Elements1:ilo-1andihi:N-1oftauare set to zero. (dimension(N-1)) πinfoβ= 0: successful exit.< 0: ifinfo = -i, thei-th argument had an illegal value. π
$a = random (50, 50);
$info = null;
$tau = zeroes(50);
gehrd($a, 1, 50, $tau, $info);
gehrd ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π«Ά
π§ orghr π§
Signature: ([io,phys]A(n,n); int [phys]ilo();int [phys]ihi();[phys]tau(k); int [o,phys]info())
generates a real orthogonal matrix Q which is defined as the product of ihi-ilo elementary reflectors of order N, as returned by "gehrd":
Q = H(ilo) H(ilo+1) . . . H(ihi-1).
π Arguments π
ilo,ihiβiloandihimust have the same values as in the previous call ofgehrd.Qis equal to the unit matrix except in the submatrixQ(ilo+1:ihi,ilo+1:ihi).1 <= ilo <= ihi <= N, if N > 0; ilo=1 and ihi=0, if N=0.πΈAβ On entry, the vectors which define the elementary reflectors, as returned bygehrd. On exit, theN-by-Northogonal matrixQ. Itβs giving orthogonal realness. β¨tauβtau(i)must contain the scalar factor of the elementary reflectorH(i), as returned bygehrd. (dimension(N-1)) πinfoβ= 0: successful exit;< 0: ifinfo = -i, thei-th argument had an illegal value. so if itβs negative, something went wrong, bestie π
$a = random (50, 50);
$info = null;
$tau = zeroes(50);
gehrd($a, 1, 50, $tau, $info);
orghr($a, 1, 50, $tau, $info);
orghr literally ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. iykyk π«Ά
hseqr π
okay so hseqr computes the eigenvalues of a real upper Hessenberg matrix H and, optionally, the matrices T and Z from the Schur decomposition H = Z T Z**T, where T is an upper quasi-triangular matrix (the Schur form), and Z is the orthogonal matrix of Schur vectors. main character energy π
Optionally Z may be postmultiplied into an input orthogonal 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 orthogonal matrix Q: A = Q*H*Q**T = (QZ)*T*(QZ)**T. no cap.
Arguments π
jobβ= 0: compute eigenvalues only;= 1: compute eigenvalues and the Schur formT. simple as that β¨compzβ= 0: no Schur vectors are computed;= 1:Zis initialized to the unit matrix and the matrixZof Schur vectors ofHis returned;= 2:Zmust contain an orthogonal matrixQon entry, and the productQ*Zis returned. choose your fighter πilo,ihiβ It is assumed thatHis already upper triangular in rows and columns1:ilo-1andihi+1:N.iloandihiare normally set by a previous call togebal, and then passed togehrdwhen the matrix output bygebalis reduced to Hessenberg form. Otherwiseiloandihishould be set to1andNrespectively.1 <= ilo <= ihi <= N, ifN > 0;ilo=1andihi=0, ifN=0. the boundaries, bestie π¦Hβ On entry, the upper Hessenberg matrixH. On exit, ifjob = 1,Hcontains the upper quasi-triangular matrixTfrom the Schur decomposition (the Schur form);2-by-2diagonal blocks (corresponding to complex conjugate pairs of eigenvalues) are returned in standard form, withH(i,i) = H(i+1,i+1)andH(i+1,i)*H(i,i+1) < 0. Ifjob = 0, the contents ofHare unspecified on exit. unspecified means donβt trust it, periodt πwr,wiβ The real and imaginary parts, respectively, of the computed eigenvalues. If two eigenvalues are computed as a complex conjugate pair, they are stored in consecutive elements ofwrandwi, say thei-th and(i+1)th, withwi(i) > 0andwi(i+1) < 0. Ifjob = 1, the eigenvalues are stored in the same order as on the diagonal of the Schur form returned inH, withwr(i) = H(i,i)and, ifH(i:i+1,i:i+1)is a2-by-2diagonal block,wi(i) = sqrt(H(i+1,i)*H(i,i+1))andwi(i+1) = -wi(i). math girlies rise π§Zβ Ifcompz = 0:Zis not referenced. Ifcompz = 1: on entry,Zneed not be set, and on exit,Zcontains the orthogonal matrixZof the Schur vectors ofH. Ifcompz = 2: on entryZmust contain anN-by-NmatrixQ, which is assumed to be equal to the unit matrix except for the submatrixZ(ilo:ihi,ilo:ihi); on exitZcontainsQ*Z. NormallyQis the orthogonal matrix generated byorghrafter the call togehrdwhich formed the Hessenberg matrixH. the lore πinfoβ= 0: successful exit;< 0: ifinfo = -i, thei-th argument had an illegal value;> 0: ifinfo = i,hseqrfailed to compute all of the eigenvalues in a total of30*(ihi-ilo+1)iterations; elements1:ilo-1andi+1:nofwrandwicontain those eigenvalues which have been successfully computed. read the fine print π
$a = random (50, 50);
$info = null;
$tau = zeroes(50);
$z= zeroes(1,1);
gehrd($a, 1, 50, $tau, $info);
hseqr($a,0,0,1,50,($wr=null),($wi=null),$z,$info);
hseqr ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. fr fr π«Ά
trevc π¦
okay so trevc computes some or all of the right and/or left eigenvectors of a real upper quasi-triangular matrix T. eigenvector era π
so the right eigenvector x and the left eigenvector y of T for an eigenvalue w are defined like this:
T*x = w*x, y'*T = w*y'
where y' denotes the conjugate transpose of the vector y.
If all eigenvectors are requested, the routine may either return the matrices X and/or Y of right or left eigenvectors of T, or the products Q*X and/or Q*Y, where Q is an input orthogonal matrix. If T was obtained from the real-Schur factorization of an original matrix A = Q*T*Q', then Q*X and Q*Y are the matrices of right or left eigenvectors of A. itβs giving decomposition realness β¨
T has to be in Schur canonical form (like what hseqr returns), meaning block upper triangular with 1-by-1 and 2-by-2 diagonal blocks; each 2-by-2 diagonal block has its diagonal elements equal and its off-diagonal elements of opposite sign. Corresponding to each 2-by-2 diagonal block is a complex conjugate pair of eigenvalues and eigenvectors; only one eigenvector of the pair is computed, namely the one corresponding to the eigenvalue with positive imaginary part. only one, bestie π
Further Details π
The algorithm used in this program is basically backward (forward) substitution, with scaling to make the code robust against possible overflow. scaling for safety π‘οΈ
Each eigenvector is normalized so that the element of largest magnitude has magnitude 1; here the magnitude of a complex number (x,y) is taken to be |x| + |y|. normalize and serve π
Arguments π
sideβ= 0: compute both right and left eigenvectors;= 1: compute right eigenvectors only;= 2: compute left eigenvectors only. pick a side, literally πhowmnyβ= 0: compute all right and/or left eigenvectors;= 1: compute all right and/or left eigenvectors, and backtransform them using the input matrices supplied inVRand/orVL;= 2: compute selected right and/or left eigenvectors, specified by the logical arrayselect. so many options β¨selectβ Ifhowmny = 2,selectspecifies the eigenvectors to be computed. Ifhowmny = 0or1,selectis not referenced. To select the real eigenvector corresponding to a real eigenvaluew(j),select(j)must be set toTRUE. To select the complex eigenvector corresponding to a complex conjugate pairw(j)andw(j+1), eitherselect(j)orselect(j+1)must be set toTRUE; then on exitselect(j)isTRUEandselect(j+1)isFALSE. TRUE/FALSE drama πTβ The upper quasi-triangular matrixTin Schur canonical form. canonical queen πVLβ On entry, ifside = 2or0andhowmny = 1,VLmust contain anN-by-NmatrixQ(usually the orthogonal matrixQof Schur vectors returned byhseqr). On exit, ifside = 2or0,VLcontains: ifhowmny = 0, the matrixYof left eigenvectors ofT;VLhas the same quasi-lower triangular form asT'. IfT(i,i)is a real eigenvalue, then thei-th columnVL(i)ofVLis its corresponding eigenvector. IfT(i:i+1,i:i+1)is a2-by-2block whose eigenvalues are complex-conjugate eigenvalues ofT, thenVL(i)+sqrt(-1)*VL(i+1)is the complex eigenvector corresponding to the eigenvalue with positive real part. ifhowmny = 1, the matrixQ*Y; ifhowmny = 2, the left eigenvectors ofTspecified byselect, stored consecutively in the columns ofVL, in the same order as their eigenvalues. A complex eigenvector corresponding to a complex eigenvalue is stored in two consecutive columns, the first holding the real part, and the second the imaginary part. Ifside = 1,VLis not referenced. left side represent πVRβ On entry, ifside = 1or0andhowmny = 1,VRmust contain anN-by-NmatrixQ(usually the orthogonal matrixQof Schur vectors returned byhseqr). On exit, ifside = 1or0,VRcontains: ifhowmny = 0, the matrixXof right eigenvectors ofT;VRhas the same quasi-upper triangular form asT. IfT(i,i)is a real eigenvalue, then thei-th columnVR(i)ofVRis its corresponding eigenvector. IfT(i:i+1,i:i+1)is a2-by-2block whose eigenvalues are complex-conjugate eigenvalues ofT, thenVR(i)+sqrt(-1)*VR(i+1)is the complex eigenvector corresponding to the eigenvalue with positive real part. ifhowmny = 1, the matrixQ*X; ifhowmny = 2, the right eigenvectors ofTspecified byselect, stored consecutively in the columns ofVR, in the same order as their eigenvalues. A complex eigenvector corresponding to a complex eigenvalue is stored in two consecutive columns, the first holding the real part and the second the imaginary part. Ifside = 2,VRis not referenced. right side represent πmβ The number of columns in the arraysVLand/orVRactually used to store the eigenvectors. Ifhowmny = 0or1,mis set toN. Each selected real eigenvector occupies one column and each selected complex eigenvector occupies two columns. counting columns, periodt β¨infoβ= 0: successful exit;< 0: ifinfo = -i, thei-th argument had an illegal value. check it bestie π
$a = random (50, 50);
$info = null;
$tau = zeroes(50);
$z= zeroes(1,1);
gehrd($a, 1, 50, $tau, $info);
hseqr($a,0,0,1,50,($wr=null),($wi=null),$z,$info);
okay so trevc literally does not care about the bad-value flag on the ndarrays you feed it π β like, it just ignores it. But it will set the bad-value flag on all its output ndarrays if the flag is set on any of the input ndarrays. so if you send in one messy flag, bestie, it comes right back out the other side π
tgevc π
Signature: ([io]A(n,n); int side();int howmny();[io]B(n,n);int select(q);[o]VL(m,m); [o]VR(p,p);int [o]m(); int [o]info(); [t]work(workn))
So this one computes some or all of the right and/or left generalized eigenvectors of a pair of real upper triangular matrices (A,B). iconic behavior honestly β¨
The right generalized eigenvector x and the left generalized eigenvector y of (A,B) that correspond to a generalized eigenvalue w are defined like this:
(A - wB) * x = 0 and y**H * (A - wB) = 0
where y**H denotes the conjugate transpose of y.
If an eigenvalue w is determined by zero diagonal elements of both A and B, then a unit vector is returned as the corresponding eigenvector. π«Ά
If you ask for all the eigenvectors, the routine may either hand you the matrices X and/or Y of right or left eigenvectors of (A,B), or the products Z*X and/or Q*Y, where Z and Q are input orthogonal matrices. And if (A,B) came from the generalized real-Schur factorization of an original pair of matrices
(A0,B0) = (Q*A*Z**H,Q*B*Z**H),
then Z*X and Q*Y are the matrices of right or left eigenvectors of A. π
Heads up though: A must be block upper triangular, with 1-by-1 and 2-by-2 diagonal blocks. Corresponding to each 2-by-2 diagonal block is a complex conjugate pair of eigenvalues and eigenvectors; only one eigenvector of the pair gets computed, namely the one corresponding to the eigenvalue with positive imaginary part. no cap. π
Arguments
sideβ= 0: compute both right and left eigenvectors;= 1: compute right eigenvectors only;= 2: compute left eigenvectors only.howmnyβ= 0: compute all right and/or left eigenvectors;= 1: compute all right and/or left eigenvectors, and backtransform them using the input matrices supplied inVRand/orVL;= 2: compute selected right and/or left eigenvectors, specified by the logical arrayselect.selectβ Ifhowmny=2,selectspecifies the eigenvectors to be computed. Ifhowmny=0or1,selectis not referenced. To select the real eigenvector corresponding to the real eigenvaluew(j),select(j)must be set toTRUE. To select the complex eigenvector corresponding to a complex conjugate pairw(j)andw(j+1), eitherselect(j)orselect(j+1)must be set toTRUE. πAβ The upper quasi-triangular matrixA.Bβ The upper triangular matrixB. IfAhas a 2-by-2 diagonal block, then the corresponding 2-by-2 block ofBmust be diagonal with positive elements.VLβ On entry, ifside = 2or0andhowmny = 1,VLmust contain an N-by-N matrixQ(usually the orthogonal matrixQof left Schur vectors returned byhgqez). On exit, ifside = 2or0,VLcontains:- if
howmny = 0, the matrixYof left eigenvectors of(A,B); - if
howmny = 1, the matrixQ*Y; - if
howmny = 2, the left eigenvectors of(A,B)specified byselect, stored consecutively in the columns ofVL, in the same order as their eigenvalues.
- if
If side = 1, VL is not referenced.
A complex eigenvector corresponding to a complex eigenvalue is stored in two consecutive columns, the first holding the real part, and the second the imaginary part. πΈ
VRβ On entry, ifside = 1or0andhowmny = 1,VRmust contain an N-by-N matrixQ(usually the orthogonal matrixZof right Schur vectors returned byhgeqz). On exit, ifside = 1or0,VRcontains:- if
howmny = 0, the matrixXof right eigenvectors of(A,B); - if
howmny = 1, the matrixZ*X; - if
howmny = 2, the right eigenvectors of(A,B)specified byselect, stored consecutively in the columns ofVR, in the same order as their eigenvalues.
- if
If side = 2, VR is not referenced.
A complex eigenvector corresponding to a complex eigenvalue is stored in two consecutive columns, the first holding the real part and the second the imaginary part. π¦
Mβ The number of columns in the arraysVLand/orVRactually used to store the eigenvectors. Ifhowmny = 0or1,Mis set toN. Each selected real eigenvector occupies one column and each selected complex eigenvector occupies two columns.infoβ= 0: successful exit.< 0: ifinfo = -i, the i-th argument had an illegal value.> 0: the 2-by-2 block(info:info+1)does not have a complex eigenvalue. π
=for example
$a = random (50, 50);
$info = null;
$tau = zeroes(50);
$z= zeroes(1,1);
gehrd($a, 1, 50, $tau, $info);
hseqr($a,0,0,1,50,($wr=null),($wi=null),$z,$info);
tgevc ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π«Ά
gebal π
Signature: ([io,phys]A(n,n); int job(); int [o,phys]ilo();int [o,phys]ihi();[o,phys]scale(n); int [o,phys]info())
This one balances a general real matrix A. what does that even mean bestie? okay so it's two steps. first, it permutes A by a similarity transformation to isolate eigenvalues in the first 1 to ilo-1 and last ihi+1 to N elements on the diagonal. and second, it applies a diagonal similarity transformation to rows and columns ilo to ihi to make the rows and columns as close in norm as possible. both steps are optional, so you can pick and choose. π
Balancing may reduce the 1-norm of the matrix, and improve the accuracy of the computed eigenvalues and/or eigenvectors. so likeβ¦ it's giving self-care for your matrix. β¨
Further Details
The permutations consist of row and column interchanges which put the matrix in the form
( T1 X Y )
P A P = ( 0 B Z )
( 0 0 T2 )
where T1 and T2 are upper triangular matrices whose eigenvalues lie along the diagonal. The column indices ilo and ihi mark the starting and ending columns of the submatrix B. Balancing consists of applying a diagonal similarity transformation inv(D) * B * D to make the 1-norms of each row of B and its corresponding column nearly equal. π
The output matrix is
( T1 X*D Y )
( 0 inv(D)*B*D inv(D)*Z ).
( 0 0 T2 )
Information about the permutations P and the diagonal matrix D is returned in the vector scale. π
Arguments
jobβ Specifies the operations to be performed onA:= 0: none: simply setilo = 1,ihi = N,scale(I) = 1.0fori = 1,...,N;= 1: permute only;= 2: scale only;= 3: both permute and scale.
Aβ On entry, the input matrixA. On exit,Ais overwritten by the balanced matrix. Ifjob = 0,Ais not referenced. See Further Details. πΈilo,ihiβiloandihiare set to integers such that on exitA(i,j) = 0ifi > jandj = 1,...,ilo-1orI = ihi+1,...,N. Ifjob = 0or2,ilo = 1andihi = N.scaleβ Details of the permutations and scaling factors applied toA. IfP(j)is the index of the row and column interchanged with row and columnjandD(j)is the scaling factor applied to row and columnj, thenscale(j) = P(j)forj = 1,...,ilo-1= D(j)forj = ilo,...,ihi= P(j)forj = ihi+1,...,N.
The order in which the interchanges are made is N to ihi+1, then 1 to ilo-1.
infoβ= 0: successful exit.< 0: ifinfo = -i, the i-th argument had an illegal value. π
$a = random (50, 50);
$scale = zeroes(50);
$info = null;
$ilo = null;
$ihi = null;
gebal($a, $ilo, $ihi, $scale, $info);
gebal ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π«Ά
gebak π¦
Signature: ([io,phys]A(n,m); int job(); int side();int [phys]ilo();int [phys]ihi();[phys]scale(n); int [o,phys]info())
gebak forms the right or left eigenvectors of a real general matrix by backward transformation on the computed eigenvectors of the balanced matrix output by gebal. so it's like the lil glow-up reversal, bestie. β¨
Arguments
Aβ On entry, the matrix of right or left eigenvectors to be transformed, as returned byhseinortrevc. On exit,Ais overwritten by the transformed eigenvectors.jobβ Specifies the type of backward transformation required:= 0, do nothing, return immediately;= 1, do backward transformation for permutation only;= 2, do backward transformation for scaling only;= 3, do backward transformations for both permutation and scaling.
job must be the same as the argument job supplied to gebal. no cap, they gotta match. π
sideβ= 0:Vcontains left eigenvectors.= 1:Vcontains right eigenvectors;ilo,ihiβ The integersiloandihidetermined bygebal.1 <= ilo <= ihi <= N, ifN > 0;ilo=1andihi=0, ifN=0. HereNis the the number of rows of the matrixA.scaleβ Details of the permutation and scaling factors, as returned bygebal.infoβ= 0: successful exit.< 0: ifinfo = -i, the i-th argument had an illegal value. π
$a = random (50, 50);
$scale = zeroes(50);
$info = null;
$ilo = null;
$ihi = null;
gebal($a, $ilo, $ihi, $scale, $info);
# Compute eigenvectors ($ev)
gebak($ev, $ilo, $ihi, $scale, $info);
gebak ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π«Ά
lange β
Signature: ([phys]A(n,m); int norm(); [o]b(); [t]work(workn))
Computes the value of the one norm, or the Frobenius norm, or the infinity norm, or the element of largest absolute value of a real matrix A. pick your fighter, bestie. π
Description
returns the value
okay so the formula for lange finishes out like this, bestie β read it like a little choose-your-own-norm menu:
lange = ( max(abs(A(i,j))), norm = 0
(
( norm1(A), norm = 1
(
( normI(A), norm = 2
(
( normF(A), norm = 3
where norm1 is the one norm of a matrix (maximum column sum), normI is the infinity norm (maximum row sum), and normF is the Frobenius norm (square root of sum of squares). and pls clock this: max(abs(A(i,j))) is not a matrix norm. it's just vibing there in slot 0. π
β¨ Arguments β¨
normβ tellslangewhich value to hand back, exactly as described up there β¬οΈAβ the n by m matrixAπ
$a = random (float, 100, 100);
$norm = $a->lange(1);
lange ignores the bad-value flag of the input ndarrays. it will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π«Ά
πΈ lansy πΈ
Signature: (A(n,n); int uplo(); int norm(); [o]b(); [t]work(workn))
Computes the value of the one norm, or the Frobenius norm, or the infinity norm, or the element of largest absolute value of a real symmetric matrix A. symmetric queens only. π
π Description π
returns the value
lansy = ( max(abs(A(i,j))), norm = 0
(
( norm1(A), norm = 1
(
( normI(A), norm = 2
(
( normF(A), norm = 3
where norm1 is the one norm of a matrix (maximum column sum), normI is the infinity norm (maximum row sum), and normF is the Frobenius norm (square root of sum of squares). and again, no cap: max(abs(A(i,j))) is not a matrix norm. it just lives there. π
normβ which value gets returned inlansy, as described above β¬οΈuploβ says whether we're referencing the upper or lower triangular part of the symmetric matrixA= 0: upper triangular part ofAis referenced= 1: lower triangular part ofAis referenced
Aβ the symmetric matrixA. ifuplo = 0, the leading n by n upper triangular part ofAcontains the upper triangular part of the matrixA, and the strictly lower triangular part ofAis not referenced. ifuplo = 1, the leading n by n lower triangular part ofAcontains the lower triangular part of the matrixA, and the strictly upper triangular part ofAis not referenced. it literally just doesn't look at the other half, it's not being shady, it's being efficient. β¨
# Assume $a is symmetric
$a = random (float, 100, 100);
$norm = $a->lansy(1, 1);
lansy ignores the bad-value flag of the input ndarrays. it will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π«Ά
π¦ lantr π¦
Signature: (A(m,n);int uplo();int norm();int diag();[o]b(); [t]work(workn))
Computes the value of the one norm, or the Frobenius norm, or the infinity norm, or the element of largest absolute value of a trapezoidal or triangular matrix A. we love a shape-shifter. π§
π Description π
returns the value
lantr = ( max(abs(A(i,j))), norm = 0
(
( norm1(A), norm = 1
(
( normI(A), norm = 2
(
( normF(A), norm = 3
where norm1 is the one norm of a matrix (maximum column sum), normI is the infinity norm (maximum row sum), and normF is the Frobenius norm (square root of sum of squares). and fr fr, max(abs(A(i,j))) is not a matrix norm. it's giving "technically a value" but not a norm. π
normβ which value gets returned inlantr, as described above β¬οΈuploβ says whether the matrixAis upper or lower trapezoidal= 0: upper triangular part ofAis referenced= 1: lower triangular part ofAis referenced- note that
Ais triangular instead of trapezoidal ifM = Nπ
diagβ says whether or not the matrixAhas a unit diagonal= 0: non-unit diagonal= 1: unit diagonal
Aβ the trapezoidal matrixA(Ais triangular ifm = n).- if
uplo = 0, the leading m by n upper trapezoidal part of the arrayAcontains the upper trapezoidal matrix, and the strictly lower triangular part ofAis not referenced. - if
uplo = 1, the leading m by n lower trapezoidal part of the arrayAcontains the lower trapezoidal matrix, and the strictly upper triangular part ofAis not referenced. - and this bit matters: when
diag = 1, the diagonal elements ofAare not referenced and are assumed to be one. so don't stress about what's chillin' on that diagonal, nobody's reading it. π
- if
# Assume $a is upper triangular
$a = random (float, 100, 100);
$norm = $a->lantr(1, 1, 0);
lantr ignores the bad-value flag of the input ndarrays. it will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π«Ά
π₯ gemm π₯
Signature: ([phys]A(m,n); int transa(); int transb(); [phys]B(p,q);[phys]alpha(); [phys]beta(); [io,phys]C(r,s))
Performs one of the matrix-matrix operations
C := alpha*op( A )*op( B ) + beta*C,
where op( X ) is one of p( X ) = X or op( X ) = X',
alpha and beta are scalars, and A, B and C are matrices, with op( A )
an m by k matrix, op( B ) a k by n matrix and C an m by n matrix.
this is THE matrix multiplication moment bestie, main character energy, the whole reason you're here. π
β Parameters β
transaβ on entry,transaspecifies the form ofop( A )to be used in the matrix multiplication, like so:transa = 0,op( A ) = A.transa = 1,op( A ) = A'.
transbβ on entry,transbspecifies the form ofop( B )to be used in the matrix multiplication, like so:transb = 0,op( B ) = B.transb = 1,op( B ) = B'.
alphaβ on entry,alphaspecifies the scalaralpha. πAβ before entry withtransa = 0, the leading m by k part of the arrayAmust contain the matrixA, otherwise the leading k by m part of the arrayAmust contain the matrixA.Bβ before entry withtransb = 0, the leading k by n part of the arrayBmust contain the matrixB, otherwise the leading n by k part of the arrayBmust contain the matrixB.betaβ on entry,betaspecifies the scalarbeta. whenbetais supplied as zero thenCneed not be set on input. so if beta's a zero you can just leave C blank, she's not being read.Cβ before entry, the leading m by n part of the arrayCmust contain the matrixC, except whenbetais zero, in which caseCneed not be set on entry.- on exit, the array
Cis overwritten by the m by n matrix( alpha*op( A )*op( B ) + beta*C ). so yeah she gets fully rewritten, no take-backs.
- on exit, the array
$a = random(5,4);
$b = random(5,4);
$alpha = pdl(0.5);
$beta = pdl(0);
$c = zeroes(5,5);
gemm($a, 0, 1,$b, $alpha, $beta, $c);
gemm ignores the bad-value flag of the input ndarrays. it will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π«Ά
π mmult π
Signature: ([phys]A(m,n); [phys]B(p,m); [o,phys]C(p,n))
Blas matrix multiplication based on gemm. β¨
mmult ignores the bad-value flag of the input ndarrays. it will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π«Ά
π crossprod π
Signature: ([phys]A(n,m); [phys]B(p,m); [o,phys]C(p,n))
Blas matrix cross product based on gemm. π
crossprod ignores the bad-value flag of the input ndarrays. it will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π«Ά
π syrk π
Signature: ([phys]A(m,n); int uplo(); int trans(); [phys]alpha(); [phys]beta(); [io,phys]C(p,p))
Performs one of the symmetric rank k operations
C := alpha*A*A' + beta*C,
or
C := alpha*A'*A + beta*C,
where alpha and beta are scalars, C is an n by n symmetric matrix
and A is an n by k matrix in the first case and a k by n matrix
in the second case.
π Parameters π
uploβ on entry,uplospecifies whether the upper or lower triangular part of the arrayCis to be referenced, like so:uplo = 0Only the upper triangular part ofCis to be referenced.uplo = 1Only the lower triangular part ofCis to be referenced.- unchanged on exit. β¨
transβ on entry,transspecifies the operation to be performed, like so:trans = 0C := alpha*A*A' + beta*C.trans = 1C := alpha*A'*A + beta*C.
alphaβ on entry,alphaspecifies the scalaralpha. unchanged on exit. πAβ before entry withtrans = 0, the leading n by k part of the arrayAmust contain the matrixA, otherwise the leading k by n part of the arrayAmust contain the matrixA.betaβ on entry,betaspecifies the scalarbeta.Cβ before entry withuplo = 0, the leading n by n upper triangular part of the arrayCmust contain the upper triangular part of the symmetric matrix and the strictly lower triangular part ofCis not referenced. on exit, the upper triangular part of the arrayCis overwritten by the upper triangular part of the updated matrix.- before entry with
uplo = 1, the leading n by n lower triangular part of the arrayCmust contain the lower triangular part of the symmetric matrix and the strictly upper triangular part ofCis not referenced. on exit, the lower triangular part of the arrayCis overwritten by the lower triangular part of the updated matrix.
- before entry with
tl;dr: you pick a half, you feed her that half, she updates that half, the other half was never invited to the party. π
$a = random(5,4);
$b = zeroes(5,5);
$alpha = 1;
$beta = 0;
syrk ($a, 1,0,$alpha, $beta , $b);
syrk ignores the bad-value flag of the input ndarrays. it will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π«Ά
π§ dot π§
Signature: ([phys]a(n);[phys]b(n);[o,phys]c())
Dot product of two vectors using Blas. β
$a = random(5);
$b = random(5);
$c = dot($a, $b)
dot ignores the bad-value flag of the input ndarrays. it will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π«Ά
axpy
Signature:
Signature: ([phys]a(n);[phys] alpha();[io,phys]b(m))
Okay bestie, axpy is giving linear combination energy: it does ax + b using Blas, and the result lands in b. So like, a gets scaled by alpha and added to b. Periodt. β¨
Example:
$a = random(5);
$b = random(5);
axpy($a, 12, $b)
And about bad values: axpy ignores the bad-value flag of the input ndarrays. But if the flag is set for any input ndarray, it will set the bad-value flag of all output ndarrays. So like, bad vibes in, bad vibes out? π
nrm2
Signature:
Signature: ([phys]a(n);[o]b())
nrm2 gives you the Euclidean norm of a vector using Blas. So like the length of the vector, bestie. πβ¨
Example:
$a = random(5);
$norm2 = norm2($a)
nrm2 ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. So it's not checking, but it will propagate. π
asum
Signature:
Signature: ([phys]a(n);[o]b())
asum is the sum of absolute values of a vector using Blas. So it's like adding up all the absolute values, no negative energy allowed. π
Example:
$a = random(5);
$absum = asum($a)
asum ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. No cap.
scal
Signature:
Signature: ([io,phys]a(n);scale())
scal scales a vector by a constant using Blas. So you multiply every element by scale. It's giving glow-up. β¨
Example:
$a = random(5);
$a->scal(0.5)
scal ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
rot
Signature:
Signature: ([io,phys]a(n);[phys]c(); [phys]s();[io,phys]b(n))
rot applies plane rotation using Blas. So it rotates vectors a and b using c and s (cosine and sine vibes). π
Example:
$a = random(5);
$b = random(5);
rot($a, 0.5, 0.7, $b)
rot ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
rotg
Signature:
Signature: ([io,phys]a();[io,phys]b();[o,phys]c(); [o,phys]s())
rotg generates plane rotation using Blas. So it takes a and b and spits out c and s. The math is mathing. β¨
Example:
$a = sequence(4);
rotg($a(0), $a(1),$a(2),$a(3))
rotg ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
lasrt
Signature:
Signature: ([io,phys]d(n); int id();int [o,phys]info())
lasrt sorts the numbers in d in increasing order (if id = 0) or in decreasing order (if id = 1). So you can sort ascending or descending, bestie. π
It uses Quick Sort, reverting to Insertion sort on arrays of size <= 20. Dimension of stack limits N to about 232. So like, it's quick but also handles small arrays with insertion sort. And the stack dimension limits N to about 232. No cap.
β¨ Arguments β¨
id:= 0: sortdin increasing order;= 1: sortdin decreasing order.d: On entry, the array to be sorted. On exit,dhas been sorted into increasing order (d(1) <= ... <= d(N)) or into decreasing order (d(1) >= ... >= d(N)), depending onid.info:= 0: successful exit;< 0: ifinfo = -i, the i-th argument had an illegal value.
Example:
$a = random(5);
lasrt ($a, 0, ($info = null));
lasrt ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
lacpy
Signature:
Signature: ([phys]A(m,n); int uplo(); [o,phys]B(p,n))
lacpy copies all or part of a two-dimensional matrix A to another matrix B. So like, copy-paste but with options. π
β¨ Arguments β¨
uplo: Specifies the part of the matrixAto be copied toB.= 0: Upper triangular part= 1: Lower triangular part- Otherwise: All of the matrix
A
A: ThembynmatrixA. Ifuplo = 0, only the upper triangle or trapezoid is accessed; ifuplo = 1, only the lower triangle or trapezoid is accessed.B: On exit,B = Ain the locations specified byuplo.
Example:
$a = random(5,5);
$b = zeroes($a);
lacpy ($a, 0, $b);
lacpy ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
laswp
Signature:
Signature: ([io,phys]A(m,n);int [phys]k1();int [phys] k2(); int [phys]ipiv(p);int [phys]inc())
laswp performs a series of row interchanges on the matrix A. One row interchange is initiated for each of rows k1 through k2 of A. Doesn't use PDL indices (start = 1). So it's like swapping rows, but note the indexing starts at 1, not 0. PDL girlies, watch out. π
β¨ Arguments β¨
A: On entry, the matrix of column dimension N to which the row interchanges will be applied. On exit, the permuted matrix.k1: The first element ofipivfor which a row interchange will be done.k2: The last element ofipivfor which a row interchange will be done.ipiv: The vector of pivot indices. Only the elements in positionsk1throughk2ofipivare accessed.ipiv(k) = limplies rowskandlare to be interchanged.inc: The increment between successive values ofipiv. Ifipivis negative, the pivots are applied in reverse order.
Example:
$a = random(5,5);
# reverse row (col for PDL)
$b = pdl([5,4,3,2,1]);
$a->laswp(1,2,$b,1);
laswp ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
lamch
Signature:
Signature: (cmach(); [o]precision())
lamch determines precision machine parameters. Works inplace. So it's giving you the deets on your machine's floating-point precision. π»
β¨ Arguments β¨
cmach: Specifies the value to be returned bylamch:= 0LAMCH := eps= 1LAMCH := sfmin= 2LAMCH := base= 3LAMCH := eps*base= 4LAMCH := t= 5LAMCH := rnd= 6LAMCH := emin= 7LAMCH := rmin= 8LAMCH := emax= 9LAMCH := rmax
where
eps= relative machine precisionsfmin= safe minimum, such that1/sfmindoes not overflowbase= base of the machineprec=eps*baset= number of (base) digits in the mantissarnd=1.0when rounding occurs in addition,0.0otherwiseemin= minimum exponent before (gradual) underflowrmin= underflow threshold -base**(emin-1)emax= largest exponent before overflowrmax= overflow threshold -(base**emax)*(1-eps)
Example:
$a = lamch (0);
print "EPS is $a for double\n";
lamch ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
labad
Signature:
Signature: ([io,phys]small(); [io,phys]large())
labad takes the values computed by lamch for underflow and overflow, and returns the square root of each of these values if the log of large is sufficiently large. This subroutine is intended to identify machines with a large exponent range, such as the Crays, and redefine the underflow and overflow limits to be the square roots of the values computed by lamch. This subroutine is needed because lamch does not compensate for poor arithmetic in the upper half of the exponent range, as is found on a Cray. So basically, it's fixing up the limits for machines with huge exponent ranges. π
β¨ Arguments β¨
small: On entry, the underflow threshold as computed bylamch. On exit, ifLOG10(large)is sufficiently large, the square root ofsmall, otherwise unchanged.large: On entry, the overflow threshold as computed bylamch. On exit, ifLOG10(large)is sufficiently large, the square root oflarge, otherwise unchanged.
Example:
$underflow = lamch(7);
$overflow = lamch(9);
labad ($underflow, $overflow);
labad ignores the bad-value flag of the input ndarrays. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
tricpy
Signature:
Signature: (A(m,n);[o] C(m,n); int uplo)
tricpy(PDL(A), int(uplo), PDL(C))
Example:
use PDL::LinearAlgebra;
$c = $a->tricpy($uplo); # explicit uplo
$c = $a->tricpy; # default upper
or
use PDL::LinearAlgebra::Real;
tricpy($a, $uplo, $c); # modify c
tricpy copies triangular part to another matrix. If uplo == 0 copy upper triangular part. So it's like copying only the triangle you want. πΊ
tricpy does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. So if bad values are present, it's not handling them, but it will propagate the flag. π
cplx_eigen
Signature:
Signature: (eigreval(n);eigimval(n); eigvec(n,p);int fortran();[o]cplx_val(c=2,n);[o]cplx_vec(c=2,n,p))
cplx_eigen outputs complex eigen-values/vectors from eigen-values/vectors as computed by geev or geevx. 'fortran' means fortran storage type. So it's converting real eigen stuff into complex eigen stuff, with a Fortran storage option. π§¬
cplx_eigen does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
augment
Signature:
Signature: (x(n); y(p);[o]out(q))
augment combines two ndarrays into a single ndarray. This routine does backward and forward dataflow automatically. So it's like merging two arrays into one, and the dataflow goes both ways. β¨
augment does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
mstack
Signature:
Signature: (x(n,m);y(n,p);[o]out(n,q))
mstack combines two ndarrays into a single ndarray. This routine does backward and forward dataflow automatically. So like stacking them side by side? It's combining, bestie. π§
mstack does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
charpol
Signature:
Signature: (A(n,n);[o]Y(n,n);[o]out(p))
charpol computes the adjoint matrix and the characteristic polynomial. Math queen. π
charpol does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
π AUTHOR π
Copyright (C) GrΓ©gory Vanuxem 2005-2018.
This library is free software; you can redistribute it and/or modify it under the terms of the Perl Artistic License as in the file Artistic_2 in this distribution.
β¨ That's the whole vibe, bestie! This page is from perl v5.38.2, dated 2024-03-31, for Real(3pm). Stay slaying! π
π
π¦ where this page comes from
- ubuntu noble: libpdl-linearalgebra-perl 0.38-1build2 Β· Artistic-2
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms