sgltgsylv(3)
π sgltgsylv(3) β MEPACK π
okay so bestie, gather round, because this is sgltgsylv from the MEPACK manual, section 3, and it is a LOT. It's the whole single-precision corner of the generalized Sylvester equation world. Yes, all of it. Grab a snack. π
β¨ NAME β¨
sgltgsylv β Single Precision
- Single Precision routines for triangular generalized Sylvester equations.
no cap, that's the entire name section. short but iconic. π
πΈ SYNOPSIS πΈ
π Functions π
this is the full roster, in order, every single one, don't skip. π«Ά
sla_tgcsylv_dag
subroutine sla_tgcsylv_dag (transa, transb, sgn1, sgn2, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, work, info)
Level-3 Kagstroem-Westin/Bartels-Stewart Algorithm for the generalized coupled Sylvester equation, but make it DAG scheduling. parallel bestie behavior. π₯
sla_tgcsylv_dual_dag
subroutine sla_tgcsylv_dual_dag (transa, transb, sgn1, sgn2, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, work, info)
OpenMP4 - DAG Algorithm for the dual generalized coupled Sylvester equation. it's giving threads. π§
sla_tgsylv_dag
subroutine sla_tgsylv_dag (transa, transb, sgn, m, n, a, lda, b, ldb, c, ldc, d, ldd, x, ldx, scale, work, info)
Level-3 Bartels-Stewart Algorithm for the generalized Sylvester equation with DAG based parallelization. π«
sla_tgcsylv_dual_kernel_44nn
subroutine sla_tgcsylv_dual_kernel_44nn (sgn1, sgn2, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, info)
Solver for a 4x4 dual generalized coupled Sylvester equation (TRANSA = N, TRANSB = N). tiny but mighty, the kernel that carries the whole operation. π
sla_tgcsylv_dual_kernel_44nt
subroutine sla_tgcsylv_dual_kernel_44nt (sgn1, sgn2, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, info)
Solver for a 4x4 dual generalized coupled Sylvester equation (TRANSA = N, TRANSB = T). same energy, different letters. π
sla_tgcsylv_dual_kernel_44tn
subroutine sla_tgcsylv_dual_kernel_44tn (sgn1, sgn2, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, info)
Solver for a 4x4 dual generalized coupled Sylvester equation (TRANSA = T, TRANSB = N). π
sla_tgcsylv_dual_kernel_44tt
subroutine sla_tgcsylv_dual_kernel_44tt (sgn1, sgn2, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, info)
Solver for a 4x4 dual generalized coupled Sylvester equation (TRANSA = T, TRANSB = T). double transposed, double slay. β¨
sla_tgcsylv_dual_l2
subroutine sla_tgcsylv_dual_l2 (transa, transb, sgn1, sgn2, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, work, info)
Level-2 Kagstroem-Westin/Bartels-Stewart Algorithm for the dual generalized coupled Sylvester equation. lvl 2 era. π¦
sla_tgcsylv_dual_l2_local_copy
subroutine sla_tgcsylv_dual_l2_local_copy (transa, transb, sgn1, sgn2, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, work, info)
Level-2 Kagstroem-Westin/Bartels-Stewart Algorithm for the dual generalized coupled Sylvester equation (Local Copy). it copies locally, respectfully. π
sla_tgcsylv_dual_l2_local_copy_128
subroutine sla_tgcsylv_dual_l2_local_copy_128 (transa, transb, sgn1, sgn2, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, work, info)
Level-2 Kagstroem-Westin/Bartels-Stewart Algorithm for the dual generalized coupled Sylvester equation (Local Copy). the _128 one. π
sla_tgcsylv_dual_l2_local_copy_32
subroutine sla_tgcsylv_dual_l2_local_copy_32 (transa, transb, sgn1, sgn2, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, work, info)
Level-2 Kagstroem-Westin/Bartels-Stewart Algorithm for the dual generalized coupled Sylvester equation (Local Copy). the _32 one. πΈ
sla_tgcsylv_dual_l2_local_copy_64
subroutine sla_tgcsylv_dual_l2_local_copy_64 (transa, transb, sgn1, sgn2, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, work, info)
Level-2 Kagstroem-Westin/Bartels-Stewart Algorithm for the dual generalized coupled Sylvester equation (Local Copy). the _64 one. β
sla_tgcsylv_dual_l2_local_copy_96
subroutine sla_tgcsylv_dual_l2_local_copy_96 (transa, transb, sgn1, sgn2, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, work, info)
Level-2 Kagstroem-Westin/Bartels-Stewart Algorithm for the dual generalized coupled Sylvester equation (Local Copy). the _96 one, the last of the local copy quartet. π
sla_tgcsylv_l2
subroutine sla_tgcsylv_l2 (transa, transb, sgn1, sgn2, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, work, info)
Level-2 Kagstroem-Westin/Bartels-Stewart Algorithm for the generalized coupled Sylvester equation (Optimized). π
sla_tgcsylv_l2_local_copy
subroutine sla_tgcsylv_l2_local_copy (transa, transb, sgn1, sgn2, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, work, info)
Level-2 Kagstroem-Westin/Bartels-Stewart Algorithm for the generalized coupled Sylvester equation (Optimized). yes, same label, different routine, keep up bestie. π«Ά
sla_tgcsylv_l2_local_copy_128
subroutine sla_tgcsylv_l2_local_copy_128 (transa, transb, sgn1, sgn2, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, work, info)
Level-2 Kagstroem-Westin/Bartels-Stewart Algorithm for the generalized coupled Sylvester equation (Optimized). _128. π
sla_tgcsylv_l2_local_copy_32
subroutine sla_tgcsylv_l2_local_copy_32 (transa, transb, sgn1, sgn2, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, work, info)
Level-2 Kagstroem-Westin/Bartels-Stewart Algorithm for the generalized coupled Sylvester equation (Optimized). _32. πΈ
sla_tgcsylv_l2_local_copy_64
subroutine sla_tgcsylv_l2_local_copy_64 (transa, transb, sgn1, sgn2, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, work, info)
Level-2 Kagstroem-Westin/Bartels-Stewart Algorithm for the generalized coupled Sylvester equation (Optimized). _64. β
sla_tgcsylv_l2_local_copy_96
subroutine sla_tgcsylv_l2_local_copy_96 (transa, transb, sgn1, sgn2, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, work, info)
Level-2 Kagstroem-Westin/Bartels-Stewart Algorithm for the generalized coupled Sylvester equation (Optimized). _96. π
sla_tgcsylv_l2_reorder
subroutine sla_tgcsylv_l2_reorder (transa, transb, sgn1, sgn2, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, work, info)
Level-2 Kagstroem-Westin/Bartels-Stewart Algorithm for the generalized coupled Sylvester equation (Optimized). reordering, as a treat. π
sla_tgcsylv_l2_unopt
subroutine sla_tgcsylv_l2_unopt (transa, transb, sgn1, sgn2, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, work, info)
Level-2 Kagstroem-Westin/Bartels-Stewart Algorithm for the generalized coupled Sylvester equation (unoptimized). it's the reference-y one, no shame in it. π
sla_tgsylv_gardiner_laub
subroutine sla_tgsylv_gardiner_laub (transa, transb, sgn, m, n, a, lda, b, ldb, c, ldc, d, ldd, x, ldx, scale, work, info)
Level-2 Gardiner-Laub algorithm for the generalized Sylvester equation. named algorithm, extra iconic. π
sla_tgsylv_l2
subroutine sla_tgsylv_l2 (transa, transb, sgn, m, n, a, lda, b, ldb, c, ldc, d, ldd, x, ldx, scale, work, info)
Level-2 Bartels-Stewart Algorithm for the generalized Sylvester equation (Optimized). π
sla_tgsylv_l2_colwise
subroutine sla_tgsylv_l2_colwise (transa, transb, sgn, m, n, a, lda, b, ldb, c, ldc, d, ldd, x, ldx, scale, work, info)
Level-2 Bartels-Stewart Algorithm for the generalized Sylvester equation (unoptimized). going column by column, one at a time, like a lil ladybug. π
sla_tgsylv_l2_local_copy
subroutine sla_tgsylv_l2_local_copy (transa, transb, sgn, m, n, a, lda, b, ldb, c, ldc, d, ldd, x, ldx, scale, work, info)
Level-2 Bartels-Stewart Algorithm for the generalized Sylvester equation (Optimized). π
sla_tgsylv_l2_local_copy_128
subroutine sla_tgsylv_l2_local_copy_128 (transa, transb, sgn, m, n, a, lda, b, ldb, c, ldc, d, ldd, x, ldx, scale, work, info)
Level-2 Bartels-Stewart Algorithm for the generalized Sylvester equation (Optimized). _128. π
sla_tgsylv_l2_local_copy_32
subroutine sla_tgsylv_l2_local_copy_32 (transa, transb, sgn, m, n, a, lda, b, ldb, c, ldc, d, ldd, x, ldx, scale, work, info)
Level-2 Bartels-Stewart Algorithm for the generalized Sylvester equation (Optimized). _32. πΈ
sla_tgsylv_l2_local_copy_64
subroutine sla_tgsylv_l2_local_copy_64 (transa, transb, sgn, m, n, a, lda, b, ldb, c, ldc, d, ldd, x, ldx, scale, work, info)
Level-2 Bartels-Stewart Algorithm for the generalized Sylvester equation (Optimized). _64. β
sla_tgsylv_l2_local_copy_96
subroutine sla_tgsylv_l2_local_copy_96 (transa, transb, sgn, m, n, a, lda, b, ldb, c, ldc, d, ldd, x, ldx, scale, work, info)
Level-2 Bartels-Stewart Algorithm for the generalized Sylvester equation (Optimized). _96. π
sla_tgsylv_l2_reorder
subroutine sla_tgsylv_l2_reorder (transa, transb, sgn, m, n, a, lda, b, ldb, c, ldc, d, ldd, x, ldx, scale, work, info)
Level-2 Bartels-Stewart Algorithm for the generalized Sylvester equation (Optimized). π
sla_tgsylv_l2_rowwise
subroutine sla_tgsylv_l2_rowwise (transa, transb, sgn, m, n, a, lda, b, ldb, c, ldc, d, ldd, x, ldx, scale, work, info)
Level-2 Bartels-Stewart Algorithm for the generalized Sylvester equation (unoptimized). row by row this time. we contain multitudes. π
sla_tgcsylv_dual_l3
subroutine sla_tgcsylv_dual_l3 (transa, transb, sgn1, sgn2, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, work, info)
Level-3 Kagstroem-Westin/Bartels-Stewart Algorithm for the dual generalized coupled Sylvester equation. level 3 era, glow up complete. π₯
sla_tgcsylv_dual_l3_2s
subroutine sla_tgcsylv_dual_l3_2s (transa, transb, sgn1, sgn2, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, work, info)
Level-3 Kagstroem-Westin/Bartels-Stewart Algorithm with sub blocking for the dual generalized coupled Sylvester equation. sub blocking, sub slaying. π
sla_tgcsylv_l3_2s
subroutine sla_tgcsylv_l3_2s (transa, transb, sgn1, sgn2, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, work, info)
Level-3 Kagstroem-Westin/Bartels-Stewart Algorithm for the generalized coupled Sylvester equation (optimized). π
sla_tgcsylv_l3
subroutine sla_tgcsylv_l3 (transa, transb, sgn1, sgn2, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, work, info)
Level-3 Kagstroem-Westin/Bartels-Stewart Algorithm for the generalized coupled Sylvester equation (optimized). the main character, lowkey. π
sla_tgcsylv_l3_unopt
subroutine sla_tgcsylv_l3_unopt (transa, transb, sgn1, sgn2, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, work, info)
Level-3 Kagstroem-Westin/Bartels-Stewart Algorithm for the generalized coupled Sylvester equation (unoptimized). π
sla_tgsylv_l3_2s
subroutine sla_tgsylv_l3_2s (transa, transb, sgn, m, n, a, lda, b, ldb, c, ldc, d, ldd, x, ldx, scale, work, info)
Level-3 Bartels-Stewart Algorithm for the generalized Sylvester equation. that's the whole description, it's confident. β¨
sla_tgsylv_l3_colwise
subroutine sla_tgsylv_l3_colwise (transa, transb, sgn, m, n, a, lda, b, ldb, c, ldc, d, ldd, x, ldx, scale, work, info)
Level-3 Bartels-Stewart Algorithm for the generalized Sylvester equation. column-wise variant, still level-3. π
sla_tgsylv_l3
subroutine sla_tgsylv_l3 (transa, transb, sgn, m, n, a, lda, b, ldb, c, ldc, d, ldd, x, ldx, scale, work, info)
Level-3 Bartels-Stewart Algorithm for the generalized Sylvester equation. π₯
sla_tgsylv_l3_rowwise
subroutine sla_tgsylv_l3_rowwise (transa, transb, sgn, m, n, a, lda, b, ldb, c, ldc, d, ldd, x, ldx, scale, work, info)
Level-3 Bartels-Stewart Algorithm for the generalized Sylvester equation. row-wise variant, same deal. π
sla_tgcsylv_dual_recursive
recursive subroutine sla_tgcsylv_dual_recursive (transa, transb, sgn1, sgn2, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, work, info)
Recursive blocking Algorithm for the dual generalized coupled Sylvester equation. it calls itself, that's the whole vibe, it's a recursive subroutine bestie. π
sla_tgcsylv_recursive
recursive subroutine sla_tgcsylv_recursive (transa, transb, sgn1, sgn2, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, work, info)
Recursive Algorithm for the generalized coupled Sylvester equation. π
sla_tgsylv_recursive
recursive subroutine sla_tgsylv_recursive (transa, transb, sgn, m, n, a, lda, b, ldb, c, ldc, d, ldd, x, ldx, scale, work, info)
Level-3 Recursive Blocked Solver for the generalized Sylvester equation. π
okay that's the entire SYNOPSIS and I'm not even winded. more sections incoming, don't go anywhere bestie π
Detailed Description π
okay so bestie, this whole page is about single precision routines for triangular generalized Sylvester equations. i know, i know, the name is giving "professor wrote this at 3am" but stay with me, it's actually so good.
This section contains the solvers for the standard Sylvester equation with (quasi) triangular coefficient matrices. The coefficient matrices are normally generated with the help of the Schur decomposition from LAPACK. And β important β all routines work in single precision arithmetic. no doubles in this house. π
β¨ Function Documentation β¨
sla_tgcsylv_dag π¦
subroutine sla_tgcsylv_dag (character, dimension(1) transa, character,
dimension(1) transb, real sgn1, real sgn2, integer m, integer n, real,
dimension(lda, *) a, integer lda, real, dimension(ldb, *) b, integer
ldb, real, dimension(ldc, *) c, integer ldc, real, dimension(ldd, *) d,
integer ldd, real, dimension(lde, *) e, integer lde, real,
dimension(ldf,*) f, integer ldf, real scale, real, dimension(*) work,
integer info)
Level-3 Kagstroem-Westin/Bartels-Stewart Algorithm for the generalized coupled Sylvester equation with DAG scheduling. yes that is a lot of names. they earned them. π
Purpose π
!>
!> SLA_TGCSYLV_DAG solves a generalized coupled Sylvester equation of the following form
!>
!> op1(A) * R + SGN1 * L * op2(B) = SCALE * E (1)
!> op1(C) * R + SGN2 * L * op2(D) = SCALE * F
!>
!> where A is a M-by-M quasi upper triangular matrix, C is a M-by-M upper triangular
!> matrix and B and D are N-by-N upper triangular matrices. Furthermore either B or
!> D can be quasi upper triangular as well. The right hand side Y and the solution X
!> M-by-N matrices. Typically the matrix pencils (A,C) and (B,D) ( or (D,B) ) are
!> created by SGGES from LAPACK.
!>
Remarks πΈ
The Algorithm uses OpenMP DAG scheduling. that's the whole remark. short and iconic. β¨
Parameters π«Ά
TRANSAβ okay soTRANSAisCHARACTER(1). It specifies the form of the system of equations with respect toAandC:== 'N':op1(A) = A,op1(C) = C(No transpose forAandC)== 'T':op1(A) = A**T,op1(C) = C **T(TransposeAandC)
TRANSBβTRANSBisCHARACTER(1). It specifies the form of the system of equations with respect toBandD:== 'N':op2(B) = B,op2(D) = D(No transpose forBandD)== 'T':op2(B) = B**T,op2(D) = D **T(TransposeBandD)
SGN1βSGN1isREAL, allowed values:+/-1. It specifies the sign between in the first equation. (yes, "between in". we don't question the phrasing, we just pass the sign π )SGN2βSGN2isREAL, allowed values:+/-1. It specifies the sign between in the second equation.MβMisINTEGER. The order of the matricesAandC.M >= 0.NβNisINTEGER. The order of the matricesBandD.N >= 0.AβAisREALarray, dimension(LDA,M). The matrixAmust be (quasi-) upper triangular.LDAβLDAisINTEGER. The leading dimension of the arrayA.LDA >= max(1,M).BβBisREALarray, dimension(LDB,N). The matrixBmust be (quasi-) upper triangular. If the matrixDis already quasi-upper triangular the matrixBmust be upper triangular.LDBβLDBisINTEGER. The leading dimension of the arrayB.LDB >= max(1,N).CβCisREALarray, dimension(LDC,M). The matrixCmust be upper triangular.LDCβLDCisINTEGER. The leading dimension of the arrayC.LDC >= max(1,M).DβDisREALarray, dimension(LDD,N). The matrixDmust be (quasi-) upper triangular. If the matrixBis already quasi-upper triangular the matrixDmust be upper triangular.LDDβLDDisINTEGER. The leading dimension of the arrayD.LDD >= max(1,N).EβEisREALarray, dimension(LDE,N).- On input, the matrix
Econtains the right hand sideE. - On output, the matrix
Econtains the solutionRof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. - Right hand side
Eand the solutionRareM-by-Nmatrices.
- On input, the matrix
LDEβLDEisINTEGER. The leading dimension of the arrayE.LDE >= max(1,M).FβFisREALarray, dimension(LDF,N).- On input, the matrix
Fcontains the right hand sideF. - On output, the matrix
Fcontains the solutionLof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. - Right hand side
Fand the solutionLareM-by-Nmatrices.
- On input, the matrix
LDFβLDFisINTEGER. The leading dimension of the arrayF.LDE >= max(1,M). (fr fr that's what it says, i'm not touching it,LDEis right there in the source π)SCALEβSCALEisREAL.SCALEis a scaling factor to prevent the overflow in the result. IfINFO == 0thenSCALEis1.0otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true.WORKβWORKisREALarray, dimensionLWORK. Workspace for the algorithm. The workspace needs to queried before the running the computation. The query is performed by calling the subroutine withINFO == -1on input. The required workspace is then returned inINFO. (query first bestie, do NOT skip the query, the vibes will be off π)INFOβINFOisINTEGER.- On input:
== -1: Perform a workspace query<> -1: normal operation
- On exit, workspace query:
< 0: ifINFO = -i, thei-th argument had an illegal value>= 0: The value ofINFOis the required number of elements in the workspace.
- On exit, normal operation:
== 0: successful exit< 0: ifINFO = -i, thei-th argument had an illegal value> 0: The equation is not solved correctly. One of the arising inner system got singular. π
- On input:
Author π
Martin Koehler, MPI Magdeburg
Date β
October 2025
Definition π
Definition at line 217 of file sla_tgcsylv_dag.f90.
sla_tgcsylv_dual_dag π§
subroutine sla_tgcsylv_dual_dag (character, dimension(1) transa, character,
dimension(1) transb, real sgn1, real sgn2, integer m, integer n, real,
dimension(lda, *) a, integer lda, real, dimension(ldb, *) b, integer
ldb, real, dimension(ldc, *) c, integer ldc, real, dimension(ldd, *) d,
integer ldd, real, dimension(lde, *) e, integer lde, real,
dimension(ldf,*) f, integer ldf, real scale, real, dimension(*) work,
integer info)
OpenMP4 - DAG Algorithm for the dual generalized coupled Sylvester equation. the sequel. the part two. the dual. π
Purpose π¦
!>
!> SLA_TGCSYLV_DUAL_DAG solves a generalized coupled Sylvester equation of the following form
!>
!> op1(A)**T * R + op1(C)**T * L = SCALE * E (1)
!> SGN1 * R * op2(B)**T + SGN2 * L * op2(D)** T = SCALE * F
!>
!> where A is a M-by-M quasi upper triangular matrix, C is a M-by-M upper triangular
!> matrix and B and D are N-by-N upper triangular matrices. Furthermore either B or
!> D can be quasi upper triangular as well. The right hand sides E, F and the solutions R, L are
!> M-by-N matrices. Typically the matrix pencils (A,C) and (B,D) ( or (D,B) ) are
!> created by SGGES from LAPACK.
!> The equation (1) is the dual to the generalized coupled Sylvester equation
!>
!> op1(A) * R + SGN1 * L * op2(B) = SCALE * E (2)
!> op1(C) * R + SGN2 * L * op2(D) = SCALE * F
!>
!> The equation (1) is the dual one to equation (2) with respect to the underlying linear system.
!> Let Z be the matrix formed by rewriting (2) into its Kronecker form. This yields
!>
!> | kron(I, op1(A)) SGN1*kron(op2(B)**T, I) | | Vec R | | Vec E |
!> Z X = | |*| | = | |
!> | kron(I, op1(C)) SGN2*kron(op2(D)**T, I) | | Vec L | | Vec F |
!>
!> Regarding Z**T one obtains
!>
!> | kron(I, op1(A)**T ) kron(I, op1(C)**T) | | Vec R | | Vec E |
!> Z**T X = | |*| | = | |
!> | SGN1*kron(op2(B), I) SGN2*kron(op2(D), I) | | Vec L | | Vec F |
!>
!> which belongs to the Sylvester equation (1). For this reason the parameters TRANSA and TRANSB
!> are expressed in terms of the Sylvester equation (2).
!>
!>
heads up bestie: because of that last line,TRANSAandTRANSBare expressed in terms of the Sylvester equation (2), not (1). that's not a typo, that's the whole point. the transposes are transposed. iykyk. π₯
Parameters π«Ά
TRANSAβTRANSAisCHARACTER(1). It specifies the form of the system of equations with respect toAandC:== 'N':op1(A) = A,op1(C) = C(No transpose forAandC)== 'T':op1(A) = A**T,op1(C) = C **T(TransposeAandC)
TRANSBβTRANSBisCHARACTER(1). It specifies the form of the system of equations with respect toBandD:== 'N':op2(B) = B,op2(D) = D(No transpose forBandD)== 'T':op2(B) = B**T,op2(D) = D **T(TransposeBandD)
SGN1βSGN1isREAL, allowed values:+/-1. It specifies the sign between in the first equation.SGN2βSGN2isREAL, allowed values:+/-1. It specifies the sign between in the second equation.MβMisINTEGER. The order of the matricesAandC.M >= 0.NβNisINTEGER. The order of the matricesBandD.N >= 0.AβAisREALarray, dimension(LDA,M). The matrixAmust be (quasi-) upper triangular.LDAβLDAisINTEGER. The leading dimension of the arrayA.LDA >= max(1,M).BβBisREALarray, dimension(LDB,N). The matrixBmust be (quasi-) upper triangular. If the matrixDis already quasi-upper triangular the matrixBmust be upper triangular.LDBβLDBβINTEGERenergy, bestie. It's the leading dimension of the arrayB, and the vibe check saysLDB >= max(1,N). π¦CβREALarray, dimension(LDC,M). And listen π β the matrixCmust be upper triangular. That's not a suggestion, that's the law. πLDCβINTEGER, leading dimension of the arrayC. Requirement:LDC >= max(1,M). Periodt. β¨DβREALarray, dimension(LDD,N). The matrixDmust be (quasi-) upper triangular. And here's the lil plot twist π«Ά β if the matrixBis already quasi-upper triangular, then the matrixDmust be upper triangular. It's giving "one of you has to be the normal one." πLDDβINTEGER, the leading dimension of the arrayD.LDD >= max(1,N), no cap. πEβREALarray, dimension(LDE,N). On input, the matrixEcontains the right hand sideE. On output, the matrixEcontains the solutionRof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand sideEand the solutionRareM-by-Nmatrices. So it walks in as the problem and struts out as the answer β main character behavior fr fr. π₯LDEβINTEGER, leading dimension of the arrayE.LDE >= max(1,M). Slay. πFβREALarray, dimension(LDF,N). On input, the matrixFholds the right hand sideF. On output, the matrixFholds the solutionLof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand sideFand the solutionLareM-by-Nmatrices. Same glow-up arc asE, honestly. β¨LDFβINTEGER, leading dimension of the arrayF. And the doc literally saysLDE >= max(1,M)here β not a typo I'm fixing, bestie, that's exactly what's written. πSCALEβREAL. This one is the bodyguard π«Ά βSCALEis a scaling factor to prevent the overflow in the result. IfINFO == 0thenSCALEis1.0, otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true.WORKβREALarray, dimensionLWORK. Workspace for the algorithm. And you cannot just roll up with an unqueried workspace β the workspace needs to be queried before running the computation. The query is performed by calling the subroutine withINFO == -1on input, and the required workspace is then returned inINFO. So basically you ask first, then you compute. Communication, queen. πINFOβINTEGER, the lil status report π
On input:
== -1: Perform a workspace query<> -1: normal operation
On exit, workspace query:
< 0: ifINFO = -i, thei-th argument had an illegal value>= 0: The value ofINFOis the required number of elements in the workspace.
On exit, normal operation:
== 0: successful exit< 0: ifINFO = -i, thei-th argument had an illegal value> 0: The equation is not solved correctly. One of the arising inner system got singular.
Ngl, that > 0 case is the "it's not me, it's the singular inner system" moment. Not great, not terrible. π
Author ποΈ
Martin Koehler, MPI Magdeburg
Date π
October 2025
Definition at line 237 of file sla_tgcsylv_dual_dag.f90.
π subroutine sla_tgcsylv_dual_kernel_44nn π
subroutine sla_tgcsylv_dual_kernel_44nn (real sgn1, real sgn2, integer m,
integer n, real, dimension(lda, *) a, integer lda, real, dimension(ldb,
*) b, integer ldb, real, dimension(ldc, *) c, integer ldc, real,
dimension(ldd, *) d, integer ldd, real, dimension(lde, *) e, integer
lde, real, dimension(ldf,*) f, integer ldf, real scale, integer info)
Solver for a 4x4 dual generalized coupled Sylvester equation (TRANSA = N, TRANSB = N). Yes bestie, a 4x4. Tiny. Adorable. The little baby of the recursion. π
Purpose
!>
!> SLA_TGCSYLV_DUAL_KERNEL_44NN solves a generalized coupled Sylvester equation of the following form
!>
!> op1(A)**T * R + op1(C)**T * L = SCALE * E (1)
!> SGN1 * R * op2(B)**T + SGN2 * L * op2(D)** T = SCALE * F
!>
!> where A is a M-by-M quasi upper triangular matrix, C is a M-by-M upper triangular
!> matrix and B and D are N-by-N upper triangular matrices. Furthermore either B or
!> D can be quasi upper triangular as well. The right hand side Y and the solution X
!> M-by-N matrices. Typically the matrix pencils (A,C) and (B,D) ( or (D,B) ) are
!> created by SGGES from LAPACK.
!> The equation (1) is the dual to the generalized coupled Sylvester equation
!>
!> op1(A) * R + SGN1 * L * op2(B) = SCALE * E (2)
!> op1(C) * R + SGN2 * L * op2(D) = SCALE * F
!>
!> The equation (1) is the dual one to equation (2) with respect to the underlying linear system.
!> Let Z be the matrix formed by rewriting (2) into its Kronecker form. This yields
!>
!> | kron(I, op1(A)) SGN1*kron(op2(B)**T, I) | | Vec R | | Vec E |
!> Z X = | |*| | = | |
!> | kron(I, op1(C)) SGN2*kron(op2(D)**T, I) | | Vec L | | Vec F |
!>
!> Regarding Z**T one obtains
!>
!> | kron(I, op1(A)**T ) kron(I, op1(C)**T) | | Vec R | | Vec E |
!> Z**T X = | |*| | = | |
!> | SGN1*kron(op2(B), I) SGN2*kron(op2(D), I) | | Vec L | | Vec F |
!>
!> which belongs to the Sylvester equation (1). For this reason the parameters TRANSA and TRANSB
!> are expressed in terms of the Sylvester equation (2).
!>
!>
Attention β οΈ
This routine only allows to solve equations that are at most of size 4 x 4. The operator arguments TRANSA and TRANSB are fixed to op1(H) = H and op2(H) = H. The primary use of this function is to end the recursion in dla_tgcsylv_dual_recursive.
Okay so this one is literally the "base case" bestie β it exists to stop the recursion from going forever. Iconic, honestly. π¦
Parameters
SGN1
!> SGN1 is REAL, allowed values: +/-1
!> Specifies the sign between in the first equation.
!>
SGN2
!> SGN2 is REAL, allowed values: +/-1
!> Specifies the sign between in the second equation.
!>
M
!> M is INTEGER
!> The order of the matrices A and C. 128 >= M >= 0.
!>
N
!> N is INTEGER
!> The order of the matrices B and D. 128 >= N >= 0.
!>
A
!> A is REAL array, dimension (LDA,M)
!> The matrix A must be (quasi-) upper triangular.
!>
LDA
!> LDA is INTEGER
!> The leading dimension of the array A. LDA >= max(1,M).
!>
B
!> B is REAL array, dimension (LDB,N)
!> The matrix B must be (quasi-) upper triangular. If the matrix D is already
!> quasi-upper triangular the matrix B must be upper triangular.
!>
LDB
!> LDB is INTEGER
!> The leading dimension of the array B. LDB >= max(1,N).
!>
C
!> C is REAL array, dimension (LDC,M)
!> The matrix C must be upper triangular.
!>
LDC
!> LDC is INTEGER
!> The leading dimension of the array C. LDC >= max(1,M).
!>
D
!> D is REAL array, dimension (LDD,N)
!> The matrix D must be (quasi-) upper triangular. If the matrix B is already
!> quasi-upper triangular the matrix D must be upper triangular.
!>
LDD
!> LDD is INTEGER
!> The leading dimension of the array D. LDD >= max(1,N).
!>
E
!> E is REAL array, dimension (LDE,N)
!> On input, the matrix E contains the right hand side E.
!> On output, the matrix E contains the solution R of Equation (1)
!> as selected by TRANSA, TRANSB, and SGN1/SGN2.
!> Right hand side E and the solution R are M-by-N matrices.
!>
LDE
!> LDE is INTEGER
!> The leading dimension of the array E. LDE >= max(1,M).
!>
F
!> F is REAL array, dimension (LDF,N)
!> On input, the matrix F contains the right hand side F.
!> On output, the matrix F contains the solution L of Equation (1)
!> as selected by TRANSA, TRANSB, and SGN1/SGN2.
!> Right hand side F and the solution L are M-by-N matrices.
!>
LDF
!> LDF is INTEGER
!> The leading dimension of the array F. LDE >= max(1,M).
!>
SCALE
!> SCALE is REAL
!> SCALE is a scaling factor to prevent the overflow in the result.
!> If INFO == 0 then SCALE is 1.0 otherwise if one of the inner systems
!> could not be solved correctly, 0 < SCALE <= 1 holds true.
!>
INFO
!> INFO is INTEGER
!>
!> On exit:
!> == 0: successful exit
!> > 0: The equation is not solved correctly. One of the arising inner
!> system got singular.
!>
Author ποΈ
Martin Koehler, MPI Magdeburg
Date π
October 2025
Definition at line 206 of file sla_tgcsylv_dual_kernel_44_nn.f90.
π¦ subroutine sla_tgcsylv_dual_kernel_44nt π¦
subroutine sla_tgcsylv_dual_kernel_44nt (real sgn1, real sgn2, integer m,
integer n, real, dimension(lda, *) a, integer lda, real, dimension(ldb,
*) b, integer ldb, real, dimension(ldc, *) c, integer ldc, real,
dimension(ldd, *) d, integer ldd, real, dimension(lde, *) e, integer
lde, real, dimension(ldf,*) f, integer ldf, real scale, integer info)
Solver for a 4x4 dual generalized coupled Sylvester equation (TRANSA = N, TRANSB = T). Look at her β same 4x4 energy, but this time TRANSB is T. She's the transposed twin and she ate. π
β¨
Purpose
okay bestie, so this whole routine is out here solving a generalized coupled Sylvester equation that looks exactly like this:
op1(A)**T * R + op1(C)**T * L = SCALE * E (1)
SGN1 * R * op2(B)**T + SGN2 * L * op2(D)** T = SCALE * F
where A is a M-by-M quasi upper triangular matrix, C is a M-by-M upper triangular matrix, and B and D are N-by-N upper triangular matrices. Also β and this is the little plot twist β either B or D can be quasi upper triangular too. The right hand sides E, F and the solutions R, L are M-by-N matrices. Typically the matrix pencils (A,C) and (B,D) (or (D,B)) get created by SGGES from LAPACK. π
Equation (1) is the dual to the generalized coupled Sylvester equation
op1(A) * R + SGN1 * L * op2(B) = SCALE * E (2)
op1(C) * R + SGN2 * L * op2(D) = SCALE * F
Equation (1) is the dual one to equation (2) with respect to the underlying linear system. Let Z be the matrix formed by rewriting (2) into its Kronecker form. That gives you:
| kron(I, op1(A)) SGN1*kron(op2(B)**T, I) | | Vec R | | Vec E |
Z X = | |*| | = | |
| kron(I, op1(C)) SGN2*kron(op2(D)**T, I) | | Vec L | | Vec F |
And regarding Z**T you obtain
| kron(I, op1(A)**T ) kron(I, op1(C)**T) | | Vec R | | Vec E |
Z**T X = | |*| | = | |
| SGN1*kron(op2(B), I) SGN2*kron(op2(D), I) | | Vec L | | Vec F |
which belongs to the Sylvester equation (1). For this reason the parameters TRANSA and TRANSB are expressed in terms of the Sylvester equation (2). π¦
Attention (read this fr) π
This routine only allows to solve equations that are at most of size 4 x 4. The operator arguments TRANSA and TRANSB are fixed to op1(H) = H and op2(H) = H**T. The primary use of this function is to end the recursion in dla_tgcsylv_dual_recursive.
Parameters π§Ύ
SGN1βSGN1isREAL, allowed values:+/-1. Specifies the sign between in the first equation. β¨SGN2βSGN2isREAL, allowed values:+/-1. Specifies the sign between in the second equation. β¨MβMisINTEGER. The order of the matricesAandC.128 >= M >= 0.NβNisINTEGER. The order of the matricesBandD.128 >= N >= 0.AβAisREALarray, dimension(LDA,M). The matrixAmust be (quasi-) upper triangular. πLDAβLDAisINTEGER. The leading dimension of the arrayA.LDA >= max(1,M).BβBisREALarray, dimension(LDB,N). The matrixBmust be (quasi-) upper triangular. If the matrixDis already quasi-upper triangular the matrixBmust be upper triangular. π«ΆLDBβLDBisINTEGER. The leading dimension of the arrayB.LDB >= max(1,N).CβCisREALarray, dimension(LDC,M). The matrixCmust be upper triangular.LDCβLDCisINTEGER. The leading dimension of the arrayC.LDC >= max(1,M).DβDisREALarray, dimension(LDD,N). The matrixDmust be (quasi-) upper triangular. If the matrixBis already quasi-upper triangular the matrixDmust be upper triangular. π«ΆLDDβLDDisINTEGER. The leading dimension of the arrayD.LDD >= max(1,N).EβEisREALarray, dimension(LDE,N). On input, the matrixEcontains the right hand sideE. On output, the matrixEcontains the solutionRof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand sideEand the solutionRareM-by-Nmatrices. πΈLDEβLDEisINTEGER. The leading dimension of the arrayE.LDE >= max(1,M).FβFisREALarray, dimension(LDF,N). On input, the matrixFcontains the right hand sideF. On output, the matrixFcontains the solutionLof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand sideFand the solutionLareM-by-Nmatrices. πΈLDFβLDFisINTEGER. The leading dimension of the arrayF.LDE >= max(1,M). (yes bestie, the source literally saysLDEthere and notLDFβ not me, I'm just the messenger π)SCALEβSCALEisREAL.SCALEis a scaling factor to prevent the overflow in the result. IfINFO == 0thenSCALEis1.0otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true. πINFOβINFOisINTEGER. On exit:== 0: successful exit π> 0: The equation is not solved correctly. One of the arising inner system got singular. π
Author π
Martin Koehler, MPI Magdeburg
Date π
October 2025
Definition at line 206 of file sla_tgcsylv_dual_kernel_44_nt.f90.
sla_tgcsylv_dual_kernel_44tn
subroutine sla_tgcsylv_dual_kernel_44tn (real sgn1, real sgn2, integer m,
integer n, real, dimension(lda, *) a, integer lda, real, dimension(ldb,
*) b, integer ldb, real, dimension(ldc, *) c, integer ldc, real,
dimension(ldd, *) d, integer ldd, real, dimension(lde, *) e, integer
lde, real, dimension(ldf,*) f, integer ldf, real scale, integer info)
Solver for a 4x4 dual generalized coupled Sylvester equation (TRANSA = T, TRANSB = N). π¦
Purpose π―
SLA_TGCSYLV_DUAL_KERNEL_44TN solves a generalized coupled Sylvester equation of the following form
op1(A)**T * R + op1(C)**T *L = SCALE * E (1)
SGN1 * R * op2(B)**T + SGN2 * L * op2(D)** T = SCALE * F
where A is a M-by-M quasi upper triangular matrix, C is a M-by-M upper triangular matrix and B and D are N-by-N upper triangular matrices. Furthermore either B or D can be quasi upper triangular as well. The right hand sides E, F and the solutions R, L are M-by-N matrices. Typically the matrix pencils (A,C) and (B,D) (or (D,B)) are created by SGGES from LAPACK. The equation (1) is the dual to the generalized coupled Sylvester equation
op1(A) * R + SGN1 * L * op2(B) = SCALE * E (2)
op1(C) * R + SGN2 * L * op2(D) = SCALE * F
The equation (1) is the dual one to equation (2) with respect to the underlying linear system. Let Z be the matrix formed by rewriting (2) into its Kronecker form. This yields
| kron(I, op1(A)) SGN1*kron(op2(B)**T, I) | | Vec R | | Vec E |
Z X = | |*| | = | |
| kron(I, op1(C)) SGN2*kron(op2(D)**T, I) | | Vec L | | Vec F |
Regarding Z**T one obtains
| kron(I, op1(A)**T ) kron(I, op1(C)**T) | | Vec R | | Vec E |
Z**T X = | |*| | = | |
| SGN1*kron(op2(B), I) SGN2*kron(op2(D), I) | | Vec L | | Vec F |
which belongs to the Sylvester equation (1). For this reason the parameters TRANSA and TRANSB are expressed in terms of the Sylvester equation (2). β¨
Attention (read this fr) π
This routine only allows to solve equations that are at most of size 4 x 4. The operator arguments TRANSA and TRANSB are fixed to op1(H) = H**T and op2(H) = H. The primary use of this function is to end the recursion in dla_tgcsylv_dual_recursive.
Parameters π§Ύ
SGN1βSGN1isREAL, allowed values:+/-1. Specifies the sign between in the first equation. β¨SGN2βSGN2isREAL, allowed values:+/-1. Specifies the sign between in the second equation. β¨MβMisINTEGER. The order of the matricesAandC.128 >= M >= 0.NβNisINTEGER. The order of the matricesBandD.128 >= N >= 0.AβAisREALarray, dimension(LDA,M). The matrixAmust be (quasi-) upper triangular. πLDAβLDAisINTEGER. The leading dimension of the arrayA.LDA >= max(1,M).BβBisREALarray, dimension(LDB,N). The matrixBmust be (quasi-) upper triangular. If the matrixDis already quasi-upper triangular the matrixBmust be upper triangular. π«ΆLDBβLDBisINTEGER. The leading dimension of the arrayB.LDB >= max(1,N).CβCisREALarray, dimension(LDC,M). The matrixCmust be upper triangular.LDCβLDCisINTEGER. The leading dimension of the arrayC.LDC >= max(1,M).DβDisREALarray, dimension(LDD,N). The matrixDmust be (quasi-) upper triangular. If the matrixBis already quasi-upper triangular the matrixDmust be upper triangular. π«ΆLDDβLDDisINTEGER. The leading dimension of the arrayD.LDD >= max(1,N).EβEisREALarray, dimension(LDE,N). On input, the matrixEcontains the right hand sideE. On output, the matrixEcontains the solutionRof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand sideEand the solutionRareM-by-Nmatrices. πΈLDEβLDEisINTEGER. The leading dimension of the arrayE.LDE >= max(1,M).FβFβFis REAL array, dimension(LDF,N). On input, the matrixFcontains the right hand sideF. On output, the matrixFcontains the solutionLof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand sideFand the solutionLareM-by-Nmatrices. πLDFβLDFis INTEGER. The leading dimension of the arrayF.LDE >= max(1,M).
not me noticing it literally saysLDEhere and notLDFπ that's what the page says bestie, we do not touch the sacred text π
SCALEβSCALEis REAL.SCALEis a scaling factor to prevent the overflow in the result. IfINFO == 0thenSCALEis1.0otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true. no overflow allowed on this campus π«ΆINFOβINFOis INTEGER.
On exit:
== 0: successful exit β¨> 0: The equation is not solved correctly. One of the arising inner system got singular. π
Author
Martin Koehler, MPI Magdeburg
Date
October 2025
Definition at line 206 of file sla_tgcsylv_dual_kernel_44_tn.f90.
π subroutine sla_tgcsylv_dual_kernel_44tt
subroutine sla_tgcsylv_dual_kernel_44tt (real sgn1, real sgn2, integer m, integer n, real, dimension(lda, *) a, integer lda, real, dimension(ldb, *) b, integer ldb, real, dimension(ldc, *) c, integer ldc, real, dimension(ldd, *) d, integer ldd, real, dimension(lde, *) e, integer lde, real, dimension(ldf,*) f, integer ldf, real scale, integer info)
Solver for a 4x4 dual generalized coupled Sylvester equation (TRANSA = T, TRANSB = T) π
Purpose
okay so SLA_TGCSYLV_DUAL_KERNEL_44TT solves a generalized coupled Sylvester equation shaped exactly like this π
op1(A)**T * R + op1(C)**T * L = SCALE * E (1)
SGN1 * R * op2(B)**T + SGN2 * L * op2(D)** T = SCALE * F
where A is a M-by-M quasi upper triangular matrix, C is a M-by-M upper triangular matrix and B and D are N-by-N upper triangular matrices. Furthermore either B or D can be quasi upper triangular as well. The right hand sides E, F and the solutions R, L are M-by-N matrices. Typically the matrix pencils (A,C) and (B,D) ( or (D,B) ) are created by SGGES from LAPACK. β¨
The equation (1) is the dual to the generalized coupled Sylvester equation
op1(A) * R + SGN1 * L * op2(B) = SCALE * E (2)
op1(C) * R + SGN2 * L * op2(D) = SCALE * F
The equation (1) is the dual one to equation (2) with respect to the underlying linear system. Let Z be the matrix formed by rewriting (2) into its Kronecker form. This yields π§
| kron(I, op1(A)) SGN1*kron(op2(B)**T, I) | | Vec R | | Vec E |
Z X = | |*| | = | |
| kron(I, op1(C)) SGN2*kron(op2(D)**T, I) | | Vec L | | Vec F |
Regarding Z**T one obtains
| kron(I, op1(A)**T ) kron(I, op1(C)**T) | | Vec R | | Vec E |
Z**T X = | |*| | = | |
| SGN1*kron(op2(B), I) SGN2*kron(op2(D), I) | | Vec L | | Vec F |
which belongs to the Sylvester equation (1). For this reason the parameters TRANSA and TRANSB are expressed in terms of the Sylvester equation (2). π€―
Attention
This routine only allows to solve equations that are at most of size 4 x 4. The operator argumentsTRANSAandTRANSBare fixed toop1(H) = H**Tandop2(H) = H**T. The primary use of this function is to end the recursion indla_tgcsylv_dual_recursive. π¨
Parameters
SGN1βSGN1is REAL, allowed values:+/-1. Specifies the sign between in the first equation. ββSGN2βSGN2is REAL, allowed values:+/-1. Specifies the sign between in the second equation. ββMβMis INTEGER. The order of the matricesAandC.128 >= M >= 0.NβNis INTEGER. The order of the matricesBandD.128 >= N >= 0.AβAis REAL array, dimension(LDA,M). The matrixAmust be (quasi-) upper triangular. πΊLDAβLDAis INTEGER. The leading dimension of the arrayA.LDA >= max(1,M).BβBis REAL array, dimension(LDB,N). The matrixBmust be (quasi-) upper triangular. If the matrixDis already quasi-upper triangular the matrixBmust be upper triangular. πΊLDBβLDBis INTEGER. The leading dimension of the arrayB.LDB >= max(1,N).CβCis REAL array, dimension(LDC,M). The matrixCmust be upper triangular. πΊLDCβLDCis INTEGER. The leading dimension of the arrayC.LDC >= max(1,M).DβDis REAL array, dimension(LDD,N). The matrixDmust be (quasi-) upper triangular. If the matrixBis already quasi-upper triangular the matrixDmust be upper triangular. πΊLDDβLDDis INTEGER. The leading dimension of the arrayD.LDD >= max(1,N).EβEis REAL array, dimension(LDE,N). On input, the matrixEcontains the right hand sideE. On output, the matrixEcontains the solutionRof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand sideEand the solutionRareM-by-Nmatrices. πLDEβLDEis INTEGER. The leading dimension of the arrayE.LDE >= max(1,M).FβFis REAL array, dimension(LDF,N). On input, the matrixFcontains the right hand sideF. On output, the matrixFcontains the solutionLof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand sideFand the solutionLareM-by-Nmatrices. πLDFβLDFis INTEGER. The leading dimension of the arrayF.LDE >= max(1,M).
same LDE situation as before bestie, it's giving copy-paste energy and honestly? iconic π
SCALEβSCALEis REAL.SCALEis a scaling factor to prevent the overflow in the result. IfINFO == 0thenSCALEis1.0otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true. protecting your floats from the void π«ΆINFOβINFOis INTEGER.
On exit:
== 0: successful exit β¨> 0: The equation is not solved correctly. One of the arising inner system got singular. π
Author
Martin Koehler, MPI Magdeburg
Date
October 2025
Definition at line 206 of file sla_tgcsylv_dual_kernel_44_tt.f90.
πΈ subroutine sla_tgcsylv_dual_l2
subroutine sla_tgcsylv_dual_l2 (character, dimension(1) transa, character, dimension(1) transb, real sgn1, real sgn2, integer m, integer n, real, dimension(lda, *) a, integer lda, real, dimension(ldb, *) b, integer ldb, real, dimension(ldc, *) c, integer ldc, real, dimension(ldd, *) d, integer ldd, real, dimension(lde, *) e, integer lde, real, dimension(ldf,*) f, integer ldf, real scale, real, dimension(*) work, integer info)
Level-2 Kagstroem-Westin/Bartels-Stewart Algorithm for the dual generalized coupled Sylvester equation. π
Purpose
SLA_TGCSYLV_DUAL_L2 solves a generalized coupled Sylvester equation that looks like this π
op1(A)**T * R + op1(C)**T * L = SCALE * E (1)
SGN1 * R * op2(B)**T + SGN2 * L * op2(D)** T = SCALE * F
where A is a M-by-M quasi upper triangular matrix, C is a M-by-M upper triangular matrix and B and D are N-by-N upper triangular matrices. Furthermore either B or D can be quasi upper triangular as well. The right hand sides E, F and the solutions R, L are M-by-N matrices. Typically the matrix pencils (A,C) and (B,D) ( or (D,B) ) are created by SGGES from LAPACK. β¨
The equation (1) is the dual to the generalized coupled Sylvester equation
op1(A) * R + SGN1 * L * op2(B) = SCALE * E (2)
op1(C) * R + SGN2 * L * op2(D) = SCALE * F
The equation (1) is the dual one to equation (2) with respect to the underlying linear system. Let Z be the matrix formed by rewriting (2) into its Kronecker form. This yields π§
| kron(I, op1(A)) SGN1*kron(op2(B)**T, I) | | Vec R | | Vec E |
Z X = | |*| | = | |
| kron(I, op1(C)) SGN2*kron(op2(D)**T, I) | | Vec L | | Vec F |
Regarding Z**T one obtains
| kron(I, op1(A)**T ) kron(I, op1(C)**T) | | Vec R | | Vec E |
Z**T X = | |*| | = | |
| SGN1*kron(op2(B), I) SGN2*kron(op2(D), I) | | Vec L | | Vec F |
which belongs to the Sylvester equation (1). For this reason the parameters TRANSA and TRANSB are expressed in terms of the Sylvester equation (2). π€―
Remarks
The algorithm is implemented using BLAS level 2 operations and hand written optimizations. π
Parameters
TRANSAβTRANSAis CHARACTER(1). Specifies the form of the system of equations with respect toAandC:== 'N':op1(A) = A,op1(C) = C(No transpose forAandC)== 'T':op1(A) = A**T,op1(C) = C **T(TransposeAandC)
TRANSBβTRANSBis CHARACTER(1). Specifies the form of the system of equations with respect toBandD:== 'N':op2(B) = B,op2(D) = D(No transpose forBandD)== 'T':op2(B) = B**T,op2(D) = D **T(TransposeBandD)
SGN1βSGN1is REAL, allowed values:+/-1. Specifies the sign between in the first equation. ββSGN2SGN2β it's aREAL, bestie, and the only allowed values are+/-1. It specifies the sign between in the second equation. πMβINTEGER. The order of the matricesAandC.M >= 0. πNβINTEGER. The order of the matricesBandD.N >= 0. β¨AβREALarray, dimension(LDA,M). The matrixAmust be (quasi-) upper triangular. π¦LDAβINTEGER. The leading dimension of the arrayA.LDA >= max(1,M). πBβREALarray, dimension(LDB,N). The matrixBmust be (quasi-) upper triangular. If the matrixDis already quasi-upper triangular, then the matrixBmust be upper triangular. πΈLDBβINTEGER. The leading dimension of the arrayB.LDB >= max(1,N). πCβREALarray, dimension(LDC,M). The matrixCmust be upper triangular. πLDCβINTEGER. The leading dimension of the arrayC.LDC >= max(1,M). π«ΆDβREALarray, dimension(LDD,N). The matrixDmust be (quasi-) upper triangular. If the matrixBis already quasi-upper triangular, then the matrixDmust be upper triangular. π«LDDβINTEGER. The leading dimension of the arrayD.LDD >= max(1,N). πEβREALarray, dimension(LDE,N). On input, the matrixEcontains the right hand sideE. On output, the matrixEcontains the solutionRof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand sideEand the solutionRareM-by-Nmatrices. π₯LDEβINTEGER. The leading dimension of the arrayE.LDE >= max(1,M). πFβREALarray, dimension(LDF,N). On input, the matrixFcontains the right hand sideF. On output, the matrixFcontains the solutionLof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand sideFand the solutionLareM-by-Nmatrices. πLDFβINTEGER. The leading dimension of the arrayF.LDE >= max(1,M). (Yes, it really saysLDEhere β we're keeping it exactly as the original, bestie. π€·ββοΈ)SCALEβREAL.SCALEis a scaling factor to prevent the overflow in the result. IfINFO == 0thenSCALEis1.0otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true. π§WORKβREALarray, dimensionLWORK. Workspace for the algorithm. The workspace needs to queried before the running the computation. The query is performed by calling the subroutine withINFO == -1on input. The required workspace is then returned inINFO. βINFOβINTEGER.- On input:
== -1: Perform a workspace query<> -1: normal operation
- On exit, workspace query:
< 0: ifINFO = -i, the i-th argument had an illegal value>= 0: The value ofINFOis the required number of elements in the workspace.
- On exit, normal operation:
== 0: successful exit< 0: ifINFO = -i, the i-th argument had an illegal value> 0: The equation is not solved correctly. One of the arising inner system got singular.
- On input:
β¨ Optimizations β¨
- Replaced
SAXPYoperation by Fortran intrinsic - Replaced all BLAS calls except of
SGERby Fortran intrinsic,
Author: Martin Koehler, MPI Magdeburg Date: October 2025 Definition at line 245 of file sla_tgcsylv_dual_l2.f90.
Okay so next up, we have a whole new subroutine: sla_tgcsylv_dual_l2_local_copy! π
subroutine sla_tgcsylv_dual_l2_local_copy (character, dimension(1) transa,
character, dimension(1) transb, real sgn1, real sgn2, integer m, integer
n, real, dimension(lda, *) a, integer lda, real, dimension(ldb, *) b,
integer ldb, real, dimension(ldc, *) c, integer ldc, real,
dimension(ldd, *) d, integer ldd, real, dimension(lde, *) e, integer
lde, real, dimension(ldf,*) f, integer ldf, real scale, real,
dimension(*) work, integer info)
Level-2 Kagstroem-Westin/Bartels-Stewart Algorithm for the dual generalized coupled Sylvester equation (Local Copy)
Purpose:
...and the whole point of it is to solve a generalized coupled Sylvester equation that looks like this, bestie:
op1(A)**T * R + op1(C)**T * L = SCALE * E (1)
SGN1 * R * op2(B)**T + SGN2 * L * op2(D)** T = SCALE * F
where A is a M-by-M quasi upper triangular matrix, C is a M-by-M upper triangular matrix and B and D are N-by-N upper triangular matrices. And plot twist β¨: either B or D can be quasi upper triangular as well. The right hand sides E, F and the solutions R, L are M-by-N matrices. Typically the matrix pencils (A,C) and (B,D) ( or (D,B) ) are created by SGGES from LAPACK. ikyk what that is π
The equation (1) is the dual to the generalized coupled Sylvester equation
op1(A) * R + SGN1 * L * op2(B) = SCALE * E (2)
op1(C) * R + SGN2 * L * op2(D) = SCALE * F
The equation (1) is the dual one to equation (2) with respect to the underlying linear system. Let Z be the matrix formed by rewriting (2) into its Kronecker form. This yields
| kron(I, op1(A)) SGN1*kron(op2(B)**T, I) | | Vec R | | Vec E |
Z X = | |*| | = | |
| kron(I, op1(C)) SGN2*kron(op2(D)**T, I) | | Vec L | | Vec F |
Regarding Z**T one obtains
| kron(I, op1(A)**T ) kron(I, op1(C)**T) | | Vec R | | Vec E |
Z**T X = | |*| | = | |
| SGN1*kron(op2(B), I) SGN2*kron(op2(D), I) | | Vec L | | Vec F |
which belongs to the Sylvester equation (1). For this reason the parameters TRANSA and TRANSB are expressed in terms of the Sylvester equation (2). no cap, that's the whole reason for the naming scheme π«Ά
β¨ REMARKS β¨
The algorithm is implemented using BLAS level 2 operations and hand written optimizations and uses local copies of the input data. For this reason M and N are limited to 128. yes literally capped at 128, that's not a vibe, that's the law π
β¨ PARAMETERS β¨
TRANSAβTRANSAisCHARACTER(1). Specifies the form of the system of equations with respect toAandC:== 'N':op1(A) = A,op1(C) = C(No transpose forAandC)== 'T':op1(A) = A**T,op1(C) = C **T(TransposeAandC)
TRANSBβTRANSBisCHARACTER(1). Specifies the form of the system of equations with respect toBandD:== 'N':op2(B) = B,op2(D) = D(No transpose forBandD)== 'T':op2(B) = B**T,op2(D) = D **T(TransposeBandD)
SGN1βSGN1isREAL, allowed values:+/-1. Specifies the sign between in the first equation. it's just a lil plus-or-minus, she's simple like that πSGN2βSGN2isREAL, allowed values:+/-1. Specifies the sign between in the second equation.MβMisINTEGER. The order of the matricesAandC.128 >= M >= 0.NβNisINTEGER. The order of the matricesBandD.128 >= N >= 0.AβAisREALarray, dimension(LDA,M). The matrixAmust be (quasi-) upper triangular. don't try to sneak a random dense matrix in there, she will not be having it πLDAβLDAisINTEGER. The leading dimension of the arrayA.LDA >= max(1,M).BβBisREALarray, dimension(LDB,N). The matrixBmust be (quasi-) upper triangular. If the matrixDis already quasi-upper triangular the matrixBmust be upper triangular. read that twice bestie, it's a real constraint β οΈLDBβLDBisINTEGER. The leading dimension of the arrayB.LDB >= max(1,N).CβCisREALarray, dimension(LDC,M). The matrixCmust be upper triangular.LDCβLDCisINTEGER. The leading dimension of the arrayC.LDC >= max(1,M).DβDisREALarray, dimension(LDD,N). The matrixDmust be (quasi-) upper triangular. If the matrixBis already quasi-upper triangular the matrixDmust be upper triangular.LDDβLDDisINTEGER. The leading dimension of the arrayD.LDD >= max(1,N).EβEisREALarray, dimension(LDE,N). On input, the matrixEcontains the right hand sideE. On output, the matrixEcontains the solutionRof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand sideEand the solutionRare M-by-N matrices. she goes in as a RHS and comes out as a whole solution, main character energy fr πLDEβLDEisINTEGER. The leading dimension of the arrayE.LDE >= max(1,M).FβFisREALarray, dimension(LDF,N). On input, the matrixFcontains the right hand sideF. On output, the matrixFcontains the solutionLof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand sideFand the solutionLare M-by-N matrices.LDFβLDFisINTEGER. The leading dimension of the arrayF.LDE >= max(1,M).
β οΈ heads up: yes, that last line saysLDEand notLDF. That is what the page says, so that is what you get. copied faithfully, no edits, we don't fix other people's typos, we just report them π
SCALEβSCALEisREAL.SCALEis a scaling factor to prevent the overflow in the result. IfINFO == 0thenSCALEis1.0otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true.WORKβWORKisREALarray, dimensionLWORK. Workspace for the algorithm. The workspace needs to queried before the running the computation. The query is performed by calling the subroutine withINFO == -1on input. The required workspace is then returned inINFO. yes you have to ask first, she doesn't just hand out her workspace for free β¨INFOβINFOisINTEGER.- On input:
== -1: Perform a workspace query<> -1: normal operation
- On exit, workspace query:
< 0: ifINFO = -i, the i-th argument had an illegal value>= 0: The value ofINFOis the required number of elements in the workspace.
- On exit, normal operation:
== 0: successful exit< 0: ifINFO = -i, the i-th argument had an illegal value> 0: The equation is not solved correctly. One of the arising inner system got singular. π yeah that one's the bad one, singular inner system means the tea is spilled and the math said no
- On input:
β¨ OPTIMIZATIONS: β¨
- Replaced
SAXPYoperation by Fortran intrinsic - No BLAS calls.
- Input data is copied to local arrays to increase the data locality if used from inside a level-3 solver.
she's got no BLAS calls at all, she's doing it by hand, artisanal, small-batch linear algebra π§
β¨ AUTHOR β¨
Martin Koehler, MPI Magdeburg
β¨ DATE β¨
October 2025
β¨ DEFINITION β¨
Definition at line 247 of file sla_tgcsylv_dual_l2_opt_local_copy.f90.
β¨ sla_tgcsylv_dual_l2_local_copy_128 β¨
subroutine sla_tgcsylv_dual_l2_local_copy_128 ( transa, transb, sgn1,
sgn2, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f,
ldf, scale, work, info)
Level-2 Kagstroem-Westin/Bartels-Stewart Algorithm for the dual generalized coupled Sylvester equation (Local Copy)
okay so meet her sibling π same energy, same local-copy lifestyle, and yes she is also doing the Kagstroem-Westin/Bartels-Stewart thing at level 2.
β¨ PURPOSE: β¨
okay so SLA_TGCSYLV_DUAL_L2_LOCAL_COPY_128 solves a generalized coupled Sylvester equation that looks exactly like this, no cap:
op1(A)**T * R + op1(C)**T * L = SCALE * E (1)
SGN1 * R * op2(B)**T + SGN2 * L * op2(D)** T = SCALE * F
where A is a M-by-M quasi upper triangular matrix, C is a M-by-M upper triangular matrix, and B and D are N-by-N upper triangular matrices. And bestie, plot twist: either B or D can be quasi upper triangular as well. The right hand sides E, F and the solutions R, L are all M-by-N matrices. Typically the matrix pencils (A,C) and (B,D) (or (D,B)) are created by SGGES from LAPACK. π
Equation (1) is the dual to the generalized coupled Sylvester equation
op1(A) * R + SGN1 * L * op2(B) = SCALE * E (2)
op1(C) * R + SGN2 * L * op2(D) = SCALE * F
The equation (1) is the dual one to equation (2) with respect to the underlying linear system. Let Z be the matrix formed by rewriting (2) into its Kronecker form. This yields
| kron(I, op1(A)) SGN1*kron(op2(B)**T, I) | | Vec R | | Vec E |
Z X = | |*| | = | |
| kron(I, op1(C)) SGN2*kron(op2(D)**T, I) | | Vec L | | Vec F |
Regarding Z**T one obtains
| kron(I, op1(A)**T ) kron(I, op1(C)**T) | | Vec R | | Vec E |
Z**T X = | |*| | = | |
| SGN1*kron(op2(B), I) SGN2*kron(op2(D), I) | | Vec L | | Vec F |
which belongs to the Sylvester equation (1). For this reason the parameters TRANSA and TRANSB are expressed in terms of the Sylvester equation (2). iykyk β¨
π Remarks
The algorithm is implemented using BLAS level 2 operations plus hand written optimizations, and it uses local copies of the input data. Because of that, M and N are limited to 128. Also, the algorithm uses alignment of the local arrays if this is supported by the compiler. At the moment this is used with ifort and xlf but not with gfortran. π«Ά
π Parameters
TRANSAβ it's aCHARACTER(1). It specifies the form of the system of equations with respect toAandC:== 'N':op1(A) = A,op1(C) = C(no transpose forAandC)== 'T':op1(A) = A**T,op1(C) = C **T(transposeAandC)
TRANSBβ it's aCHARACTER(1). It specifies the form of the system of equations with respect toBandD:== 'N':op2(B) = B,op2(D) = D(no transpose forBandD)== 'T':op2(B) = B**T,op2(D) = D **T(transposeBandD)
SGN1β it'sREAL, and the only allowed values are+/-1. It specifies the sign between in the first equation. πSGN2β it'sREAL, and the only allowed values are+/-1. It specifies the sign between in the second equation.Mβ it'sINTEGER. The order of the matricesAandC.128 >= M >= 0.Nβ it'sINTEGER. The order of the matricesBandD.128 >= N >= 0.Aβ it's aREALarray, dimension(LDA,M). The matrixAmust be (quasi-) upper triangular.LDAβ it'sINTEGER. The leading dimension of the arrayA.LDA >= max(1,M).Bβ it's aREALarray, dimension(LDB,N). The matrixBmust be (quasi-) upper triangular. If the matrixDis already quasi-upper triangular, then the matrixBmust be upper triangular.LDBβ it'sINTEGER. The leading dimension of the arrayB.LDB >= max(1,N).Cβ it's aREALarray, dimension(LDC,M). The matrixCmust be upper triangular.LDCβ it'sINTEGER. The leading dimension of the arrayC.LDC >= max(1,M).Dβ it's aREALarray, dimension(LDD,N). The matrixDmust be (quasi-) upper triangular. If the matrixBis already quasi-upper triangular, then the matrixDmust be upper triangular.LDDβ it'sINTEGER. The leading dimension of the arrayD.LDD >= max(1,N).Eβ it's aREALarray, dimension(LDE,N). On input, the matrixEcontains the right hand sideE. On output, the matrixEcontains the solutionRof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. The right hand sideEand the solutionRare M-by-N matrices. β¨LDEβ it'sINTEGER. The leading dimension of the arrayE.LDE >= max(1,M).Fβ it's aREALarray, dimension(LDF,N). On input, the matrixFcontains the right hand sideF. On output, the matrixFcontains the solutionLof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. The right hand sideFand the solutionLare M-by-N matrices.LDFβ it'sINTEGER. The leading dimension of the arrayF.LDE >= max(1,M). (yep, that's literally what it says π«Ά we are simply the messenger)SCALEβ it'sREAL.SCALEis a scaling factor to prevent the overflow in the result. IfINFO == 0thenSCALEis1.0; otherwise, if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true. π₯WORKβ it's aREALarray, dimensionLWORK. Workspace for the algorithm. The workspace needs to be queried before running the computation. The query is performed by calling the subroutine withINFO == -1on input. The required workspace is then returned inINFO.INFOβ it'sINTEGER. π
On input:
== -1: perform a workspace query<> -1: normal operation
On exit, workspace query:
< 0: ifINFO = -i, the i-th argument had an illegal value>= 0: the value ofINFOis the required number of elements in the workspace.
On exit, normal operation:
== 0: successful exit< 0: ifINFO = -i, the i-th argument had an illegal value> 0: the equation is not solved correctly. One of the arising inner system got singular. π
π₯ Optimizations:
- Replaced
SAXPYoperation by Fortran intrinsic - No BLAS calls.
- Input data is copied to local arrays to increase the data locality if used from inside a level-3 solver.
- The local copies are aligned to 64 byte if supported by the compiler.
βοΈ Author
Martin Koehler, MPI Magdeburg
π Date
October 2025
Definition at line 248 of file sla_tgcsylv_dual_l2_opt_local_copy_128.f90.
subroutine sla_tgcsylv_dual_l2_local_copy_32 ( transa, transb, sgn1,
sgn2, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f,
ldf, scale, work, info)
Level-2 Kagstroem-Westin/Bartels-Stewart Algorithm for the dual generalized coupled Sylvester equation (Local Copy) π¦
Purpose:
okay bestie so SLA_TGCSYLV_DUAL_L2_LOCAL_COPY_32 solves a generalized coupled Sylvester equation that looks exactly like this:
op1(A)**T * R + op1(C)**T * L = SCALE * E (1)
SGN1 * R * op2(B)**T + SGN2 * L * op2(D)** T = SCALE * F
Let me set the scene π
β A is a M-by-M quasi upper triangular matrix, C is a M-by-M upper triangular matrix, and B and D are N-by-N upper triangular matrices. And plot twist: either B or D can be quasi upper triangular as well. The right hand sides E, F and the solutions R, L are all M-by-N matrices. Typically the matrix pencils (A,C) and (B,D) (or (D,B)) are the ones SGGES from LAPACK hands you. iconic behavior honestly.
So equation (1) is the dual to the generalized coupled Sylvester equation:
op1(A) * R + SGN1 * L * op2(B) = SCALE * E (2)
op1(C) * R + SGN2 * L * op2(D) = SCALE * F
And it's the dual one to equation (2) with respect to the underlying linear system, fr fr. Let Z be the matrix you get by rewriting (2) into its Kronecker form. That gives you:
| kron(I, op1(A)) SGN1*kron(op2(B)**T, I) | | Vec R | | Vec E |
Z X = | |*| | = | |
| kron(I, op1(C)) SGN2*kron(op2(D)**T, I) | | Vec L | | Vec F |
And looking at Z**T you get:
| kron(I, op1(A)**T ) kron(I, op1(C)**T) | | Vec R | | Vec E |
Z**T X = | |*| | = | |
| SGN1*kron(op2(B), I) SGN2*kron(op2(D), I) | | Vec L | | Vec F |
which belongs to the Sylvester equation (1). π That's literally why the parameters TRANSA and TRANSB are expressed in terms of the Sylvester equation (2). iykyk.
β¨ Remarks β¨
The algorithm is implemented using BLAS level 2 operations plus hand written optimizations, and it uses local copies of the input data. For this reason M and N are limited to 32. Also, the algorithm uses alignment of the local arrays if this is supported by the compiler. At the moment this is used with ifort and xlf but not with gfortran. π
π Parameters π
TRANSAβ isCHARACTER(1). Specifies the form of the system of equations with respect toAandC:== 'N':op1(A) = A,op1(C) = C(No transpose for A and C)== 'T':op1(A) = A**T,op1(C) = C **T(Transpose A and C)
TRANSBβ isCHARACTER(1). Specifies the form of the system of equations with respect toBandD:== 'N':op2(B) = B,op2(D) = D(No transpose for B and D)== 'T':op2(B) = B**T,op2(D) = D **T(Transpose B and D)
SGN1β isREAL, allowed values:+/-1. Specifies the sign between in the first equation.SGN2β isREAL, allowed values:+/-1. Specifies the sign between in the second equation.Mβ isINTEGER. The order of the matricesAandC.32 >= M >= 0.Nβ isINTEGER. The order of the matricesBandD.32 >= N >= 0.Aβ isREAL array, dimension(LDA,M). The matrixAmust be (quasi-) upper triangular.LDAβ isINTEGER. The leading dimension of the arrayA.LDA >= max(1,M).Bβ isREAL array, dimension(LDB,N). The matrixBmust be (quasi-) upper triangular. If the matrixDis already quasi-upper triangular the matrixBmust be upper triangular.LDBβ isINTEGER. The leading dimension of the arrayB.LDB >= max(1,N).Cβ isREAL array, dimension(LDC,M). The matrixCmust be upper triangular.LDCβ isINTEGER. The leading dimension of the arrayC.LDC >= max(1,M).Dβ isREAL array, dimension(LDD,N). The matrixDmust be (quasi-) upper triangular. If the matrixBis already quasi-upper triangular the matrixDmust be upper triangular.LDDβ isINTEGER. The leading dimension of the arrayD.LDD >= max(1,N).Eβ isREAL array, dimension(LDE,N). On input, the matrixEcontains the right hand sideE. On output, the matrixEcontains the solutionRof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand sideEand the solutionRare M-by-N matrices.LDEβ isINTEGER. The leading dimension of the arrayE.LDE >= max(1,M).Fβ isREAL array, dimension(LDF,N). On input, the matrixFcontains the right hand sideF. On output, the matrixFcontains the solutionLof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand sideFand the solutionLare M-by-N matrices.LDFβ isINTEGER. The leading dimension of the arrayF.LDE >= max(1,M).SCALEβ isREAL.SCALEis a scaling factor to prevent the overflow in the result. IfINFO == 0thenSCALEis1.0otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true.WORKβ isREAL array, dimensionLWORK. Workspace for the algorithm. The workspace needs to queried before the running the computation. The query is performed by calling the subroutine withINFO == -1on input. The required workspace is then returned inINFO.INFOβ isINTEGER.- On input:
== -1 :Perform a workspace query<> -1:normal operation
- On exit, workspace query:
< 0 :ifINFO = -i, the i-th argument had an illegal value>= 0:The value ofINFOis the required number of elements in the workspace.
- On exit, normal operation:
== 0:successful exit< 0:ifINFO = -i, the i-th argument had an illegal value> 0:The equation is not solved correctly. One of the arising inner system got singular.
- On input:
π Optimizations: π
- Replaced SAXPY operation by Fortran intrinsic
- No BLAS calls.
- Input data is copied to local arrays to increase the data locality if used from inside a level-3 solver.
- The local copies are aligned to 64 byte if supported by the compiler.
π Author π
Martin Koehler, MPI Magdeburg
π Date π
October 2025
π Definition π
At line 247 of file sla_tgcsylv_dual_l2_opt_local_copy_32.f90.
π sla_tgcsylv_dual_l2_local_copy_64
subroutine sla_tgcsylv_dual_l2_local_copy_64 ( transa, transb, sgn1,
sgn2, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f,
ldf, scale, work, info)
Level-2 Kagstroem-Westin/Bartels-Stewart Algorithm for the dual generalized coupled Sylvester equation (Local Copy) π¦
Purpose:
Okay so this whole thing is the doc block for SLA_TGCSYLV_DUAL_L2_LOCAL_COPY_64 β lemme finish that equation breakdown for you bestie, we were literally mid-sentence π
!> SLA_TGCSYLV_DUAL_L2_LOCAL_COPY_64 solves a generalized coupled Sylvester equation of the following form
!>
!> op1(A)**T * R + op1(C)**T * L = SCALE * E (1)
!> SGN1 * R * op2(B)**T + SGN2 * L * op2(D)** T = SCALE * F
!>
!> where A is a M-by-M quasi upper triangular matrix, C is a M-by-M upper triangular
!> matrix and B and D are N-by-N upper triangular matrices. Furthermore either B or
!> D can be quasi upper triangular as well. The right hand sides E, F and the solutions R, L are
!> M-by-N matrices. Typically the matrix pencils (A,C) and (B,D) ( or (D,B) ) are
!> created by SGGES from LAPACK.
!> The equation (1) is the dual to the generalized coupled Sylvester equation
!>
!> op1(A) * R + SGN1 * L * op2(B) = SCALE * E (2)
!> op1(C) * R + SGN2 * L * op2(D) = SCALE * F
!>
!> The equation (1) is the dual one to equation (2) with respect to the underlying linear system.
!> Let Z be the matrix formed by rewriting (2) into its Kronecker form. This yields
!>
!> | kron(I, op1(A)) SGN1*kron(op2(B)**T, I) | | Vec R | | Vec E |
!> Z X = | |*| | = | |
!> | kron(I, op1(C)) SGN2*kron(op2(D)**T, I) | | Vec L | | Vec F |
!>
!> Regarding Z**T one obtains
!>
!> | kron(I, op1(A)**T ) kron(I, op1(C)**T) | | Vec R | | Vec E |
!> Z**T X = | |*| | = | |
!> | SGN1*kron(op2(B), I) SGN2*kron(op2(D), I) | | Vec L | | Vec F |
!>
!> which belongs to the Sylvester equation (1). For this reason the parameters TRANSA and TRANSB
!> are expressed in terms of the Sylvester equation (2).
!>
!>
So basically Z is just equation (2) in its Kron form, and the transpose Z**T is giving... equation (1) β¨ That's the whole "dual" thing, that's why TRANSA and TRANSB get described in terms of equation (2) even though we're out here solving (1). iykyk π¦
πΈ Remarks πΈ
The algorithm is implemented using BLAS level 2 operations and hand written optimizations, and it uses local copies of the input data. For this reason M and N are limited to 64 π (yes, sixty-four, that's the ceiling bestie). Furthermore, the algorithm uses alignment of the local arrays if this is supported by the compiler. At the moment this is used with ifort and xlf but not with gfortran π
β¨ Parameters β¨
TRANSAβ isCHARACTER(1). Specifies the form of the system of equations with respect toAandC:== 'N': op1(A) = A, op1(C) = C (No transpose for A and C)== 'T': op1(A) = A**T, op1(C) = C **T (Transpose A and C)
TRANSBβ isCHARACTER(1). Specifies the form of the system of equations with respect toBandD:== 'N': op2(B) = B, op2(D) = D (No transpose for B and D)== 'T': op2(B) = B**T, op2(D) = D **T (Transpose B and D)
SGN1β isREAL, allowed values:+/-1. Specifies the sign between in the first equation. π₯SGN2β isREAL, allowed values:+/-1. Specifies the sign between in the second equation. π₯Mβ isINTEGER. The order of the matricesAandC.64 >= M >= 0.Nβ isINTEGER. The order of the matricesBandD.64 >= N >= 0.Aβ isREAL array, dimension (LDA,M). The matrixAmust be (quasi-) upper triangular.LDAβ isINTEGER. The leading dimension of the arrayA.LDA >= max(1,M).Bβ isREAL array, dimension (LDB,N). The matrixBmust be (quasi-) upper triangular. If the matrixDis already quasi-upper triangular the matrixBmust be upper triangular. πLDBβ isINTEGER. The leading dimension of the arrayB.LDB >= max(1,N).Cβ isREAL array, dimension (LDC,M). The matrixCmust be upper triangular.LDCβ isINTEGER. The leading dimension of the arrayC.LDC >= max(1,M).Dβ isREAL array, dimension (LDD,N). The matrixDmust be (quasi-) upper triangular. If the matrixBis already quasi-upper triangular the matrixDmust be upper triangular. πLDDβ isINTEGER. The leading dimension of the arrayD.LDD >= max(1,N).Eβ isREAL array, dimension (LDE,N). On input, the matrixEcontains the right hand sideE. On output, the matrixEcontains the solutionRof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand sideEand the solutionRareM-by-Nmatrices. π«ΆLDEβ isINTEGER. The leading dimension of the arrayE.LDE >= max(1,M).Fβ isREAL array, dimension (LDF,N). On input, the matrixFcontains the right hand sideF. On output, the matrixFcontains the solutionLof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand sideFand the solutionLareM-by-Nmatrices. π«ΆLDFβ isINTEGER. The leading dimension of the arrayF.LDE >= max(1,M). (yes bestie, that saysLDEin the original, we don't fix typos in the manpage, we report them π)SCALEβ isREAL.SCALEis a scaling factor to prevent the overflow in the result. IfINFO == 0thenSCALEis1.0otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true.WORKβ isREAL array, dimension LWORK. Workspace for the algorithm. The workspace needs to queried before the running the computation. The query is performed by calling the subroutine withINFO == -1on input. The required workspace is then returned inINFO. πINFOβ isINTEGER.- On input:
== -1 : Perform a workspace query<> -1: normal operation
- On exit, workspace query:
< 0 : if INFO = -i, the i-th argument had an illegal value>= 0: The value of INFO is the required number of elements in the workspace.
- On exit, normal operation:
== 0: successful exit< 0: if INFO = -i, the i-th argument had an illegal value> 0: The equation is not solved correctly. One of the arising inner system got singular.π
- On input:
π Optimizations π
- Replaced
SAXPYoperation by Fortran intrinsic - No BLAS calls.
- Input data is copied to local arrays to increase the data locality if used from inside a level-3 solver.
- The local copies are aligned to
64byte if supported by the compiler.
π Author π
Martin Koehler, MPI Magdeburg
β Date β
October 2025
Definition at line 246 of file sla_tgcsylv_dual_l2_opt_local_copy_64.f90.
okay and now we're meeting the next subroutine, the ninety-six one, bestie, she's coming in hot π
subroutine sla_tgcsylv_dual_l2_local_copy_96 ( transa, transb, sgn1,
sgn2, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f,
ldf, scale, work, info)
Level-2 Kagstroem-Westin/Bartels-Stewart Algorithm for the dual generalized coupled Sylvester equation (Local Copy)
Purpose:
π« SLA_TGCSYLV_DUAL_L2_LOCAL_COPY_96 π«
okay bestie so this one solves a generalized coupled Sylvester equation and it looks like this:
op1(A)**T * R + op1(C)**T * L = SCALE * E (1)
SGN1 * R * op2(B)**T + SGN2 * L * op2(D)** T = SCALE * F
where A is a M-by-M quasi upper triangular matrix, C is a M-by-M upper triangular matrix, and B and D are N-by-N upper triangular matrices. Also β plot twist β either B or D can be quasi upper triangular too π«Ά. The right hand sides E, F and the solutions R, L are M-by-N matrices. Typically the matrix pencils (A,C) and (B,D) (or (D,B)) are created by SGGES from LAPACK.
Equation (1) is the dual to the generalized coupled Sylvester equation
op1(A) * R + SGN1 * L * op2(B) = SCALE * E (2)
op1(C) * R + SGN2 * L * op2(D) = SCALE * F
and equation (1) is the dual one to equation (2) with respect to the underlying linear system. Let Z be the matrix formed by rewriting (2) into its Kronecker form. That gives you:
| kron(I, op1(A)) SGN1*kron(op2(B)**T, I) | | Vec R | | Vec E |
Z X = | |*| | = | |
| kron(I, op1(C)) SGN2*kron(op2(D)**T, I) | | Vec L | | Vec F |
and if you look at Z**T you get
| kron(I, op1(A)**T ) kron(I, op1(C)**T) | | Vec R | | Vec E |
Z**T X = | |*| | = | |
| SGN1*kron(op2(B), I) SGN2*kron(op2(D), I) | | Vec L | | Vec F |
which belongs to the Sylvester equation (1). That's literally why the parameters TRANSA and TRANSB are expressed in terms of the Sylvester equation (2) β¨. iykyk.
πΈ Remarks πΈ
The algorithm is implemented using BLAS level 2 operations and hand written optimizations, and it uses local copies of the input data. Because of that, M and N are limited to 96. On top of that, the algorithm uses alignment of the local arrays if this is supported by the compiler. At the moment this is used with ifort and xlf but not with gfortran.
π Parameters π
TRANSAβTRANSAisCHARACTER(1). Specifies the form of the system of equations with respect toAandC:== 'N':op1(A) = A,op1(C) = C(No transpose forAandC)== 'T':op1(A) = A**T,op1(C) = C **T(TransposeAandC)
TRANSBβTRANSBisCHARACTER(1). Specifies the form of the system of equations with respect toBandD:== 'N':op2(B) = B,op2(D) = D(No transpose forBandD)== 'T':op2(B) = B**T,op2(D) = D **T(TransposeBandD)
SGN1βSGN1isREAL, allowed values:+/-1. Specifies the sign between in the first equation.SGN2βSGN2isREAL, allowed values:+/-1. Specifies the sign between in the second equation.MβMisINTEGER. The order of the matricesAandC.96 >= M >= 0.NβNisINTEGER. The order of the matricesBandD.96 >= N >= 0.AβAisREALarray, dimension(LDA,M). The matrixAmust be (quasi-) upper triangular.LDAβLDAisINTEGER. The leading dimension of the arrayA.LDA >= max(1,M).BβBisREALarray, dimension(LDB,N). The matrixBmust be (quasi-) upper triangular. If the matrixDis already quasi-upper triangular the matrixBmust be upper triangular.LDBβLDBisINTEGER. The leading dimension of the arrayB.LDB >= max(1,N).CβCisREALarray, dimension(LDC,M). The matrixCmust be upper triangular.LDCβLDCisINTEGER. The leading dimension of the arrayC.LDC >= max(1,M).DβDisREALarray, dimension(LDD,N). The matrixDmust be (quasi-) upper triangular. If the matrixBis already quasi-upper triangular the matrixDmust be upper triangular.LDDβLDDisINTEGER. The leading dimension of the arrayD.LDD >= max(1,N).EβEisREALarray, dimension(LDE,N). On input, the matrixEcontains the right hand sideE. On output, the matrixEcontains the solutionRof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand sideEand the solutionRare M-by-N matrices.LDEβLDEisINTEGER. The leading dimension of the arrayE.LDE >= max(1,M).FβFisREALarray, dimension(LDF,N). On input, the matrixFcontains the right hand sideF. On output, the matrixFcontains the solutionLof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand sideFand the solutionLare M-by-N matrices.LDFβLDFisINTEGER. The leading dimension of the arrayF.LDE >= max(1,M).SCALEβSCALEisREAL.SCALEis a scaling factor to prevent the overflow in the result. IfINFO == 0thenSCALEis1.0otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true.WORKβWORKisREALarray, dimensionLWORK. Workspace for the algorithm. The workspace needs to queried before the running the computation. The query is performed by calling the subroutine withINFO == -1on input. The required workspace is then returned inINFO.INFOβINFOisINTEGER.- On input:
== -1 :Perform a workspace query<> -1:normal operation
- On exit, workspace query:
< 0 :ifINFO = -i, the i-th argument had an illegal value>= 0:The value ofINFOis the required number of elements in the workspace.
- On exit, normal operation:
== 0:successful exit< 0:ifINFO = -i, the i-th argument had an illegal value> 0:The equation is not solved correctly. One of the arising inner system got singular.
- On input:
π₯ Optimizations: π₯
- Replaced
SAXPYoperation by Fortran intrinsic - No BLAS calls.
- Input data is copied to local arrays to increase the data locality if used from inside a level-3 solver.
- The local copies are aligned to 64 byte if supported by the compiler.
π Author π
Martin Koehler, MPI Magdeburg
π Date π
October 2025
Definition at line 246 of file sla_tgcsylv_dual_l2_opt_local_copy_96.f90.
β¨ subroutine sla_tgcsylv_dual_l3 β¨
subroutine sla_tgcsylv_dual_l3 (character, dimension(1) transa, character,
dimension(1) transb, real sgn1, real sgn2, integer m, integer n, real,
dimension(lda, *) a, integer lda, real, dimension(ldb, *) b, integer
ldb, real, dimension(ldc, *) c, integer ldc, real, dimension(ldd, *) d,
integer ldd, real, dimension(lde, *) e, integer lde, real,
dimension(ldf,*) f, integer ldf, real scale, real, dimension(*) work,
integer info)
Level-3 Kagstroem-Westin/Bartels-Stewart Algorithm for the dual generalized coupled Sylvester equation.
π― Purpose: π―
Which is literally the dual of the generalized coupled Sylvester equation
op1(A) * R + SGN1 * L * op2(B) = SCALE * E (2)
op1(C) * R + SGN2 * L * op2(D) = SCALE * F
and bestie, "dual" here is a technical thing, not a vibe thing π . It means equation (1) is the dual of equation (2) with respect to the underlying linear system. Let Z be the matrix you get when you rewrite (2) into its Kronecker form. That gives you
| kron(I, op1(A)) SGN1*kron(op2(B)**T, I) | | Vec R | | Vec E |
Z X = | |*| | = | |
| kron(I, op1(C)) SGN2*kron(op2(D)**T, I) | | Vec L | | Vec F |
and then if you look at Z**T instead, you get
| kron(I, op1(A)**T ) kron(I, op1(C)**T) | | Vec R | | Vec E |
Z**T X = | |*| | = | |
| SGN1*kron(op2(B), I) SGN2*kron(op2(D), I) | | Vec L | | Vec F |
which β plot twist π«’ β belongs to the Sylvester equation (1). So that's why the parameters TRANSA and TRANSB are expressed in terms of the Sylvester equation (2). iykyk π§
π Parameters π
TRANSAβ isCHARACTER(1). It says what form the system of equations takes with respect toAandC:== 'N':op1(A) = A,op1(C) = C(no transpose forAandC)== 'T':op1(A) = A**T,op1(C) = C **T(transposeAandC)
TRANSBβ isCHARACTER(1). It says what form the system of equations takes with respect toBandD:== 'N':op2(B) = B,op2(D) = D(no transpose forBandD)== 'T':op2(B) = B**T,op2(D) = D **T(transposeBandD)
SGN1β isREAL, allowed values:+/-1. It specifies the sign between in the first equation. β¨SGN2β isREAL, allowed values:+/-1. It specifies the sign between in the second equation. β¨Mβ isINTEGER. The order of the matricesAandC.M >= 0.Nβ isINTEGER. The order of the matricesBandD.N >= 0.Aβ isREAL array, dimension(LDA,M). The matrixAmust be (quasi-) upper triangular. πLDAβ isINTEGER. The leading dimension of the arrayA.LDA >= max(1,M).Bβ isREAL array, dimension(LDB,N). The matrixBmust be (quasi-) upper triangular. If the matrixDis already quasi-upper triangular the matrixBmust be upper triangular. π¦LDBβ isINTEGER. The leading dimension of the arrayB.LDB >= max(1,N).Cβ isREAL array, dimension(LDC,M). The matrixCmust be upper triangular.LDCβ isINTEGER. The leading dimension of the arrayC.LDC >= max(1,M).Dβ isREAL array, dimension(LDD,N). The matrixDmust be (quasi-) upper triangular. If the matrixBis already quasi-upper triangular the matrixDmust be upper triangular. π¦LDDβ isINTEGER. The leading dimension of the arrayD.LDD >= max(1,N).Eβ isREAL array, dimension(LDE,N). On input, the matrixEcontains the right hand sideE. On output, the matrixEcontains the solutionRof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand sideEand the solutionRareM-by-Nmatrices. it literally transforms in place, no cap β¨LDEβ isINTEGER. The leading dimension of the arrayE.LDE >= max(1,M).Fβ isREAL array, dimension(LDF,N). On input, the matrixFcontains the right hand sideF. On output, the matrixFcontains the solutionLof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand sideFand the solutionLareM-by-Nmatrices. same energy asE, fr fr β¨LDFβ isINTEGER. The leading dimension of the arrayF.LDE >= max(1,M). π«Ά (yes, bestie, that's exactly what it says β I'm just the messenger)SCALEβ isREAL.SCALEis a scaling factor to prevent the overflow in the result. IfINFO == 0thenSCALEis1.0, otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true.WORKβ isREAL array, dimensionLWORK. Workspace for the algorithm. The workspace needs to queried before the running the computation. The query is performed by calling the subroutine withINFO == -1on input. The required workspace is then returned inINFO. π₯INFOβ isINTEGER.- On input:
== -1: Perform a workspace query<> -1: normal operation
- On exit, workspace query:
< 0: ifINFO = -i, thei-th argument had an illegal value>= 0: The value ofINFOis the required number of elements in the workspace.
- On exit, normal operation:
== 0: successful exit π< 0: ifINFO = -i, thei-th argument had an illegal value> 0: The equation is not solved correctly. One of the arising inner system got singular. π
- On input:
πΈ Author πΈ
Martin Koehler, MPI Magdeburg
π Date π
October 2025
Definition at line 236 of file sla_tgcsylv_dual_l3.f90.
π¦ subroutine sla_tgcsylv_dual_l3_2s π¦
subroutine sla_tgcsylv_dual_l3_2s (character, dimension(1) transa,
character, dimension(1) transb, real sgn1, real sgn2, integer m, integer
n, real, dimension(lda, *) a, integer lda, real, dimension(ldb, *) b,
integer ldb, real, dimension(ldc, *) c, integer ldc, real,
dimension(ldd, *) d, integer ldd, real, dimension(lde, *) e, integer
lde, real, dimension(ldf,*) f, integer ldf, real scale, real,
dimension(*) work, integer info)
Level-3 Kagstroem-Westin/Bartels-Stewart Algorithm with sub blocking for the dual generalized coupled Sylvester equation.
π― Purpose π―
okay so real quick, bestie, let me tell you what SLA_TGCSYLV_DUAL_L3_2S actually solves π β it takes on a generalized coupled Sylvester equation shaped like this:
op1(A)**T * R + op1(C)**T * L = SCALE * E (1)
SGN1 * R * op2(B)**T + SGN2 * L * op2(D)** T = SCALE * F
where, and stay with me here:
Ais a M-by-M quasi upper triangular matrix πCis a M-by-M upper triangular matrixBandDare N-by-N upper triangular matrices πΈ- and either
BorDcan be quasi upper triangular as well, so slay, flexible
The right hand sides E, F and the solutions R, L are all M-by-N matrices. Typically the matrix pencils (A,C) and (B,D) (or (D,B)) are created by SGGES from LAPACK β iykyk π§
Equation (1) is the dual to the generalized coupled Sylvester equation:
op1(A) * R + SGN1 * L * op2(B) = SCALE * E (2)
op1(C) * R + SGN2 * L * op2(D) = SCALE * F
Like, equation (1) is the dual one to equation (2) with respect to the underlying linear system. Let Z be the matrix formed by rewriting (2) into its Kronecker form. That gives you:
| kron(I, op1(A)) SGN1*kron(op2(B)**T, I) | | Vec R | | Vec E |
Z X = | |*| | = | |
| kron(I, op1(C)) SGN2*kron(op2(D)**T, I) | | Vec L | | Vec F |
And then, regarding Z**T, you obtain:
| kron(I, op1(A)**T ) kron(I, op1(C)**T) | | Vec R | | Vec E |
Z**T X = | |*| | = | |
| SGN1*kron(op2(B), I) SGN2*kron(op2(D), I) | | Vec L | | Vec F |
which belongs to the Sylvester equation (1). And that's literally why the parameters TRANSA and TRANSB are expressed in terms of the Sylvester equation (2), not (1) β no cap, that's the whole plot twist π
β¨ Parameters β¨
TRANSAβTRANSAisCHARACTER(1). It specifies the form of the system of equations with respect toAandC:== 'N':op1(A) = A,op1(C) = C(no transpose forAandC)== 'T':op1(A) = A**T,op1(C) = C **T(transposeAandC)
TRANSBβTRANSBisCHARACTER(1). It specifies the form of the system of equations with respect toBandD:== 'N':op2(B) = B,op2(D) = D(no transpose forBandD)== 'T':op2(B) = B**T,op2(D) = D **T(transposeBandD)
SGN1βSGN1isREAL, allowed values:+/-1. Specifies the sign between in the first equation πSGN2βSGN2isREAL, allowed values:+/-1. Specifies the sign between in the second equation πMβMisINTEGER. The order of the matricesAandC.M >= 0.NβNisINTEGER. The order of the matricesBandD.N >= 0.AβAisREAL array, dimension(LDA,M). The matrixAmust be (quasi-) upper triangular. πLDAβLDAisINTEGER. The leading dimension of the arrayA.LDA >= max(1,M).BβBisREAL array, dimension(LDB,N). The matrixBmust be (quasi-) upper triangular. If the matrixDis already quasi-upper triangular the matrixBmust be upper triangular. (yes, it's a whole trade-off situation π«Ά)LDBβLDBisINTEGER. The leading dimension of the arrayB.LDB >= max(1,N).CβCisREAL array, dimension(LDC,M). The matrixCmust be upper triangular.LDCβLDCisINTEGER. The leading dimension of the arrayC.LDC >= max(1,M).DβDisREAL array, dimension(LDD,N). The matrixDmust be (quasi-) upper triangular. If the matrixBis already quasi-upper triangular the matrixDmust be upper triangular.LDDβLDDisINTEGER. The leading dimension of the arrayD.LDD >= max(1,N).EβEisREAL array, dimension(LDE,N).- On input, the matrix
Econtains the right hand sideE. - On output, the matrix
Econtains the solutionRof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. - Right hand side
Eand the solutionRare M-by-N matrices. π¦
- On input, the matrix
LDEβLDEisINTEGER. The leading dimension of the arrayE.LDE >= max(1,M).FβFisREAL array, dimension(LDF,N).- On input, the matrix
Fcontains the right hand sideF. - On output, the matrix
Fcontains the solutionLof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. - Right hand side
Fand the solutionLare M-by-N matrices. π¦
- On input, the matrix
LDFβLDFisINTEGER. The leading dimension of the arrayF.LDE >= max(1,M).SCALEβSCALEisREAL.SCALEis a scaling factor to prevent the overflow in the result. IfINFO == 0thenSCALEis1.0otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true. tiny SCALE = the math was fighting for its life πWORKβWORKisREAL array, dimensionLWORK. Workspace for the algorithm. The workspace needs to queried before the running the computation. The query is performed by calling the subroutine withINFO == -1on input. The required workspace is then returned inINFO. (peep theINFOblock below, bestie, it's all connected)INFOβINFOisINTEGER.- On input:
== -1: Perform a workspace query<> -1: normal operation
- On exit, workspace query:
< 0: ifINFO = -i, the i-th argument had an illegal value>= 0: The value ofINFOis the required number of elements in the workspace.
- On exit, normal operation:
== 0: successful exit β¨< 0: ifINFO = -i, the i-th argument had an illegal value> 0: The equation is not solved correctly. One of the arising inner system got singular. π
- On input:
ngl the workspace query thing is iconic β you literally call the routine withINFO == -1, it tells you how muchWORKto bring, and then you actually run it. main character energy fr fr π
π Author π
Martin Koehler, MPI Magdeburg
πΈ Date πΈ
October 2025
β Definition β
Definition at line 237 of file sla_tgcsylv_dual_l3_2stage.f90.
π recursive subroutine sla_tgcsylv_dual_recursive π
okay so here's the signature, and yes she's long, she's worth it:
recursive subroutine sla_tgcsylv_dual_recursive (character, dimension(1)
transa, character, dimension(1) transb, real sgn1, real sgn2, integer m,
integer n, real, dimension(lda, *) a, integer lda, real, dimension(ldb,
*) b, integer ldb, real, dimension(ldc, *) c, integer ldc, real,
dimension(ldd, *) d, integer ldd, real, dimension(lde, *) e, integer
lde, real, dimension(ldf,*) f, integer ldf, real scale, real,
dimension(*) work, integer info)
Recursive blocking Algorithm for the dual generalized coupled Sylvester equation. π
Purpose:
okay bestie, we're deep in the SLA_TGCSYLV_DUAL_RECURSIVE zone and the math is giving β¨
SLA_TGCSYLV_DUAL_RECURSIVE solves a generalized coupled Sylvester equation shaped like this π
op1(A)**T * R + op1(C)**T * L = SCALE * E (1)
SGN1 * R * op2(B)**T + SGN2 * L * op2(D)** T = SCALE * F
okay so let's break that down, because it's a lot π
Ais a M-by-M quasi upper triangular matrixCis a M-by-M upper triangular matrixBandDare N-by-N upper triangular matrices- and either
BorDcan be quasi upper triangular as well (not both being weird at the same time, iykyk) - the right hand sides
E,Fand the solutionsR,Lare all M-by-N matrices - typically the matrix pencils
(A,C)and(B,D)(or(D,B)) are created bySGGESfrom LAPACK π«Ά
Equation (1) is the dual to the generalized coupled Sylvester equation π
op1(A) * R + SGN1 * L * op2(B) = SCALE * E (2)
op1(C) * R + SGN2 * L * op2(D) = SCALE * F
Equation (1) is the dual one to equation (2) with respect to the underlying linear system. Let Z be the matrix formed by rewriting (2) into its Kronecker form. This yields π
| kron(I, op1(A)) SGN1*kron(op2(B)**T, I) | | Vec R | | Vec E |
Z X = | |*| | = | |
| kron(I, op1(C)) SGN2*kron(op2(D)**T, I) | | Vec L | | Vec F |
Regarding Z**T one obtains π
| kron(I, op1(A)**T ) kron(I, op1(C)**T) | | Vec R | | Vec E |
Z**T X = | |*| | = | |
| SGN1*kron(op2(B), I) SGN2*kron(op2(D), I) | | Vec L | | Vec F |
which belongs to the Sylvester equation (1). For this reason the parameters TRANSA and TRANSB are expressed in terms of the Sylvester equation (2). mind = blown π€―
TRANSAβTRANSAisCHARACTER(1). It specifies the form of the system of equations with respect toAandC:== 'N':op1(A) = A,op1(C) = C(No transpose forAandC)== 'T':op1(A) = A**T,op1(C) = C **T(TransposeAandC)
TRANSBβTRANSBisCHARACTER(1). It specifies the form of the system of equations with respect toBandD:== 'N':op2(B) = B,op2(D) = D(No transpose forBandD)== 'T':op2(B) = B**T,op2(D) = D **T(TransposeBandD)
SGN1βSGN1isREAL, allowed values:+/-1. Specifies the sign between in the first equation. β¨SGN2βSGN2isREAL, allowed values:+/-1. Specifies the sign between in the second equation. β¨MβMisINTEGER. The order of the matricesAandC.M >= 0. πNβNisINTEGER. The order of the matricesBandD.N >= 0. πAβAisREALarray, dimension(LDA,M). The matrixAmust be (quasi-) upper triangular.LDAβLDAisINTEGER. The leading dimension of the arrayA.LDA >= max(1,M).BβBisREALarray, dimension(LDB,N). The matrixBmust be (quasi-) upper triangular. If the matrixDis already quasi-upper triangular the matrixBmust be upper triangular. πLDBβLDBisINTEGER. The leading dimension of the arrayB.LDB >= max(1,N).CβCisREALarray, dimension(LDC,M). The matrixCmust be upper triangular.LDCβLDCisINTEGER. The leading dimension of the arrayC.LDC >= max(1,M).DβDisREALarray, dimension(LDD,N). The matrixDmust be (quasi-) upper triangular. If the matrixBis already quasi-upper triangular the matrixDmust be upper triangular. πLDDβLDDisINTEGER. The leading dimension of the arrayD.LDD >= max(1,N).EβEisREALarray, dimension(LDE,N). On input, the matrixEcontains the right hand sideE. On output, the matrixEcontains the solutionRof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand sideEand the solutionRareM-by-Nmatrices. πΈLDEβLDEisINTEGER. The leading dimension of the arrayE.LDE >= max(1,M).FβFisREALarray, dimension(LDF,N). On input, the matrixFcontains the right hand sideF. On output, the matrixFcontains the solutionLof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand sideFand the solutionLareM-by-Nmatrices. πΈLDFβLDFisINTEGER. The leading dimension of the arrayF.LDE >= max(1,M).
ngl, that's literally what the page says β it talks aboutLDEin theLDFentry π keeping it exactly as written, no cap.
SCALEβSCALEisREAL.SCALEis a scaling factor to prevent the overflow in the result. IfINFO == 0thenSCALEis1.0otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true. π₯WORKβWORKisREALarray, dimensionLWORK. Workspace for the algorithm. The workspace needs to queried before the running the computation. The query is performed by calling the subroutine withINFO == -1on input. The required workspace is then returned inINFO. π οΈINFOβINFOisINTEGER.- On input:
== -1: Perform a workspace query<> -1: normal operation
- On exit, workspace query:
< 0: ifINFO = -i, the i-th argument had an illegal value>= 0: The value ofINFOis the required number of elements in the workspace.
- On exit, normal operation:
== 0: successful exit π< 0: ifINFO = -i, the i-th argument had an illegal value> 0: The equation is not solved correctly. One of the arising inner system got singular. π
- On input:
π Author
Martin Koehler, MPI Magdeburg
ποΈ Date
October 2025
π Definition
Definition at line 240 of file sla_tgcsylv_dual_recursive.f90.
and now, plot twist, a whole other subroutine walks in π
subroutine sla_tgcsylv_l2 (character, dimension(1) transa, character,
dimension(1) transb, real sgn1, real sgn2, integer m, integer n, real,
dimension(lda, *) a, integer lda, real, dimension(ldb, *) b, integer
ldb, real, dimension(ldc, *) c, integer ldc, real, dimension(ldd, *) d,
integer ldd, real, dimension(lde, *) e, integer lde, real,
dimension(ldf,*) f, integer ldf, real scale, real, dimension(*) work,
integer info)
Level-2 Kagstroem-Westin/Bartels Algorithm for the generalized coupled Sylvester equation (Optimized) β¨
Purpose:
Remarks
The algorithm is implemented using BLAS level 2 operations and hand written optimizations. π β¨
Parameters
TRANSAβTRANSAisCHARACTER(1). It specifies the form of the system of equations with respect to A and C:== 'N':op1(A) = A, op1(C) = C(No transpose for A and C) π== 'T':op1(A) = A**T, op1(C) = C **T(Transpose A and C) π₯
TRANSBβTRANSBisCHARACTER(1). It specifies the form of the system of equations with respect to B and D:== 'N':op2(B) = B, op2(D) = D(No transpose for B and D) πΈ== 'T':op2(B) = B**T, op2(D) = D **T(Transpose B and D) π«
SGN1βSGN1isREAL, allowed values:+/-1. Specifies the sign between in the first equation. (Yes, "between in" is literally what it says, bestie. We keep it exactly.) π«ΆSGN2βSGN2isREAL, allowed values:+/-1. Specifies the sign between in the second equation. (Same energy.) πMβMisINTEGER. The order of the matrices A and C.M >= 0. πNβNisINTEGER. The order of the matrices B and D.N >= 0. πAβAisREALarray, dimension(LDA,M). The matrix A must be (quasi-) upper triangular. (Don't try to sneak in a lower triangular, it won't slay.) πLDAβLDAisINTEGER. The leading dimension of the array A.LDA >= max(1,M). πBβBisREALarray, dimension(LDB,N). The matrix B must be (quasi-) upper triangular. If the matrix D is already quasi-upper triangular the matrix B must be upper triangular. (So like, one of them can be quasi, but if D is quasi then B has to be strictly upper triangular. The drama.) πLDBβLDBisINTEGER. The leading dimension of the array B.LDB >= max(1,N). πCβCisREALarray, dimension(LDC,M). The matrix C must be upper triangular. (No quasi here, bestie. Just upper triangular.) π¦LDCβLDCisINTEGER. The leading dimension of the array C.LDC >= max(1,M). πDβDisREALarray, dimension(LDD,N). The matrix D must be (quasi-) upper triangular. If the matrix B is already quasi-upper triangular the matrix D must be upper triangular. (Same energy as B, but for D.) πLDDβLDDisINTEGER. The leading dimension of the array D.LDD >= max(1,N). πEβEisREALarray, dimension(LDE,N). On input, the matrix E contains the right hand side E. On output, the matrix E contains the solution R of Equation (1) as selected by TRANSA, TRANSB, and SGN1/SGN2. Right hand side E and the solution R are M-by-N matrices. (It goes in as E, comes out as R. Glow up.) β¨LDEβLDEisINTEGER. The leading dimension of the array E.LDE >= max(1,M). πFβFisREALarray, dimension(LDF,N). On input, the matrix F contains the right hand side F. On output, the matrix F contains the solution L of Equation (1) as selected by TRANSA, TRANSB, and SGN1/SGN2. Right hand side F and the solution L are M-by-N matrices. πLDFβLDFisINTEGER. The leading dimension of the array F.LDE >= max(1,M). (Wait, it saysLDE >= max(1,M)for LDF? That's a typo in the original, bestie. We keep it exactly.) πSCALEβSCALEisREAL. SCALE is a scaling factor to prevent the overflow in the result. IfINFO == 0then SCALE is1.0otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true. πWORKβWORKisREALarray, dimensionLWORK. Workspace for the algorithm. The workspace needs to queried before the running the computation. The query is performed by calling the subroutine withINFO == -1on input. The required workspace is then returned in INFO. π§°INFOβINFOisINTEGER. On input:== -1: Perform a workspace query π<> -1: normal operation π οΈ On exit, workspace query:< 0: ifINFO = -i, the i-th argument had an illegal value π±>= 0: The value of INFO is the required number of elements in the workspace. π¦ On exit, normal operation:== 0: successful exit π< 0: ifINFO = -i, the i-th argument had an illegal value π> 0: The equation is not solved correctly. One of the arising inner system got singular. π
Optimizations
- Replaced level-3 by level-2 and level-1 calls,
- Replaced SAXPY operation by Fortran intrinsic
- Replaced all BLAS calls except of SGER by Fortran intrinsic,
Author
Martin Koehler, MPI Magdeburg
Date
October 2025
Definition
Definition at line 225 of file sla_tgcsylv_l2.f90.
subroutine sla_tgcsylv_l2_local_copy
subroutine sla_tgcsylv_l2_local_copy (character, dimension(1) transa,
character, dimension(1) transb, real sgn1, real sgn2, integer m, integer
n, real, dimension(lda, *) a, integer lda, real, dimension(ldb, *) b,
integer ldb, real, dimension(ldc, *) c, integer ldc, real,
dimension(ldd, *) d, integer ldd, real, dimension(lde, *) e, integer
lde, real, dimension(ldf,*) f, integer ldf, real scale, real,
dimension(*) work, integer info)
Level-2 Kagstroem-Westin/Bartels-Stewart Algorithm for the generalized coupled Sylvester equation (Optimized) π
Purpose:
okay so SLA_TGCSYLV_L2_LOCAL_COPY solves a generalized coupled Sylvester equation, and it looks exactly like this:
op1(A) * R + SGN1 * L * op2(B) = SCALE * E (1)
op1(C) * R + SGN2 * L * op2(D) = SCALE * F
where A is a M-by-M quasi upper triangular matrix, C is a M-by-M upper triangular matrix, and B and D are N-by-N upper triangular matrices. And not only that β either B or D can be quasi upper triangular as well. The right hand side Y and the solution X are M-by-N matrices. Typically the matrix pencils (A,C) and (B,D) (or (D,B)) are created by SGGES from LAPACK. bestie the LAPACK pipeline is real π
Remarks
The algorithm is implemented using BLAS level 2 operations and hand written optimizations. no cap, hand written, iconic behavior β¨
Parameters
TRANSAβTRANSAisCHARACTER(1). It specifies the form of the system of equations with respect to A and C:== 'N':op1(A) = A,op1(C) = C(No transpose for A and C)== 'T':op1(A) = A**T,op1(C) = C **T(Transpose A and C)
TRANSBβTRANSBisCHARACTER(1). It specifies the form of the system of equations with respect to B and D:== 'N':op2(B) = B,op2(D) = D(No transpose for B and D)== 'T':op2(B) = B**T,op2(D) = D **T(Transpose B and D)
SGN1βSGN1isREAL, allowed values:+/-1. It specifies the sign between in the first equation.SGN2βSGN2isREAL, allowed values:+/-1. It specifies the sign between in the second equation.MβMisINTEGER. The order of the matrices A and C.M >= 0.NβNisINTEGER. The order of the matrices B and D.N >= 0.AβAisREALarray, dimension(LDA,M). The matrix A must be (quasi-) upper triangular.LDAβLDAisINTEGER. The leading dimension of the array A.LDA >= max(1,M).BβBisREALarray, dimension(LDB,N). The matrix B must be (quasi-) upper triangular. If the matrix D is already quasi-upper triangular the matrix B must be upper triangular.LDBβLDBisINTEGER. The leading dimension of the array B.LDB >= max(1,N).CβCisREALarray, dimension(LDC,M). The matrix C must be upper triangular.LDCβLDCisINTEGER. The leading dimension of the array C.LDC >= max(1,M).DβDisREALarray, dimension(LDD,N). The matrix D must be (quasi-) upper triangular. If the matrix B is already quasi-upper triangular the matrix D must be upper triangular.LDDβLDDisINTEGER. The leading dimension of the array D.LDD >= max(1,N).EβEisREALarray, dimension(LDE,N).- On input, the matrix E contains the right hand side E.
- On output, the matrix E contains the solution R of Equation (1) as selected by
TRANSA,TRANSB, andSGN1/SGN2. - On output, the matrix E contains the solution R of Equation (1) as selected by
TRANSA,TRANSB, andSGN1/SGN2. (yes bestie the doc literally says this twice β we are not editing, we are β¨preservingβ¨ π«Ά) - Right hand side E and the solution R are M-by-N matrices.
LDEβLDEisINTEGER. The leading dimension of the array E.LDE >= max(1,M).FβFisREALarray, dimension(LDF,N). On input, the matrix F contains the right hand side F. On output, the matrix F contains the solution L of Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand side F and the solution L are M-by-N matrices.LDFβLDFisINTEGER. The leading dimension of the array F.LDE >= max(1,M). (that is genuinely what it says βLDE, notLDF. we are just the messengers π)SCALEβSCALEisREAL.SCALEis a scaling factor to prevent the overflow in the result. IfINFO == 0thenSCALEis1.0otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true.WORKβWORKisREALarray, dimensionLWORK. Workspace for the algorithm. The workspace needs to queried before the running the computation. The query is performed by calling the subroutine withINFO == -1on input. The required workspace is then returned inINFO.INFOβINFOisINTEGER.- On input:
== -1: Perform a workspace query<> -1: normal operation
- On exit, workspace query:
< 0: ifINFO = -i, the i-th argument had an illegal value>= 0: The value ofINFOis the required number of elements in the workspace.
- On exit, normal operation:
== 0: successful exit< 0: ifINFO = -i, the i-th argument had an illegal value> 0: The equation is not solved correctly. One of the arising inner system got singular.
- On input:
Optimizations:
- Replaced level-3 by level-2 and level-1 calls,
- Reorder the solution order to column first style,
- Replaced SAXPY operation by Fortran intrinsic
- Replaced all BLAS calls except of STRMV and SGER by Fortran intrinsic,
- Use local copies of A, B, C, D, E, and F (M, N <=128) .
Author
Martin Koehler, MPI Magdeburg
Date
October 2025
Definition at line 227 of file sla_tgcsylv_l2_opt_local_copy.f90.
π¦ sla_tgcsylv_l2_local_copy_128 π¦
subroutine sla_tgcsylv_l2_local_copy_128 ( transa, transb, sgn1, sgn2,
m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf,
scale, work, info)
Level-2 Kagstroem-Westin/Bartels-Stewart Algorithm for the generalized coupled Sylvester equation (Optimized)
Purpose:
okay so this one? this one is the _128 girlie. she does SLA_TGCSYLV_L2_LOCAL_COPY_128 and she solves a generalized coupled Sylvester equation that looks like this: β¨
op1(A) * R + SGN1 * L * op2(B) = SCALE * E (1)
op1(C) * R + SGN2 * L * op2(D) = SCALE * F
where A is a M-by-M quasi upper triangular matrix, C is a M-by-M upper triangular matrix, and B and D are N-by-N upper triangular matrices. also, ngl, either B or D can be quasi upper triangular as well. the right hand side is Y and the solution is X, both M-by-N matrices. typically the matrix pencils (A,C) and (B,D) (or (D,B)) are made by SGGES from LAPACK. π
πΈ Remarks πΈ
the algorithm is implemented using BLAS level 2 operations plus hand written optimizations and aligned local copies. periodt.
β¨ Parameters β¨
here comes the whole cast, bestie. every single one:
TRANSAβTRANSAisCHARACTER(1). it specifies the form of the system of equations with respect toAandC:== 'N':op1(A) = A,op1(C) = C(no transpose forAandC)== 'T':op1(A) = A**T,op1(C) = C **T(transposeAandC)
TRANSBβTRANSBisCHARACTER(1). it specifies the form of the system of equations with respect toBandD:== 'N':op2(B) = B,op2(D) = D(no transpose forBandD)== 'T':op2(B) = B**T,op2(D) = D **T(transposeBandD)
SGN1βSGN1isREAL, allowed values:+/-1. it specifies the sign between in the first equation.SGN2βSGN2isREAL, allowed values:+/-1. it specifies the sign between in the second equation.MβMisINTEGER. the order of the matricesAandC.128 => M >= 0.NβNisINTEGER. the order of the matricesBandD.128 >= N >= 0.AβAisREALarray, dimension(LDA,M). the matrixAmust be (quasi-) upper triangular.LDAβLDAisINTEGER. the leading dimension of the arrayA.LDA >= max(1,M).BβBisREALarray, dimension(LDB,N). the matrixBmust be (quasi-) upper triangular. if the matrixDis already quasi-upper triangular the matrixBmust be upper triangular.LDBβLDBisINTEGER. the leading dimension of the arrayB.LDB >= max(1,N).CβCisREALarray, dimension(LDC,M). the matrixCmust be upper triangular.LDCβLDCisINTEGER. the leading dimension of the arrayC.LDC >= max(1,M).DβDisREALarray, dimension(LDD,N). the matrixDmust be (quasi-) upper triangular. if the matrixBis already quasi-upper triangular the matrixDmust be upper triangular.LDDβLDDisINTEGER. the leading dimension of the arrayD.LDD >= max(1,N).EβEisREALarray, dimension(LDE,N). on input, the matrixEcontains the right hand sideE. on output, the matrixEcontains the solutionRof Equation (1) β (yeah bestie it says it twice in the source, so it says it twice here too, we don't gatekeep) β on output, the matrixEcontains the solutionRof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. right hand sideEand the solutionRare M-by-N matrices.LDEβLDEisINTEGER. the leading dimension of the arrayE.LDE >= max(1,M).FβFisREALarray, dimension(LDF,N). on input, the matrixFcontains the right hand sideF. on output, the matrixFcontains the solutionLof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. right hand sideFand the solutionLare M-by-N matrices.LDFβLDFisINTEGER. the leading dimension of the arrayF.LDE >= max(1,M). (yes. it saysLDEhere. in theLDFentry. iconic of it honestly.)SCALEβSCALEisREAL.SCALEis a scaling factor to prevent the overflow in the result. ifINFO == 0thenSCALEis1.0, otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true.WORKβWORKisREALarray, dimensionLWORK. workspace for the algorithm. the workspace needs to be queried before running the computation. the query is performed by calling the subroutine withINFO == -1on input. the required workspace is then returned inINFO.INFOβINFOisINTEGER.- on input:
== -1: perform a workspace query<> -1: normal operation
- on exit, workspace query:
< 0: ifINFO = -i, the i-th argument had an illegal value>= 0: the value ofINFOis the required number of elements in the workspace.
- on exit, normal operation:
== 0: successful exit< 0: ifINFO = -i, the i-th argument had an illegal value> 0: the equation is not solved correctly. one of the arising inner system got singular. (that's the "we tried, bestie" exit π)
- on input:
π Optimizations: π
the glow-up list. she ate:
- replaced level-3 by level-2 and level-1 calls,
- reorder the solution order to column first style,
- replaced
SAXPYoperation by Fortran intrinsic - replaced all BLAS calls except of
STRMVandSGERby Fortran intrinsic, - align local copies and fix problem size to
<= 128
π¦ Author π¦
Martin Koehler, MPI Magdeburg π«Ά
π Date π
October 2025 β¨
Definition at line 225 of file sla_tgcsylv_l2_opt_local_copy_128.f90.
and now, entering the chat: the _32 version. same energy, smaller alignment vibe π
subroutine sla_tgcsylv_l2_local_copy_32 ( transa, transb, sgn1, sgn2, m,
n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale,
work, info)
Level-2 Kagstroem-Westin/Bartels-Stewart Algorithm for the generalized coupled Sylvester equation (Optimized)
Purpose:
WORKβWORKis aREALarray, dimensionLWORK. It's the workspace for the algorithm, bestie, and you gotta query it before you run the computation. How? Call the subroutine withINFO == -1on input, and the required workspace gets handed back to you inINFO. It's giving "ask before you order" energy. πINFOβINFOisINTEGER. She's got two modes and you need to know both, no cap:
On input:
== -1: perform a workspace query π΅οΈ<> -1: normal operation
On exit, workspace query:
< 0: ifINFO = -i, the i-th argument had an illegal value π>= 0: the value ofINFOis the required number of elements in the workspace β¨
On exit, normal operation:
== 0: successful exit, slay π< 0: ifINFO = -i, the i-th argument had an illegal value> 0: the equation is not solved correctly. One of the arising inner system got singular π
β¨ Optimizations: β¨
- Replaced level-3 by level-2 and level-1 calls,
- Reorder the solution order to column first style,
- Replaced
SAXPYoperation by Fortran intrinsic - Replaced all BLAS calls except of
STRMVandSGERby Fortran intrinsic, - Align local copies and fix problem size to
<= 32
π Author
Martin Koehler, MPI Magdeburg
ποΈ Date
October 2025
π Definition
At line 226 of file sla_tgcsylv_l2_opt_local_copy_32.f90.
subroutine sla_tgcsylv_l2_local_copy_64 ( transa, transb, sgn1, sgn2, m,
n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale,
work, info)
Level-2 Kagstroem-Westin/Bartels-Stewart Algorithm for the generalized coupled Sylvester equation (Optimized) π¦
πΈ Purpose:
TRANSAβ this one'sCHARACTER(1), bestie, and it decides what shape the equations take on the A-and-C side π'N'βop1(A) = A,op1(C) = C(no transpose for A and C, we're keeping it natural β¨)'T'βop1(A) = A**T,op1(C) = C **T(transpose A and C, flip it and reverse it π¦)
TRANSBβ alsoCHARACTER(1), and it does the exact same job but for B and D π'N'βop2(B) = B,op2(D) = D(no transpose for B and D)'T'βop2(B) = B**T,op2(D) = D **T(transpose B and D)
SGN1βREAL, and the only allowed values are+/-1. It specifies the sign between in the first equation π₯SGN2βREAL, allowed values+/-1again. It specifies the sign between in the second equation π₯MβINTEGER. The order of the matrices A and C.64 => M >= 0πNβINTEGER. The order of the matrices B and D.64 >= N >= 0πΈAβREALarray, dimension(LDA,M). The matrix A must be (quasi-) upper triangular, no exceptions, that's the whole vibe πLDAβINTEGER. The leading dimension of the array A.LDA >= max(1,M)βBβREALarray, dimension(LDB,N). The matrix B must be (quasi-) upper triangular. And listen: if the matrix D is already quasi-upper triangular, then the matrix B must be upper triangular. That's the deal, okay? π«ΆLDBβINTEGER. The leading dimension of the array B.LDB >= max(1,N)βCβREALarray, dimension(LDC,M). The matrix C must be upper triangular πLDCβINTEGER. The leading dimension of the array C.LDC >= max(1,M)βDβREALarray, dimension(LDD,N). The matrix D must be (quasi-) upper triangular. And same energy as B: if the matrix B is already quasi-upper triangular, then the matrix D must be upper triangular πLDDβINTEGER. The leading dimension of the array D.LDD >= max(1,N)βEβREALarray, dimension(LDE,N). On input, the matrix E contains the right hand side E. On output, the matrix E contains the solution R of Equation (1). On output, the matrix E contains the solution R of Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand side E and the solution R are M-by-N matrices. It literally swaps roles on you, main character behavior πLDEβINTEGER. The leading dimension of the array E.LDE >= max(1,M)βFβREALarray, dimension(LDF,N). On input, the matrix F contains the right hand side F. On output, the matrix F contains the solution L of Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand side F and the solution L are M-by-N matrices πLDFβINTEGER. The leading dimension of the array F.LDE >= max(1,M)βSCALEβREAL. It's a scaling factor to prevent the overflow in the result. IfINFO == 0then SCALE is1.0; otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true. So if it's not 1.0, something got messy πWORKβREALarray, dimensionLWORK. Workspace for the algorithm. And no cap: the workspace needs to be queried before running the computation. You do that query by calling the subroutine withINFO == -1on input, and the required workspace is then returned inINFO. Do the query, bestie, don't skip it πINFOβINTEGER
On input:
== -1β perform a workspace query<> -1β normal operation
On exit, workspace query:
< 0β ifINFO = -i, the i-th argument had an illegal value>= 0β the value of INFO is the required number of elements in the workspace
On exit, normal operation:
== 0β successful exit β¨< 0β ifINFO = -i, the i-th argument had an illegal value> 0β the equation is not solved correctly. One of the arising inner system got singular. π
β¨ Optimizations: β¨
- Replaced level-3 by level-2 and level-1 calls π₯
- Reorder the solution order to column first style π
- Replaced SAXPY operation by Fortran intrinsic β‘
- Replaced all BLAS calls except of STRMV and SGER by Fortran intrinsic πΈ
- Align local copies and fix problem size to
<= 64π
π Author π
Martin Koehler, MPI Magdeburg π«Ά
π Date π
October 2025
Definition at line 226 of file sla_tgcsylv_l2_opt_local_copy_64.f90.
subroutine sla_tgcsylv_l2_local_copy_96 ( transa, transb, sgn1, sgn2, m,
n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale,
work, info)
Level-2 Kagstroem-Westin/Bartels-Stewart Algorithm for the generalized coupled Sylvester equation (Optimized) π
Purpose:
SLA_TGCSYLV_L2_LOCAL_COPY_96</p> solves a generalized coupled Sylvester equation that looks like this, bestie:
op1(A) * R + SGN1 * L * op2(B) = SCALE * E (1)
op1(C) * R + SGN2 * L * op2(D) = SCALE * F
Where A is a M-by-M quasi upper triangular matrix, C is a M-by-M upper triangular matrix, and B and D are N-by-N upper triangular matrices. Also β plot twist β either B or D can be quasi upper triangular as well. The right hand side Y and the solution X are M-by-N matrices. Typically the matrix pencils (A,C) and (B,D) ( or (D,B) ) are created by SGGES from LAPACK. β¨
π Remarks π
The algorithm is implemented using BLAS level 2 operations and hand written optimizations and aligned local copies. (Yes, she hand-wrote her own optimizations. Iconic behaviour.)
π Parameters π
TRANSAβTRANSAisCHARACTER(1). It specifies the form of the system of equations with respect toAandC:== 'N':op1(A) = A,op1(C) = C(No transpose forAandC)== 'T':op1(A) = A**T,op1(C) = C **T(TransposeAandC)
TRANSBβTRANSBisCHARACTER(1). It specifies the form of the system of equations with respect toBandD:== 'N':op2(B) = B,op2(D) = D(No transpose forBandD)== 'T':op2(B) = B**T,op2(D) = D **T(TransposeBandD)
SGN1βSGN1isREAL, allowed values:+/-1. Specifies the sign between in the first equation. π«SGN2βSGN2isREAL, allowed values:+/-1. Specifies the sign between in the second equation. π«MβMisINTEGER. The order of the matricesAandC.96 => M >= 0.NβNisINTEGER. The order of the matricesBandD.96 >= N >= 0.AβAisREAL array, dimension(LDA,M). The matrixAmust be (quasi-) upper triangular.LDAβLDAisINTEGER. The leading dimension of the arrayA.LDA >= max(1,M).BβBisREAL array, dimension(LDB,N). The matrixBmust be (quasi-) upper triangular. If the matrixDis already quasi-upper triangular the matrixBmust be upper triangular. (Yeah, only one of them gets to be quasi. The universe said balance. βοΈ)LDBβLDBisINTEGER. The leading dimension of the arrayB.LDB >= max(1,N).CβCisREAL array, dimension(LDC,M). The matrixCmust be upper triangular.LDCβLDCisINTEGER. The leading dimension of the arrayC.LDC >= max(1,M).DβDisREAL array, dimension(LDD,N). The matrixDmust be (quasi-) upper triangular. If the matrixBis already quasi upper triangular the matrixDmust be upper triangular.LDDβLDDisINTEGER. The leading dimension of the arrayD.LDD >= max(1,N).EβEisREAL array, dimension(LDE,N). On input, the matrixEcontains the right hand sideE. On output, the matrixEcontains the solutionRof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand sideEand the solutionRareM-by-Nmatrices. πLDEβLDEisINTEGER. The leading dimension of the arrayE.LDE >= max(1,M).FβFisREAL array, dimension(LDF,N). On input, the matrixFcontains the right hand sideF. On output, the matrixFcontains the solutionLof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand sideFand the solutionLareM-by-Nmatrices. πLDFβLDFisINTEGER. The leading dimension of the arrayF.LDE >= max(1,M).SCALEβSCALEisREAL.SCALEis a scaling factor to prevent the overflow in the result. IfINFO == 0thenSCALEis1.0otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true.WORKβWORKisREAL array, dimensionLWORK. Workspace for the algorithm. The workspace needs to queried before the running the computation. The query is performed by calling the subroutine withINFO == -1on input. The required workspace is then returned inINFO. πINFOβINFOisINTEGER.- On input:
== -1: Perform a workspace query<> -1: normal operation
- On exit, workspace query:
< 0: ifINFO = -i, the i-th argument had an illegal value>= 0: The value ofINFOis the required number of elements in the workspace.
- On exit, normal operation:
== 0: successful exit< 0: ifINFO = -i, the i-th argument had an illegal value> 0: The equation is not solved correctly. One of the arising inner system got singular.
- On input:
bestie if you get INFO > 0 the vibes are rancid β an inner system went singular and the equation did not get solved correctly. Not a slay. π
π₯ Optimizations π₯
- Replaced level-3 by level-2 and level-1 calls,
- Reorder the solution order to column first style,
- Replaced SAXPY operation by Fortran intrinsic
- Replaced all BLAS calls except of STRMV and SGER by Fortran intrinsic,
- Align local copies and fix problem size to
<= 96
Author β Martin Koehler, MPI Magdeburg π«Ά
Date β October 2025
Definition at line 225 of file sla_tgcsylv_l2_opt_local_copy_96.f90.
π and nowβ¦ the next one π
subroutine sla_tgcsylv_l2_reorder (character, dimension(1) transa,
character, dimension(1) transb, real sgn1, real sgn2, integer m, integer
n, real, dimension(lda, *) a, integer lda, real, dimension(ldb, *) b,
integer ldb, real, dimension(ldc, *) c, integer ldc, real,
dimension(ldd, *) d, integer ldd, real, dimension(lde, *) e, integer
lde, real, dimension(ldf,*) f, integer ldf, real scale, real,
dimension(*) work, integer info)
Level-2 Kagstroem-Westin/Bartels-Stewart Algorithm for the generalized coupled Sylvester equation (Optimized)
π¦ Purpose π¦
okay so bestie, let's talk about what SLA_TGCSYLV_L2_REORDER actually does π
β it solves a generalized coupled Sylvester equation that looks like this:
op1(A) * R + SGN1 * L * op2(B) = SCALE * E (1)
op1(C) * R + SGN2 * L * op2(D) = SCALE * F
where A is a M-by-M quasi upper triangular matrix, C is a M-by-M upper triangular matrix and B and D are N-by-N upper triangular matrices. Furthermore either B or D can be quasi upper triangular as well. The right hand side Y and the solution X M-by-N matrices. Typically the matrix pencils (A,C) and (B,D) ( or (D,B) ) are created by SGGES from LAPACK.
(yeah the original literally says "the right hand side Y and the solution X M-by-N matrices" β we're keeping it exactly like that, no notes π)
π Remarks
The algorithm is implemented using BLAS level 2 operations and hand written optimizations. bestie said "I'll do it myself" and honestly? she ate π₯
β¨ Parameters
TRANSAβ isCHARACTER(1). Specifies the form of the system of equations with respect to A and C:== 'N':op1(A) = A,op1(C) = C(No transpose for A and C)== 'T':op1(A) = A**T,op1(C) = C **T(Transpose A and C)
TRANSBβ isCHARACTER(1). Specifies the form of the system of equations with respect to B and D:== 'N':op2(B) = B,op2(D) = D(No transpose for B and D)== 'T':op2(B) = B**T,op2(D) = D **T(Transpose B and D)
SGN1β isREAL, allowed values:+/-1. Specifies the sign between in the first equation.SGN2β isREAL, allowed values:+/-1. Specifies the sign between in the second equation.Mβ isINTEGER. The order of the matrices A and C.M >= 0.Nβ isINTEGER. The order of the matrices B and D.N >= 0.Aβ isREALarray, dimension(LDA,M). The matrix A must be (quasi-) upper triangular.LDAβ isINTEGER. The leading dimension of the array A.LDA >= max(1,M).Bβ isREALarray, dimension(LDB,N). The matrix B must be (quasi-) upper triangular. If the matrix D is already quasi-upper triangular the matrix B must be upper triangular.LDBβ isINTEGER. The leading dimension of the array B.LDB >= max(1,N).Cβ isREALarray, dimension(LDC,M). The matrix C must be upper triangular.LDCβ isINTEGER. The leading dimension of the array C.LDC >= max(1,M).Dβ isREALarray, dimension(LDD,N). The matrix D must be (quasi-) upper triangular. If the matrix B is already quasi-upper triangular the matrix D must be upper triangular.LDDβ isINTEGER. The leading dimension of the array D.LDD >= max(1,N).Eβ isREALarray, dimension(LDE,N). On input, the matrix E contains the right hand side E. On output, the matrix E contains the solution R of Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand side E and the solution R are M-by-N matrices.LDEβ isINTEGER. The leading dimension of the array E.LDE >= max(1,M).Fβ isREALarray, dimension(LDF,N). On input, the matrix F contains the right hand side F. On output, the matrix F contains the solution L of Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand side F and the solution L are M-by-N matrices.LDFβ isINTEGER. The leading dimension of the array F.LDE >= max(1,M).
heads up π«Ά β yes, that last one really does sayLDE >= max(1,M)in the source, notLDF. we are not fixing it, we are reporting it, periodt.
SCALEβ isREAL. SCALE is a scaling factor to prevent the overflow in the result. IfINFO == 0then SCALE is1.0otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true.WORKβ isREALarray, dimensionLWORK. Workspace for the algorithm. The workspace needs to queried before the running the computation. The query is performed by calling the subroutine withINFO == -1on input. The required workspace is then returned inINFO.INFOβ isINTEGER.- On input:
== -1: Perform a workspace query<> -1: normal operation
- On exit, workspace query:
< 0: ifINFO = -i, the i-th argument had an illegal value>= 0: The value ofINFOis the required number of elements in the workspace.
- On exit, normal operation:
== 0: successful exit< 0: ifINFO = -i, the i-th argument had an illegal value> 0: The equation is not solved correctly. One of the arising inner system got singular.
- On input:
π₯ Optimizations
- Replaced level-3 by level-2 and level-1 calls,
- Reorder the solution order to column first style,
- Replaced SAXPY operation by Fortran intrinsic
- Replaced all BLAS calls except of
STRMVandSGERby Fortran intrinsic, - Column first computation of the solution.
look at her go, hand-optimizing like the main character she is π
π Author
Martin Koehler, MPI Magdeburg
π Date
October 2025
Definition at line 226 of file sla_tgcsylv_l2_opt_reorder.f90.
πΈ sla_tgcsylv_l2_unopt
and now for the unoptimized sister version, because every queen needs a chill twin π¦
subroutine sla_tgcsylv_l2_unopt (character, dimension(1) transa, character,
dimension(1) transb, real sgn1, real sgn2, integer m, integer n, real,
dimension(lda, *) a, integer lda, real, dimension(ldb, *) b, integer
ldb, real, dimension(ldc, *) c, integer ldc, real, dimension(ldd, *) d,
integer ldd, real, dimension(lde, *) e, integer lde, real,
dimension(ldf,*) f, integer ldf, real scale, real, dimension(*) work,
integer info)
Level-2 Kagstroem-Westin/Bartels-Stewart Algorithm for the generalized coupled Sylvester equation (unoptimized)
Purpose:
...and the whole thing is basically: it solves the system without any of the fancy optimizations. π
π«Ά Attention π«Ά
The algorithm is implemented using BLAS level 2 operations without further optimizations. For a faster implementation see SLA_TGSYLV_L2. Translation: this one is the slow-and-steady version, bestie. It works! It's just not the glow-up version. β¨
π Parameters π
TRANSAβTRANSAisCHARACTER(1). It says what form the system of equations takes with respect toAandC:== 'N':op1(A) = A,op1(C) = C(no transpose forAandC)== 'T':op1(A) = A**T,op1(C) = C**T(transposeAandC)
TRANSBβTRANSBisCHARACTER(1). Same vibe check but forBandD:== 'N':op2(B) = B,op2(D) = D(no transpose forBandD)== 'T':op2(B) = B**T,op2(D) = D**T(transposeBandD)
SGN1βSGN1isREAL, allowed values:+/-1. This is the sign sitting between the two terms in the first equation. π«‘SGN2βSGN2isREAL, allowed values:+/-1. This is the sign sitting between the two terms in the second equation. π«‘MβMisINTEGER. The order of the matricesAandC.M >= 0. πNβNisINTEGER. The order of the matricesBandD.N >= 0. πAβAisREAL array, dimension (LDA,M). The matrixAmust be (quasi-) upper triangular. No cap. π¦LDAβLDAisINTEGER. The leading dimension of the arrayA.LDA >= max(1,M).BβBisREAL array, dimension (LDB,N). The matrixBmust be (quasi-) upper triangular. If the matrixDis already quasi-upper triangular, then the matrixBmust be upper triangular. It's giving "one of y'all has to be the chill one."LDBβLDBisINTEGER. The leading dimension of the arrayB.LDB >= max(1,N).CβCisREAL array, dimension (LDC,M). The matrixCmust be upper triangular. Periodt. πLDCβLDCisINTEGER. The leading dimension of the arrayC.LDC >= max(1,M).DβDisREAL array, dimension (LDD,N). The matrixDmust be (quasi-) upper triangular. If the matrixBis already quasi-upper triangular, then the matrixDmust be upper triangular. Same energy asB, mirrored. Iconic.LDDβLDDisINTEGER. The leading dimension of the arrayD.LDD >= max(1,N).EβEisREAL array, dimension (LDE,N).- On input, the matrix
Econtains the right hand sideE. - On output, the matrix
Econtains the solutionRof Equation (1), as selected byTRANSA,TRANSB, andSGN1/SGN2. - Right hand side
Eand the solutionRareM-by-Nmatrices. Glow-up moment: it goes in as a right hand side and comes out as a whole solution. π
- On input, the matrix
LDEβLDEisINTEGER. The leading dimension of the arrayE.LDE >= max(1,M).FβFisREAL array, dimension (LDF,N).- On input, the matrix
Fcontains the right hand sideF. - On output, the matrix
Fcontains the solutionLof Equation (1), as selected byTRANSA,TRANSB, andSGN1/SGN2. - Right hand side
Fand the solutionLareM-by-Nmatrices. Same transformation arc, different letter. π¦
- On input, the matrix
LDFβLDFisINTEGER. The leading dimension of the arrayF.LDE >= max(1,M). (yes, that's what it says βLDEβ we are reporting it exactly, not fixing it, that's the rule bestie π)SCALEβSCALEisREAL. It's a scaling factor to prevent overflow in the result. IfINFO == 0thenSCALEis1.0; otherwise, if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true. So ifSCALEisn't 1, something in the inside got a little wobbly. πWORKβWORKisREAL array, dimension LWORK. Workspace for the algorithm. The workspace needs to be queried before running the computation. The query is performed by calling the subroutine withINFO == -1on input. The required workspace is then returned inINFO. Ask before you take β always query first, bestie. β¨INFOβINFOisINTEGER.
On input:
== -1: perform a workspace query<> -1: normal operation
On exit, workspace query:
< 0: ifINFO = -i, thei-th argument had an illegal value>= 0: the value ofINFOis the required number of elements in the workspace
On exit, normal operation:
== 0: successful exit π< 0: ifINFO = -i, thei-th argument had an illegal value> 0: the equation is not solved correctly. One of the arising inner systems got singular. Not the singular inner system. Not today. π
β¨ Optimizations: β¨
- Nothing. π«
That's it. That's the optimizations section. "Nothing." A whole bullet point for it. Slay in the most cursed way possible.
π Author π
Martin Koehler, MPI Magdeburg
π Date π
October 2025
π Definition π
At line 225 of file sla_tgcsylv_l2_unopt.f90.
π¦ And now... presenting... sla_tgcsylv_l3 π¦
subroutine sla_tgcsylv_l3 (character, dimension(1) transa, character,
dimension(1) transb, real sgn1, real sgn2, integer m, integer n, real,
dimension(lda, *) a, integer lda, real, dimension(ldb, *) b, integer
ldb, real, dimension(ldc, *) c, integer ldc, real, dimension(ldd, *) d,
integer ldd, real, dimension(lde, *) e, integer lde, real,
dimension(ldf,*) f, integer ldf, real scale, real, dimension(*) work,
integer info)
Level-3 Kagstroem-Westin/Bartels-Stewart Algorithm for the generalized coupled Sylvester equation (optimized) π₯
Yes bestie, THIS is the optimized one. The glow-up. The main character. The _l3. π
π Purpose: π
π Attention
The algorithm is implemented using BLAS level 3 operations. That's the whole vibe. Fast, chunky, blocky, slay. β¨
π Parameters
πΈ TRANSA
TRANSA is CHARACTER(1) and it says what form the system takes with respect to A and C:
== 'N':op1(A) = A,op1(C) = C(no transpose forAandC)== 'T':op1(A) = A**T,op1(C) = C **T(transposeAandC)
π¦ TRANSB
TRANSB is CHARACTER(1) and it says what form the system takes with respect to B and D:
== 'N':op2(B) = B,op2(D) = D(no transpose forBandD)== 'T':op2(B) = B**T,op2(D) = D **T(transposeBandD)
β¨ SGN1
SGN1 is REAL, allowed values: +/-1. It specifies the sign between in the first equation. Lowkey just a lil plus or minus, bestie. π
π SGN2
SGN2 is REAL, allowed values: +/-1. It specifies the sign between in the second equation. Same energy as SGN1, different equation. π«Ά
π M
M is INTEGER. It's the order of the matrices A and C. M >= 0.
π N
N is INTEGER. It's the order of the matrices B and D. N >= 0.
π A
A is REAL array, dimension (LDA,M). The matrix A must be (quasi-) upper triangular. No exceptions, fr fr.
β LDA
LDA is INTEGER. It's the leading dimension of the array A. LDA >= max(1,M).
π B
B is REAL array, dimension (LDB,N). The matrix B must be (quasi-) upper triangular. And here's the plot twist: if the matrix D is already quasi-upper triangular, then the matrix B must be upper triangular. Iconic mutual-exclusion moment. π
π§ LDB
LDB is INTEGER. It's the leading dimension of the array B. LDB >= max(1,N).
πΈ C
C is REAL array, dimension (LDC,M). The matrix C must be upper triangular.
π LDC
LDC is INTEGER. It's the leading dimension of the array C. LDC >= max(1,M).
π¦ D
D is REAL array, dimension (LDD,N). The matrix D must be (quasi-) upper triangular. And the mirror of before: if the matrix B is already quasi-upper triangular, then the matrix D must be upper triangular. It's giving "only one of you gets to be quasi at a time." π
π LDD
LDD is INTEGER. It's the leading dimension of the array D. LDD >= max(1,N).
π E
E is REAL array, dimension (LDE,N).
- On input, the matrix
Econtains the right hand sideE. - On output, the matrix
Econtains the solutionRof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2.
Right hand side E and the solution R are M-by-N matrices. Glow-up arc tbh. β¨
β LDE
LDE is INTEGER. It's the leading dimension of the array E. LDE >= max(1,M).
π F
F is REAL array, dimension (LDF,N).
- On input, the matrix
Fcontains the right hand sideF. - On output, the matrix
Fcontains the solutionLof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2.
Right hand side F and the solution L are M-by-N matrices. Twin flame behaviour with E. π
π§ LDF
LDF is INTEGER. It's the leading dimension of the array F. LDE >= max(1,M).
Okay bestie, real talk, that last one saysLDE >= max(1,M)in the original β notLDF. Not me pointing it out, the page literally says that. Keeping it exactly as written because facts don't change even when the typo has main character energy. π
π SCALE
SCALE is REAL. SCALE is a scaling factor to prevent the overflow in the result. If INFO == 0 then SCALE is 1.0, otherwise if one of the inner systems could not be solved correctly, 0 < SCALE <= 1 holds true. It's the safety net keeping your numbers from absolutely losing it. π«Ά
πΈ WORK
WORK is REAL array, dimension LWORK. Workspace for the algorithm.
The workspace needs to be queried before running the computation. The query is performed by calling the subroutine with INFO == -1 on input. The required workspace is then returned in INFO. Yes bestie, you have to ask first. π
π INFO
INFO is INTEGER.
On input:
== -1: perform a workspace query<> -1: normal operation
On exit, workspace query:
< 0: ifINFO = -i, the i-th argument had an illegal value>= 0: the value ofINFOis the required number of elements in the workspace
On exit, normal operation:
== 0: successful exit π< 0: ifINFO = -i, the i-th argument had an illegal value> 0: the equation is not solved correctly. One of the arising inner system got singular. π
β‘ Optimizations:
- Nothing but standard L3 BLAS calls. Clean, no tricks, just blocks.
- Changed computation order to column major. β¨
βοΈ Author
Martin Koehler, MPI Magdeburg
π Date
October 2025
π Definition
At line 223 of file sla_tgcsylv_l3_opt.f90.
π«§ subroutine sla_tgcsylv_l3_2s
subroutine sla_tgcsylv_l3_2s (character, dimension(1) transa, character,
dimension(1) transb, real sgn1, real sgn2, integer m, integer n, real,
dimension(lda, *) a, integer lda, real, dimension(ldb, *) b, integer
ldb, real, dimension(ldc, *) c, integer ldc, real, dimension(ldd, *) d,
integer ldd, real, dimension(lde, *) e, integer lde, real,
dimension(ldf,*) f, integer ldf, real scale, real, dimension(*) work,
integer info)
Level-3 Kagstroem-Westin/Bartels-Stewart Algorithm for the generalized coupled Sylvester equation (optimized)
π Purpose:
okay bestie so SLA_TGCSYLV_L3_2S solves a generalized coupled Sylvester equation that looks exactly like this π
op1(A) * R + SGN1 * L * op2(B) = SCALE * E (1)
op1(C) * R + SGN2 * L * op2(D) = SCALE * F
where A is a M-by-M quasi upper triangular matrix, C is a M-by-M upper triangular matrix, and B and D are N-by-N upper triangular matrices. And likeβ¦ either B or D can be quasi upper triangular as well π«Ά. The right hand side Y and the solution X are M-by-N matrices. Typically the matrix pencils (A,C) and (B,D) ( or (D,B) ) are created by SGGES from LAPACK. that's just the lore, iykyk β¨
β¨ Remarks β¨
This algorithm uses 2 Stage blocking with DAG scheduled solves. that's the whole flex, no cap π
β¨ Parameters β¨
TRANSAβCHARACTER(1). Tells you the form of the system of equations with respect toAandC: if it's'N'thenop1(A) = A,op1(C) = C(no transpose for A and C), and if it's'T'thenop1(A) = A**T,op1(C) = C **T(transpose A and C). pick your fighter β¨TRANSBβCHARACTER(1). Same energy but forBandD:'N'gives youop2(B) = B,op2(D) = D(no transpose for B and D),'T'gives youop2(B) = B**T,op2(D) = D **T(transpose B and D).SGN1βREAL, allowed values:+/-1. It's the sign between in the first equation. literally just a plus or minus, she's simple like that πSGN2βREAL, allowed values:+/-1. The sign between in the second equation. same vibe, second equation π¦MβINTEGER. The order of the matricesAandC.M >= 0.NβINTEGER. The order of the matricesBandD.N >= 0.AβREALarray, dimension(LDA,M). The matrixAmust be (quasi-) upper triangular. no exceptions bestie πLDAβINTEGER. The leading dimension of the arrayA.LDA >= max(1,M).BβREALarray, dimension(LDB,N). The matrixBmust be (quasi-) upper triangular. But heads up: if the matrixDis already quasi-upper triangular, then the matrixBmust be upper triangular πLDBβINTEGER. The leading dimension of the arrayB.LDB >= max(1,N).CβREALarray, dimension(LDC,M). The matrixCmust be upper triangular. periodt.LDCβINTEGER. The leading dimension of the arrayC.LDC >= max(1,M).DβREALarray, dimension(LDD,N). The matrixDmust be (quasi-) upper triangular. And same deal asB: if the matrixBis already quasi-upper triangular, thenDmust be upper triangular π«ΆLDDβINTEGER. The leading dimension of the arrayD.LDD >= max(1,N).EβREALarray, dimension(LDE,N). On input,Eholds the right hand sideE. On output,Eholds the solutionRof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. The right hand sideEand the solutionRare M-by-N matrices. she does a little glow-up in place πLDEβINTEGER. The leading dimension of the arrayE.LDE >= max(1,M).FβREALarray, dimension(LDF,N). On input,Fholds the right hand sideF. On output,Fholds the solutionLof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand sideFand the solutionLare M-by-N matrices. same transformation arc, slay β¨LDFβINTEGER. The leading dimension of the arrayF.LDE >= max(1,M). (yes, it literally saysLDEin the source, we do not fix, we do not question π)SCALEβREAL. It's a scaling factor to prevent the overflow in the result. IfINFO == 0thenSCALEis1.0, otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true. so if you see a tiny scale, something was struggling πWORKβREALarray, dimensionLWORK. Workspace for the algorithm. And listen: the workspace needs to queried before the running the computation. The query is performed by calling the subroutine withINFO == -1on input. The required workspace is then returned inINFO. so you gotta ask before you act, main character energy πINFOβINTEGER.- On input:
== -1: Perform a workspace query<> -1: normal operation
- On exit, workspace query:
< 0: ifINFO = -i, the i-th argument had an illegal value>= 0: The value ofINFOis the required number of elements in the workspace.
- On exit, normal operation:
== 0: successful exit< 0: ifINFO = -i, the i-th argument had an illegal value> 0: The equation is not solved correctly. One of the arising inner system got singular.
- On input:
bestie if INFO > 0 comes back at you, the equation did not get solved correctly β one of the arising inner systems went singular. do not ignore her, she is telling you something π₯
βοΈ Author
Martin Koehler, MPI Magdeburg
ποΈ Date
October 2025
Definition at line 217 of file sla_tgcsylv_l3_2stage.f90. π«
π¦ sla_tgcsylv_l3_unopt
okay and then there's this one:
subroutine sla_tgcsylv_l3_unopt (character, dimension(1) transa, character,
dimension(1) transb, real sgn1, real sgn2, integer m, integer n, real,
dimension(lda, *) a, integer lda, real, dimension(ldb, *) b, integer
ldb, real, dimension(ldc, *) c, integer ldc, real, dimension(ldd, *) d,
integer ldd, real, dimension(lde, *) e, integer lde, real,
dimension(ldf,*) f, integer ldf, real scale, real, dimension(*) work,
integer info)
Level-3 Kagstroem-Westin/Bartels-Stewart Algorithm for the generalized coupled Sylvester equation (unoptimized) π§
Purpose:
okay bestie</p> so SLA_TGCSYLV_L3_UNOPT π
is the one that solves a generalized coupled Sylvester equation, and it looks like this:
op1(A) * R + SGN1 * L * op2(B) = SCALE * E (1)
op1(C) * R + SGN2 * L * op2(D) = SCALE * F
where A is a M-by-M quasi upper triangular matrix, C is a M-by-M upper triangular matrix, and B and D are N-by-N upper triangular matrices. And listen β either B or D can be quasi upper triangular too, it's flexible like that β¨. The right hand side Y and the solution X are M-by-N matrices. Typically the matrix pencils (A,C) and (B,D) (or (D,B)) are the ones made by SGGES from LAPACK π«Ά.
Attention β οΈ
The algorithm is implemented using BLAS level 3 operations. slay.
Parameters π
TRANSAβTRANSAisCHARACTER(1). It says what form the system of equations takes with respect toAandC:== 'N':op1(A) = A,op1(C) = C(no transpose forAandC)== 'T':op1(A) = A**T,op1(C) = C **T(transposeAandC)
TRANSBβTRANSBisCHARACTER(1). It says what form the system of equations takes with respect toBandD:== 'N':op2(B) = B,op2(D) = D(no transpose forBandD)== 'T':op2(B) = B**T,op2(D) = D **T(transposeBandD)
SGN1βSGN1isREAL, allowed values:+/-1. Specifies the sign between in the first equation. (yes, that's literally what it says, bestie, it's the sign thing in equation one π)SGN2βSGN2isREAL, allowed values:+/-1. Specifies the sign between in the second equation.MβMisINTEGER. The order of the matricesAandC.M >= 0.NβNisINTEGER. The order of the matricesBandD.N >= 0.AβAisREAL array, dimension(LDA,M). The matrixAmust be (quasi-) upper triangular. no cap.LDAβLDAisINTEGER. The leading dimension of the arrayA.LDA >= max(1,M).BβBisREAL array, dimension(LDB,N). The matrixBmust be (quasi-) upper triangular. If the matrixDis already quasi-upper triangular, the matrixBmust be upper triangular. πLDBβLDBisINTEGER. The leading dimension of the arrayB.LDB >= max(1,N).CβCisREAL array, dimension(LDC,M). The matrixCmust be upper triangular.LDCβLDCisINTEGER. The leading dimension of the arrayC.LDC >= max(1,M).DβDisREAL array, dimension(LDD,N). The matrixDmust be (quasi-) upper triangular. If the matrixBis already quasi-upper triangular, the matrixDmust be upper triangular. πLDDβLDDisINTEGER. The leading dimension of the arrayD.LDD >= max(1,N).EβEisREAL array, dimension(LDE,N). On input, the matrixEcontains the right hand sideE. On output, the matrixEcontains the solutionRof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand sideEand the solutionRareM-by-Nmatrices. β¨LDEβLDEisINTEGER. The leading dimension of the arrayE.LDE >= max(1,M).FβFisREAL array, dimension(LDF,N). On input, the matrixFcontains the right hand sideF. On output, the matrixFcontains the solutionLof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. Right hand sideFand the solutionLareM-by-Nmatrices.LDFβLDFisINTEGER. The leading dimension of the arrayF.LDE >= max(1,M). (yes bestie it saysLDEthere in the original, we do not "fix" it, we simply report it π)SCALEβSCALEisREAL.SCALEis a scaling factor to prevent the overflow in the result. IfINFO == 0thenSCALEis1.0, otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true. π«ΆWORKβWORKisREAL array, dimensionLWORK. Workspace for the algorithm. The workspace needs to be queried before running the computation. The query is performed by calling the subroutine withINFO == -1on input. The required workspace is then returned inINFO. iykyk πINFOβINFOisINTEGER.- On input:
== -1: Perform a workspace query<> -1: normal operation
- On exit, workspace query:
< 0: ifINFO = -i, the i-th argument had an illegal value>= 0: The value ofINFOis the required number of elements in the workspace.
- On exit, normal operation:
== 0: successful exit π< 0: ifINFO = -i, the i-th argument had an illegal value> 0: The equation is not solved correctly. One of the arising inner system got singular. π
- On input:
Optimizations: π₯
- Nothing but standard L3 BLAS calls.
Author πΈ
Martin Koehler, MPI Magdeburg
Date π¦
October 2025
Definition π
At line 223 of file sla_tgcsylv_l3_unopt.f90.
and now, bestie, meet the next icon β here's the signature, verbatim, no touchy:
recursive subroutine sla_tgcsylv_recursive (character, dimension(1) transa,
character, dimension(1) transb, real sgn1, real sgn2, integer m, integer
n, real, dimension(lda, *) a, integer lda, real, dimension(ldb, *) b,
integer ldb, real, dimension(ldc, *) c, integer ldc, real,
dimension(ldd, *) d, integer ldd, real, dimension(lde, *) e, integer
lde, real, dimension(ldf,*) f, integer ldf, real scale, real,
dimension(*) work, integer info)
Recursive Algorithm for the generalized coupled Sylvester equation. β¨
Purpose:
TRANSAβ it's aCHARACTER(1), bestie, and it tells us what form the system is in forAandC:'N':op1(A) = A,op1(C) = Cβ no transpose, we're keeping it natural π'T':op1(A) = A**T,op1(C) = C **Tβ transposingAandC, flipping the whole vibe
TRANSBβ also aCHARACTER(1), but this one handlesBandD:'N':op2(B) = B,op2(D) = Dβ no transpose forBandD, as-is, iconic'T':op2(B) = B**T,op2(D) = D **Tβ transposeBandD, rotate the fit π
SGN1β aREAL, allowed values:+/-1. It's the sign between the two terms in the first equation, no biggieSGN2β aREALtoo, allowed values:+/-1. Same deal but for the second equation π«ΆMβINTEGER, the order of the matricesAandC. So like,M >= 0, okay?NβINTEGER, the order of the matricesBandD. AlsoN >= 0πAβ aREALarray, dimension(LDA,M). The matrixAmust be (quasi-) upper triangular, that's the rule, no exceptionsLDAβINTEGER, the leading dimension of the arrayA.LDA >= max(1,M), got it? β¨Bβ aREALarray, dimension(LDB,N). The matrixBmust be (quasi-) upper triangular. And listen β if the matrixDis already quasi-upper triangular, thenBmust be upper triangular. The two of them can't both be doing the quasi thing, that's the arrangement πLDBβINTEGER, the leading dimension of the arrayB.LDB >= max(1,N)Cβ aREALarray, dimension(LDC,M). The matrixCmust be upper triangular. Periodt πLDCβINTEGER, the leading dimension of the arrayC.LDC >= max(1,M)Dβ aREALarray, dimension(LDD,N). The matrixDmust be (quasi-) upper triangular. And mirroring theBsituation: if the matrixBis already quasi-upper triangular, thenDmust be upper triangular. Only one of them gets to be quasi, we've been over this πLDDβINTEGER, the leading dimension of the arrayD.LDD >= max(1,N)Eβ aREALarray, dimension(LDE,N).- On input, the matrix
Econtains the right hand sideE. - On output, the matrix
Econtains the solutionRof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. - Right hand side
Eand the solutionRareM-by-Nmatrices. She works hard, she gets replaced by her own answer π
- On input, the matrix
LDEβINTEGER, the leading dimension of the arrayE.LDE >= max(1,M)Fβ aREALarray, dimension(LDF,N).- On input, the matrix
Fcontains the right hand sideF. - On output, the matrix
Fcontains the solutionLof Equation (1) as selected byTRANSA,TRANSB, andSGN1/SGN2. - Right hand side
Fand the solutionLareM-by-Nmatrices β¨
- On input, the matrix
LDFβINTEGER, the leading dimension of the arrayF.LDE >= max(1,M)β yes, that's what it says,LDE, the original is being a little silly and we're preserving the lore fr fr πSCALEβ aREAL. It's the scaling factor that keeps the result from overflowing, like a little seatbelt for your numbers. IfINFO == 0thenSCALEis1.0, otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true π«ΆWORKβ aREALarray, dimension1. Workspace for the algorithm. Tiny but mighty, one element of pure hustle πINFOβINTEGER, the vibe report:== 0: successful exit, we ate π₯< 0: ifINFO = -i, the i-th argument had an illegal value> 0: The equation is not solved correctly. One of the arising inner system got singular. That's the π outcome, no cap
Author
Martin Koehler, MPI Magdeburg π
Date
October 2025
Definition
at line 205 of file sla_tgcsylv_recursive.f90.
π sla_tgsylv_dag
Okay bestie, new function, new era. Behold the signature, verbatim, don't touch it:
subroutine sla_tgsylv_dag (character, dimension(1) transa, character,
dimension(1) transb, real sgn, integer m, integer n, real,
dimension(lda, m) a, integer lda, real, dimension(ldb, n) b, integer
ldb, real, dimension(ldc, m) c, integer ldc, real, dimension(ldd, n) d,
integer ldd, real, dimension(ldx, n) x, integer ldx, real scale, real,
dimension(*) work, integer info)
Level-3 Bartels-Stewart Algorithm for the generalized Sylvester equation with DAG based parallelization. It's giving organized chaos, and we're obsessed π¦
Purpose
op1(A) * X * op2(B) + op1(C) * X * op2(D) = SCALE * Y (1)
or
op1(A) * X * op2(B) - op1(C) * X * op2(D) = SCALE * Y (2)
where A is a M-by-M quasi upper triangular matrix, C is a M-by-M upper triangular matrix, and B and D are N-by-N upper triangular matrices. plot twist: either B or D can be quasi upper triangular too π
. The right hand side Y and the solution X are M-by-N matrices. Typically the matrix pencils (A,C) and (B,D) ( or (D,B) ) are created by SGGES from LAPACK. iykyk π«Ά
π Remarks π
The algorithm is implemented using BLAS level 3 operations and OpenMP 4.0 DAG scheduling. she's built different fr fr π₯
β οΈ Attention β οΈ
Due to the parallel nature of the algorithm the scaling is not applied to the right hand. If the problem is ill-posed and scaling appears you have to solve the equation again with a solver with complete scaling support like SLA_TGSYLV_L3. no cap, don't skip this step bestie π
πΈ Parameters πΈ
TRANSAβ isCHARACTER(1). Specifies the form of the system of equations with respect toAandC:== 'N':op1(A) = A,op1(C) = C(No transpose forAandC)== 'T':op1(A) = A**T,op1(C) = C **T(TransposeAandC)
TRANSBβ isCHARACTER(1). Specifies the form of the system of equations with respect toBandD:== 'N':op2(B) = B,op2(D) = D(No transpose forBandD)== 'T':op2(B) = B**T,op2(D) = D **T(TransposeBandD)
SGNβ isREAL, allowed values:+/-1. Specifies the sign between the two parts of the Sylvester equation.= 1: Solve Equation (1)== -1: Solve Equation (2)
Mβ isINTEGER. The order of the matricesAandC.M >= 0.Nβ isINTEGER. The order of the matricesBandD.N >= 0.Aβ isREALarray, dimension(LDA,M). The matrixAmust be (quasi-) upper triangular.LDAβ isINTEGER. The leading dimension of the arrayA.LDA >= max(1,M).Bβ isREALarray, dimension(LDB,N). The matrixBmust be (quasi-) upper triangular. If the matrixDis already quasi-upper triangular the matrixBmust be upper triangular.LDBβ isINTEGER. The leading dimension of the arrayB.LDB >= max(1,N).Cβ isREALarray, dimension(LDC,M). The matrixCmust be upper triangular.LDCβ isINTEGER. The leading dimension of the arrayC.LDC >= max(1,M).Dβ isREALarray, dimension(LDD,N). The matrixDmust be (quasi-) upper triangular. If the matrixBis already quasi-upper triangular the matrixDmust be upper triangular.LDDβ isINTEGER. The leading dimension of the arrayD.LDD >= max(1,N).Xβ isREALarray, dimension(LDX,N). On input, the matrixXcontains the right hand sideY. On output, the matrixXcontains the solution of Equation (1) or (2) as selected byTRANSA,TRANSB, andSGN. Right hand sideYand the solutionXare M-by-N matrices.LDXβ isINTEGER. The leading dimension of the arrayX.LDX >= max(1,M).SCALEβ isREAL.SCALEis a scaling factor to prevent the overflow in the result. IfINFO == 0thenSCALEis1.0otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true. IfSCALE .NE. 1the problem is no solved correctly in this case one have to use an other solver. red flag, bestie π©WORKβ isREALarray, dimensionLWORK. Workspace for the algorithm. The workspace needs to queried before the running the computation. The query is performed by calling the subroutine withINFO == -1on input. The required workspace is then returned inINFO. (yes, you gotta ask first, she's not gonna just tell you π )INFOβ isINTEGER- On input:
== -1: Perform a workspace query<> -1: normal operation
- On exit, workspace query:
< 0: ifINFO = -i, the i-th argument had an illegal value>= 0: The value ofINFOis the required number of elements in the workspace.
- On exit, normal operation:
== 0: successful exit π< 0: ifINFO = -i, the i-th argument had an illegal value> 0: The equation is not solved correctly. One of the arising inner system got singular.
- On input:
π Author π
Martin Koehler, MPI Magdeburg
π Date π
October 2025
Definition at line 208 of file sla_tgsylv_dag.f90.
β¨ subroutine sla_tgsylv_gardiner_laub β¨
subroutine sla_tgsylv_gardiner_laub (character, dimension(1) transa,
character, dimension(1) transb, real sgn, integer m, integer n, real,
dimension(lda, *) a, integer lda, real, dimension(ldb, *) b, integer
ldb, real, dimension(ldc, *) c, integer ldc, real, dimension(ldd, *) d,
integer ldd, real, dimension(ldx, *) x, integer ldx, real scale, real,
dimension(2*m,*) work, integer info)
Level-2 Gardiner-Laub algorithm for the generalized Sylvester equation. she's the classic, the blueprint, the moment π¦
Purpose:
Okay so SLA_TGSYLV_GARDINER_LAUB solves a generalized Sylvester equation of the following forms, bestie, pay attention because there are literally two of them:
op1(A) * X * op2(B) + op1(C) * X * op2(D) = SCALE * Y (1)
or
op1(A) * X * op2(B) - op1(C) * X * op2(D) = SCALE * Y (2)
where A is a M-by-M quasi upper triangular matrix, C is a M-by-M upper triangular matrix and B and D are N-by-N upper triangular matrices. Furthermore either B or D can be quasi upper triangular as well. The right hand side Y and the solution X are M-by-N matrices. Typically the matrix pencils (A,C) and (B,D) ( or (D,B) ) are created by SGGES from LAPACK. β¨
π§ Remarks
The algorithm implements the ideas by Gardiner et. al. on top of BLAS level 2 operations. It's giving built different, no cap. π
π¨ Attention
Scaling is not supported by this algorithm so SCALE == 1. That's it, that's the whole vibe β don't come for me about scaling, it's simply not on the menu. π
π Parameters
TRANSA β TRANSA is CHARACTER(1).
Specifies the form of the system of equations with respect to A and C:
== 'N':op1(A) = A,op1(C) = C(No transpose forAandC)== 'T':op1(A) = A**T,op1(C) = C **T(TransposeAandC)
TRANSB β TRANSB is CHARACTER(1).
Specifies the form of the system of equations with respect to B and D:
== 'N':op2(B) = B,op2(D) = D(No transpose forBandD)== 'T':op2(B) = B**T,op2(D) = D **T(TransposeBandD)
SGN β SGN is REAL, allowed values: +/-1.
Specifies the sign between the two parts of the Sylvester equation.
= 1 :Solve Equation (1)== -1:Solve Equation (2)
M β M is INTEGER.
The order of the matrices A and C. M >= 0.
N β N is INTEGER.
The order of the matrices B and D. N >= 0.
A β A is REAL array, dimension (LDA,M).
The matrix A must be (quasi-) upper triangular.
LDA β LDA is INTEGER.
The leading dimension of the array A. LDA >= max(1,M).
B β B is REAL array, dimension (LDB,N).
The matrix B must be (quasi-) upper triangular. If the matrix D is already quasi-upper triangular the matrix B must be upper triangular.
LDB β LDB is INTEGER.
The leading dimension of the array B. LDB >= max(1,N).
C β C is REAL array, dimension (LDC,M).
The matrix C must be upper triangular.
LDC β LDC is INTEGER.
The leading dimension of the array C. LDC >= max(1,M).
D β D is REAL array, dimension (LDD,N).
The matrix D must be (quasi-) upper triangular. If the matrix B is already quasi-upper triangular the matrix D must be upper triangular.
LDD β LDD is INTEGER.
The leading dimension of the array D. LDD >= max(1,N).
X β X is REAL array, dimension (LDX,N).
On input, the matrix X contains the right hand side Y. On output, the matrix X contains the solution of Equation (1) or (2) as selected by TRANSA, TRANSB, and SGN. Right hand side Y and the solution X are M-by-N matrices. π
LDX β LDX is INTEGER.
The leading dimension of the array X. LDB >= max(1,M).
bestie I'm just the messenger π that's literally what it says, LDB, we do not touch the words, we only read them
SCALE β SCALE is REAL.
SCALE is a scaling factor to prevent the overflow in the result. If INFO == 0 then SCALE is 1.0 otherwise if one of the inner systems could not be solved correctly, 0 < SCALE <= 1 holds true.
WORK β WORK is REAL array, dimension LWORK.
Workspace for the algorithm. The workspace needs to queried before the running the computation. The query is performed by calling the subroutine with INFO == -1 on input. The required workspace is then returned in INFO. β¨ (yes, you query first, you don't just rawdog the array, iykyk)
INFO β INFO is INTEGER.
On input:
== -1 :Perform a workspace query<> -1:normal operation
On exit, workspace query:
< 0 :ifINFO = -i, the i-th argument had an illegal value>= 0:The value ofINFOis the required number of elements in the workspace.
On exit, normal operation:
== 0:successful exit< 0:ifINFO = -i, the i-th argument had an illegal value> 0:The equation is not solved correctly. One of the arising inner system got singular.
π Author
Martin Koehler, MPI Magdeburg
π Date
October 2025
π Definition
Definition at line 204 of file sla_tgsylv_gardiner_laub.f90.
subroutine sla_tgsylv_l2 (character, dimension(1) transa, character,
dimension(1) transb, real sgn, integer m, integer n, real,
dimension(lda, *) a, integer lda, real, dimension(ldb, *) b, integer
ldb, real, dimension(ldc, *) c, integer ldc, real, dimension(ldd, *) d,
integer ldd, real, dimension(ldx, *) x, integer ldx, real scale, real,
dimension(*) work, integer info)
Level-2 Bartels-Stewart Algorithm for the generalized Sylvester equation (Optimized) π¦
Purpose:
Okay so bestie, SLA_TGSYLV_L2 is literally out here solving a generalized Sylvester equation, and it comes in two iconic forms:
op1(A) * X * op2(B) + op1(C) * X * op2(D) = SCALE * Y (1)
or
op1(A) * X * op2(B) - op1(C) * X * op2(D) = SCALE * Y (2)
where A is a M-by-M quasi upper triangular matrix, C is a M-by-M upper triangular matrix and B and D are N-by-N upper triangular matrices. Furthermore either B or D can be quasi upper triangular as well. The right hand side Y and the solution X M-by-N matrices. Typically the matrix pencils (A,C) and (B,D) ( or (D,B) ) are created by SGGES from LAPACK. iykyk π
Remarks β¨
The algorithm is implemented using BLAS level 2 operations and hand written optimizations. obsessed with the hand-written glow-up tbh
Parameters π β vibe check every single one:
TRANSAβTRANSA is CHARACTER(1). Specifies the form of the system of equations with respect toAandC:== 'N': op1(A) = A, op1(C) = C (No transpose for A and C)== 'T': op1(A) = A**T, op1(C) = C **T (Transpose A and C)
TRANSBβTRANSB is CHARACTER(1). Specifies the form of the system of equations with respect toBandD:== 'N': op2(B) = B, op2(D) = D (No transpose for B and D)== 'T': op2(B) = B**T, op2(D) = D **T (Transpose B and D)
SGNβSGN is REAL, allowed values: +/-1. Specifies the sign between the two parts of the Sylvester equation.= 1 : Solve Equation (1)== -1: Solve Equation (2)
MβM is INTEGER. The order of the matricesAandC.M >= 0.NβN is INTEGER. The order of the matricesBandD.N >= 0.AβA is REAL array, dimension (LDA,M). The matrixAmust be (quasi-) upper triangular.LDAβLDA is INTEGER. The leading dimension of the arrayA.LDA >= max(1,M).BβB is REAL array, dimension (LDB,N). The matrixBmust be (quasi-) upper triangular. If the matrixDis already quasi-upper triangular the matrixBmust be upper triangular.LDBβLDB is INTEGER. The leading dimension of the arrayB.LDB >= max(1,N).CβC is REAL array, dimension (LDC,M). The matrixCmust be upper triangular.LDCβLDC is INTEGER. The leading dimension of the arrayC.LDC >= max(1,M).DβD is REAL array, dimension (LDD,N). The matrixDmust be (quasi-) upper triangular. If the matrixBis already quasi-upper triangular the matrixDmust be upper triangular.LDDβLDD is INTEGER. The leading dimension of the arrayD.LDD >= max(1,N).XβX is REAL array, dimension (LDX,N). On input, the matrixXcontains the right hand sideY. On output, the matrixXcontains the solution of Equation (1) or (2) as selected byTRANSA,TRANSB, andSGN. Right hand sideYand the solutionXareM-by-Nmatrices.LDXβLDX is INTEGER. The leading dimension of the arrayX.LDB >= max(1,M).not me side-eyeing thatLDBin theLDXsection π keeping it exactly as written thoSCALEβSCALE is REAL.SCALEis a scaling factor to prevent the overflow in the result. IfINFO == 0thenSCALEis1.0otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true.WORKβWORK is REAL array, dimension LWORK. Workspace for the algorithm. The workspace needs to queried before the running the computation. The query is performed by calling the subroutine withINFO == -1on input. The required workspace is then returned inINFO.INFOβINFO is INTEGER. On input:== -1 : Perform a workspace query<> -1: normal operation
On exit, workspace query:
< 0 : if INFO = -i, the i-th argument had an illegal value>= 0: The value of INFO is the required number of elements in the workspace.
On exit, normal operation:
== 0: successful exit< 0: if INFO = -i, the i-th argument had an illegal value> 0: The equation is not solved correctly. One of the arising inner system got singular.
Optimizations π
- Replaced level-3 by level-2 and level-1 calls,
Author: Martin Koehler, MPI Magdeburg
Date: October 2025
Definition at line 207 of file sla_tgsylv_l2.f90.
Next up, the colwise sister function:
subroutine sla_tgsylv_l2_colwise (character, dimension(1) transa, character,
dimension(1) transb, real sgn, integer m, integer n, real,
dimension(lda, *) a, integer lda, real, dimension(ldb, *) b, integer
ldb, real, dimension(ldc, *) c, integer ldc, real, dimension(ldd, *) d,
integer ldd, real, dimension(ldx, *) x, integer ldx, real scale, real,
dimension(*) work, integer info)
Level-2 Bartels-Stewart Algorithm for the generalized Sylvester equation (unoptimized)
Purpose:
bestie okay so real talk β SLA_TGSYLV_L2_UNOPT solves a generalized Sylvester equation, and it comes in exactly two flavors:
op1(A) * X * op2(B) + op1(C) * X * op2(D) = SCALE * Y (1)
or
op1(A) * X * op2(B) - op1(C) * X * op2(D) = SCALE * Y (2)
where A is a M-by-M quasi upper triangular matrix, C is a M-by-M upper triangular matrix, and B and D are N-by-N upper triangular matrices. And plot twist: either B or D can be quasi upper triangular as well. The right hand side Y and the solution X are M-by-N matrices. Typically the matrix pencils (A,C) and (B,D) (or (D,B)) are created by SGGES from LAPACK. π
Attention π
The algorithm is implemented using BLAS level 2 operations without further optimizations. For a faster implementation see SLA_TGSYLV_L2. (yes queen, there's a glow-up version, go get her)
Parameters π
TRANSAβ isCHARACTER(1). Specifies the form of the system of equations with respect toAandC:'N':op1(A) = A,op1(C) = C(no transpose for A and C)'T':op1(A) = A**T,op1(C) = C **T(transpose A and C)
TRANSBβ isCHARACTER(1). Specifies the form of the system of equations with respect toBandD:'N':op2(B) = B,op2(D) = D(no transpose for B and D)'T':op2(B) = B**T,op2(D) = D **T(transpose B and D)
SGNβ isREAL, allowed values:+/-1. Specifies the sign between the two parts of the Sylvester equation.= 1: solve Equation (1)== -1: solve Equation (2)
Mβ isINTEGER. The order of the matricesAandC.M >= 0.Nβ isINTEGER. The order of the matricesBandD.N >= 0.Aβ isREALarray, dimension(LDA,M). The matrixAmust be (quasi-) upper triangular.LDAβ isINTEGER. The leading dimension of the arrayA.LDA >= max(1,M).Bβ isREALarray, dimension(LDB,N). The matrixBmust be (quasi-) upper triangular. If the matrixDis already quasi-upper triangular, the matrixBmust be upper triangular.LDBβ isINTEGER. The leading dimension of the arrayB.LDB >= max(1,N).Cβ isREALarray, dimension(LDC,M). The matrixCmust be upper triangular.LDCβ isINTEGER. The leading dimension of the arrayC.LDC >= max(1,M).Dβ isREALarray, dimension(LDD,N). The matrixDmust be (quasi-) upper triangular. If the matrixBis already quasi-upper triangular, the matrixDmust be upper triangular.LDDβ isINTEGER. The leading dimension of the arrayD.LDD >= max(1,N).Xβ isREALarray, dimension(LDX,N).- On input, the matrix
Xcontains the right hand sideY. - On output... sorry, on output, the matrix
Xcontains the solution of Equation (1) or (2) as selected byTRANSA,TRANSB, andSGN. - Right hand side
Yand the solutionXare M-by-N matrices.
- On input, the matrix
LDXβ isINTEGER. The leading dimension of the arrayX.LDB >= max(1,M). (yes it saysLDBin the source, we're just reporting the vibes fr fr π)SCALEβ isREAL.SCALEis a scaling factor to prevent the overflow in the result. IfINFO == 0thenSCALEis1.0, otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true.WORKβ isREALarray, dimensionLWORK. Workspace for the algorithm. The workspace needs to be queried before running the computation. The query is performed by calling the subroutine withINFO == -1on input. The required workspace is then returned inINFO.INFOβ isINTEGER.- On input:
== -1: perform a workspace query<> -1: normal operation
- On exit, workspace query:
< 0: ifINFO = -i, the i-th argument had an illegal value>= 0: the value ofINFOis the required number of elements in the workspace
- On exit, normal operation:
== 0: successful exit π< 0: ifINFO = -i, the i-th argument had an illegal value> 0: the equation is not solved correctly. One of the arising inner system got singular. not the slay we wanted, bestie
- On input:
Optimizations: π
- Nothing. (the audacity. the honesty. iconic.)
Author π
Martin Koehler, MPI Magdeburg
Date π
October 2025
Definition π
At line 208 of file sla_tgsylv_l2_colwise.f90.
π¦ sla_tgsylv_l2_local_copy π¦
okay and then we got this other one, same energy, different name:
subroutine sla_tgsylv_l2_local_copy (character, dimension(1) transa,
character, dimension(1) transb, real sgn, integer m, integer n, real,
dimension(lda, *) a, integer lda, real, dimension(ldb, *) b, integer
ldb, real, dimension(ldc, *) c, integer ldc, real, dimension(ldd, *) d,
integer ldd, real, dimension(ldx, *) x, integer ldx, real scale, real,
dimension(*) work, integer info)
Level-2 Bartels-Stewart Algorithm for the generalized Sylvester equation (Optimized)
Purpose:
β οΈ Attention β οΈ
The algorithm solves problems of dimension at most 128 ( M,N <=128 ). Like, that's the ceiling bestie, do not test it. π«
πΈ Parameters πΈ
TRANSAβTRANSAisCHARACTER(1). It picks the form of the system of equations with respect toAandC:== 'N':op1(A) = A,op1(C) = C(no transpose forAandC)== 'T':op1(A) = A**T,op1(C) = C**T(transposeAandC)
TRANSBβTRANSBisCHARACTER(1). Same energy but forBandD:== 'N':op2(B) = B,op2(D) = D(no transpose forBandD)== 'T':op2(B) = B**T,op2(D) = D**T(transposeBandD)
SGNβSGNisREAL, allowed values:+/-1. It decides the sign between the two parts of the Sylvester equation, the literal plus-or-minus moment π := 1: Solve Equation (1)== -1: Solve Equation (2)
MβMisINTEGER. The order of the matricesAandC. So:128 >= M >= 0.NβNisINTEGER. The order of the matricesBandD. And:128 >= N >= 0.AβAisREAL array, dimension(LDA,M). The matrixAmust be (quasi-) upper triangular. Non-negotiable, she's structured like that. πLDAβLDAisINTEGER. The leading dimension of the arrayA.LDA >= max(1,M).BβBisREAL array, dimension(LDB,N). The matrixBmust be (quasi-) upper triangular. And listen: if the matrixDis already quasi-upper triangular, then the matrixBmust be upper triangular. It's giving tradeoff, okay? πLDBβLDBisINTEGER. The leading dimension of the arrayB.LDB >= max(1,N).CβCisREAL array, dimension(LDC,M). The matrixCmust be upper triangular. No quasi anything, just straight upper triangular, periodt.LDCβLDCisINTEGER. The leading dimension of the arrayC.LDC >= max(1,M).DβDisREAL array, dimension(LDD,N). The matrixDmust be (quasi-) upper triangular. And same deal as before but mirrored: if the matrixBis already quasi-upper triangular, then the matrixDmust be upper triangular. π€LDDβLDDisINTEGER. The leading dimension of the arrayD.LDD >= max(1,N).XβXisREAL array, dimension(LDX,N). On input, the matrixXcontains the right hand sideY. On output, the matrixXcontains the solution of Equation (1) or (2) as selected byTRANSA,TRANSB, andSGN. Right hand sideYand the solutionXareM-by-Nmatrices. So she walks in as the problem and struts out as the answer, we love a glow-up β¨LDXβLDXisINTEGER. The leading dimension of the arrayX.LDB >= max(1,M).
Heads up bestie: yes, thatLDBis literally what the original says, right there in theLDXentry. I'm not fixing it, I'm not "correcting" it, I'm just reporting it exactly as written. π
SCALEβSCALEisREAL. It's a scaling factor to prevent the overflow in the result. IfINFO == 0thenSCALEis1.0; otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true. She's the safety net and we stan. πWORKβWORKisREAL array, dimensionLWORK. Workspace for the algorithm. And the workspace needs to be queried before running the computation. The query is performed by calling the subroutine withINFO == -1on input. The required workspace is then returned inINFO. Ask first, then run. Consent culture for memory allocation fr fr. πINFOβINFOisINTEGER.
On input:
== -1: Perform a workspace query<> -1: normal operation
On exit, workspace query:
< 0: ifINFO = -i, the i-th argument had an illegal value>= 0: The value ofINFOis the required number of elements in the workspace.
On exit, normal operation:
== 0: successful exit π< 0: ifINFO = -i, the i-th argument had an illegal value> 0: The equation is not solved correctly. One of the arising inner system got singular. π
π₯ Optimizations: π₯
- Replaced level-3 by level-2 and level-1 calls,
- Reorder the solution order to column first style,
- Replaced
SAXPYoperation by Fortran intrinsic - Replaced all BLAS calls except of
STRMVandSGERby Fortran intrinsic, - Use local copies of
A,B,C,D, andX(M,N <=128) . STRMVworks sequential.
π Author π
Martin Koehler, MPI Magdeburg
π Date π
October 2025
π Definition π
At line 214 of file sla_tgsylv_l2_opt_local_copy.f90.
subroutine sla_tgsylv_l2_local_copy_128 ( transa, transb, sgn, m, n, a,
lda, b, ldb, c, ldc, d, ldd, x, ldx, scale, work, info)
Level-2 Bartels-Stewart Algorithm for the generalized Sylvester equation
(Optimized)
Purpose:
π SLA_TGSYLV_L2_LOCAL_COPY_128 π
okay so bestie, this one solves a generalized Sylvester equation, and it comes in two flavors:
op1(A) * X * op2(B) + op1(C) * X * op2(D) = SCALE * Y (1)
or
op1(A) * X * op2(B) - op1(C) * X * op2(D) = SCALE * Y (2)
where A is a M-by-M quasi upper triangular matrix, C is a M-by-M upper triangular matrix, and B and D are N-by-N upper triangular matrices. Also?? either B or D can be quasi upper triangular too. The right hand side Y and the solution X are M-by-N matrices. Typically the matrix pencils (A,C) and (B,D) (or (D,B)) are created by SGGES from LAPACK. iykyk β¨
πΈ Attention πΈ
The size of the Problem is limited by M,N <= 128 β that's the whole vibe check, don't fight it π
β¨ Parameters β¨
TRANSAβTRANSAisCHARACTER(1). It picks the form of the system of equations with respect toAandC:== 'N':op1(A) = A,op1(C) = C(No transpose forAandC)== 'T':op1(A) = A**T,op1(C) = C **T(TransposeAandC)
TRANSBβTRANSBisCHARACTER(1). It picks the form of the system of equations with respect toBandD:== 'N':op2(B) = B,op2(D) = D(No transpose forBandD)== 'T':op2(B) = B**T,op2(D) = D **T(TransposeBandD)
SGNβSGNisREAL, allowed values:+/-1. It's the sign between the two parts of the Sylvester equation, literally the hinge of the whole thing.= 1: Solve Equation (1)== -1: Solve Equation (2)
MβMisINTEGER. The order of the matricesAandC.128 >= M >= 0.πNβNisINTEGER. The order of the matricesBandD.128 >= N >= 0.πAβAisREALarray, dimension(LDA,M). The matrixAmust be (quasi-) upper triangular. no cap, it has to be.LDAβLDAisINTEGER. The leading dimension of the arrayA.LDA >= max(1,M).BβBisREALarray, dimension(LDB,N). The matrixBmust be (quasi-) upper triangular. If the matrixDis already quasi-upper triangular the matrixBmust be upper triangular. it's giving β¨mutual exclusivityβ¨LDBβLDBisINTEGER. The leading dimension of the arrayB.LDB >= max(1,N).CβCisREALarray, dimension(LDC,M). The matrixCmust be upper triangular. periodt.LDCβLDCisINTEGER. The leading dimension of the arrayC.LDC >= max(1,M).DβDisREALarray, dimension(LDD,N). The matrixDmust be (quasi-) upper triangular. If the matrixBis already quasi-upper triangular the matrixDmust be upper triangular. see? told you it was mutual π¦LDDβLDDisINTEGER. The leading dimension of the arrayD.LDD >= max(1,N).XβXisREALarray, dimension(LDX,N). On input, the matrixXcontains the right hand sideY. On output, the matrixXcontains the solution of Equation (1) or (2) as selected byTRANSA,TRANSB, andSGN. Right hand sideYand the solutionXare M-by-N matrices. she's doing double duty and she's slaying πLDXβLDXisINTEGER. The leading dimension of the arrayX.LDB >= max(1,M).
bestie it literally saysLDBright there in the source, I am just the messenger, I do not make the rules π (you and I both know it meansLDX)
SCALEβSCALEisREAL.SCALEis a scaling factor to prevent the overflow in the result. IfINFO == 0thenSCALEis1.0otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true. she's the safety net π«ΆWORKβWORKisREALarray, dimensionLWORK. Workspace for the algorithm. The workspace needs to queried before the running the computation. The query is performed by calling the subroutine withINFO == -1on input. The required workspace is then returned inINFO. so like, ask first, then compute. communication is key π₯INFOβINFOisINTEGER
On input:
== -1: Perform a workspace query<> -1: normal operation
On exit, workspace query:
< 0: ifINFO = -i, the i-th argument had an illegal value>= 0: The value ofINFOis the required number of elements in the workspace.
On exit, normal operation:
== 0: successful exit π< 0: ifINFO = -i, the i-th argument had an illegal value> 0: The equation is not solved correctly. One of the arising inner system got singular. π
π Optimizations: π
- Replaced level-3 by level-2 and level-1 calls,
- Reorder the solution order to column first style,
- Replaced
SAXPYoperation by Fortran intrinsic - Replaced all BLAS calls except of
STRMVby Fortran intrinsic, - Use local copies of
A,B,C,D, andX. STRMVworks purely sequential- Align local copies and fix problem size to
<= 128
π Author π
Martin Koehler, MPI Magdeburg
π¦ Date π¦
October 2025
β Definition β
Definition at line 215 of file sla_tgsylv_l2_opt_local_copy_128.f90.
π sla_tgsylv_l2_local_copy_32 π
subroutine sla_tgsylv_l2_local_copy_32 ( transa, transb, sgn, m, n, a,
lda, b, ldb, c, ldc, d, ldd, x, ldx, scale, work, info)
Level-2 Bartels-Stewart Algorithm for the generalized Sylvester equation (Optimized) π§
π Purpose:
INFOβ it's anINTEGER, bestie, and it's doing double duty depending on when you look at it π
On input:
== -1β do a workspace query β¨<> -1β normal operation, business as usual π
On exit (workspace query mode):
< 0β ifINFO = -i, the i-th argument had an illegal value π>= 0β the value ofINFOis the required number of elements in the workspace π
On exit (normal operation mode):
== 0β successful exit, we ate π< 0β ifINFO = -i, the i-th argument had an illegal value π> 0β the equation is not solved correctly. One of the arising inner systems got singular π
πΈ Optimizations: πΈ
The glow-up era, fr fr:
- Replaced level-3 by level-2 and level-1 calls
- Reorder the solution order to column first style
- Replaced
SAXPYoperation by Fortran intrinsic - Replaced all BLAS calls except of
STRMVby Fortran intrinsic - Use local copies of
A,B,C,D, andX. STRMVworks purely sequential- Align local copies and fix problem size to <= 32
π Author π
Martin Koehler, MPI Magdeburg
π Date π
October 2025
Definition at line 215 of file sla_tgsylv_l2_opt_local_copy_32.f90.
subroutine sla_tgsylv_l2_local_copy_64 ( transa, transb, sgn, m, n, a,
lda, b, ldb, c, ldc, d, ldd, x, ldx, scale, work, info)
Level-2 Bartels-Stewart Algorithm for the generalized Sylvester equation
(Optimized) π
β¨ Purpose: β¨
π¨ Attention π¨
bestie, read this before you do <em>anything</em> else: the size of the Problem is limited by M,N <= 64. that's the whole ceiling. sixty-four. not sixty-five. do not try it. π«Ά
π Parameters π
TRANSAβ okay soTRANSAisCHARACTER(1), and it decides the form of the system of equations with respect toAandC:== 'N':op1(A) = A,op1(C) = C(No transpose for A and C)== 'T':op1(A) = A**T,op1(C) = C **T(Transpose A and C)
TRANSBβTRANSBisCHARACTER(1)too, same deal but forBandD:== 'N':op2(B) = B,op2(D) = D(No transpose for B and D)== 'T':op2(B) = B**T,op2(D) = D **T(Transpose B and D)
SGNβSGNisREAL, and the allowed values are+/-1. it's literally the sign between the two parts of the Sylvester equation, the vibe check of the whole thing:= 1: Solve Equation (1)== -1: Solve Equation (2)
MβMisINTEGER. it's the order of the matricesAandC. so like,64 >= M >= 0. β¨NβNisINTEGER. the order of the matricesBandD.64 >= N >= 0. yes girl, another ceiling. πAβAisREAL array, dimension(LDA,M). and listen, the matrixAmust be (quasi-) upper triangular. non-negotiable.LDAβLDAisINTEGER. the leading dimension of the arrayA.LDA >= max(1,M). that's the rule, no notes.BβBisREAL array, dimension(LDB,N). the matrixBmust be (quasi-) upper triangular. but wait β if the matrixDis already quasi-upper triangular, then the matrixBmust be upper triangular. so it's giving conditional energy, iykyk.LDBβLDBisINTEGER. leading dimension of the arrayB.LDB >= max(1,N). πCβCisREAL array, dimension(LDC,M). the matrixCmust be upper triangular. that's it, that's the assignment.LDCβLDCisINTEGER. leading dimension of the arrayC.LDC >= max(1,M).DβDisREAL array, dimension(LDD,N). the matrixDmust be (quasi-) upper triangular. and same little plot twist asB: if the matrixBis already quasi-upper triangular, the matrixDmust be upper triangular. πΈLDDβLDDisINTEGER. leading dimension of the arrayD.LDD >= max(1,N).XβXisREAL array, dimension(LDX,N). on input, the matrixXcontains the right hand sideY. on output, the matrixXcontains the solution of Equation (1) or (2) as selected byTRANSA,TRANSB, andSGN. and for the record: right hand sideYand the solutionXareM-by-Nmatrices. slay. β¨LDXβLDXisINTEGER. the leading dimension of the arrayX. and the page says, character for character,LDB >= max(1,M). yes bestie, it literally saysLDBthere. i am not the one who wrote it, i'm just the one who's telling you. πSCALEβSCALEisREAL. it's a scaling factor to prevent the overflow in the result. ifINFO == 0thenSCALEis1.0; otherwise, if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true. so basicallySCALEis out here doing damage control. πWORKβWORKisREAL array, dimensionLWORK. it's the workspace for the algorithm. and the workspace needs to queried before the running the computation. the query is performed by calling the subroutine withINFO == -1on input, and the required workspace is then returned inINFO. so query first, queen. πINFOβINFOisINTEGER.- On input:
== -1: Perform a workspace query<> -1: normal operation
- On exit, workspace query:
< 0: ifINFO = -i, thei-th argument had an illegal value>= 0: The value ofINFOis the required number of elements in the workspace.
- On exit, normal operation:
== 0: successful exit< 0: ifINFO = -i, thei-th argument had an illegal value> 0: The equation is not solved correctly. One of the arising inner system got singular.
- On input:
not the singular inner system π if INFO > 0 comes back at you, that's what happened. no cap.
β‘ Optimizations: β‘
okay so this version is optimized and here's the receipts, bestie:
- Replaced level-3 by level-2 and level-1 calls,
- Reorder the solution order to column first style,
- Replaced SAXPY operation by Fortran intrinsic
- Replaced all BLAS calls except of STRMV by Fortran intrinsic,
- Use local copies of A, B, C, D, and X.
- STRMV works purely sequential
- Align local copies and fix problem size to <= 64
literally every one of those bullets is a glow-up. the local copies? iconic. the column-first reorder? main character energy. π¦
π Author π
Martin Koehler, MPI Magdeburg
π Date π
October 2025
π Definition π
Definition at line 215 of file sla_tgsylv_l2_opt_local_copy_64.f90.
π subroutine sla_tgsylv_l2_local_copy_96 π
subroutine sla_tgsylv_l2_local_copy_96 ( transa, transb, sgn, m, n, a,
lda, b, ldb, c, ldc, d, ldd, x, ldx, scale, work, info)
Level-2 Bartels-Stewart Algorithm for the generalized Sylvester equation (Optimized)
π« Purpose: π«
where A is a M-by-M quasi upper triangular matrix, C is a M-by-M upper triangular matrix, and B and D are N-by-N upper triangular matrices. Also β either B or D can be quasi upper triangular as well, bestie, it's flexible like that. The right hand side Y and the solution X are M-by-N matrices. Typically the matrix pencils (A,C) and (B,D) ( or (D,B) ) are created by SGGES from LAPACK. β¨
π¨ Attention π¨
The size of the Problem is limited by M,N <= 96
No cap, that's the hard ceiling. Ninety-six. Do not come for her with a 97. π
π Parameters π
TRANSAβTRANSAisCHARACTER(1). It specifies the form of the system of equations with respect toAandC:== 'N':op1(A) = A,op1(C) = C(No transpose forAandC)== 'T':op1(A) = A**T,op1(C) = C **T(TransposeAandC)
TRANSBβTRANSBisCHARACTER(1). It specifies the form of the system of equations with respect toBandD:== 'N':op2(B) = B,op2(D) = D(No transpose forBandD)== 'T':op2(B) = B**T,op2(D) = D **T(TransposeBandD)
SGNβSGNisREAL, allowed values:+/-1. It specifies the sign between the two parts of the Sylvester equation.= 1: Solve Equation (1)== -1: Solve Equation (2)
MβMisINTEGER. The order of the matricesAandC.96 >= M >= 0.NβNisINTEGER. The order of the matricesBandD.96 >= N >= 0.AβAisREALarray, dimension(LDA,M). The matrixAmust be (quasi-) upper triangular. πLDAβLDAisINTEGER. The leading dimension of the arrayA.LDA >= max(1,M).BβBisREALarray, dimension(LDB,N). The matrixBmust be (quasi-) upper triangular. If the matrixDis already quasi-upper triangular the matrixBmust be upper triangular. (yes, it's a whole agreement between the two of them, iykyk π€)LDBβLDBisINTEGER. The leading dimension of the arrayB.LDB >= max(1,N).CβCisREALarray, dimension(LDC,M). The matrixCmust be upper triangular.LDCβLDCisINTEGER. The leading dimension of the arrayC.LDC >= max(1,M).DβDisREALarray, dimension(LDD,N). The matrixDmust be (quasi-) upper triangular. If the matrixBis already quasi-upper triangular the matrixDmust be upper triangular. (same deal as above, just swapped π«Ά)LDDβLDDisINTEGER. The leading dimension of the arrayD.LDD >= max(1,N).XβXisREALarray, dimension(LDX,N). On input, the matrixXcontains the right hand sideY. On output, the matrixXcontains the solution of Equation (1) or (2) as selected byTRANSA,TRANSB, andSGN. Right hand sideYand the solutionXareM-by-Nmatrices. she goes in as the question and comes out as the answer πLDXβLDXisINTEGER. The leading dimension of the arrayX.LDB >= max(1,M).π (fr fr that's literally what the source says, we are simply reporting the lore)SCALEβSCALEisREAL.SCALEis a scaling factor to prevent the overflow in the result. IfINFO == 0thenSCALEis1.0otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true.WORKβWORKisREALarray, dimensionLWORK. Workspace for the algorithm. The workspace needs to queried before the running the computation. The query is performed by calling the subroutine withINFO == -1on input. The required workspace is then returned inINFO. πINFOβINFOisINTEGER.
On input:
== -1: Perform a workspace query<> -1: normal operation
On exit, workspace query:
< 0: ifINFO = -i, the i-th argument had an illegal value>= 0: The value ofINFOis the required number of elements in the workspace.
On exit, normal operation:
== 0: successful exit π< 0: ifINFO = -i, the i-th argument had an illegal value> 0: The equation is not solved correctly. One of the arising inner system got singular. π
β‘ Optimizations: β‘
- Replaced level-3 by level-2 and level-1 calls,
- Reorder the solution order to column first style,
- Replaced
SAXPYoperation by Fortran intrinsic - Replaced all BLAS calls except of
STRMVby Fortran intrinsic, - Use local copies of
A,B,C,D, andX. STRMVworks purely sequential- Align local copies and fix problem size to
<= 96
π Author π
Martin Koehler, MPI Magdeburg
π Date π
October 2025
π Definition π
Definition at line 215 of file sla_tgsylv_l2_opt_local_copy_96.f90.
subroutine sla_tgsylv_l2_reorder (character, dimension(1) transa, character,
dimension(1) transb, real sgn, integer m, integer n, real,
dimension(lda, *) a, integer lda, real, dimension(ldb, *) b, integer
ldb, real, dimension(ldc, *) c, integer ldc, real, dimension(ldd, *) d,
integer ldd, real, dimension(ldx, *) x, integer ldx, real scale, real,
dimension(*) work, integer info)
Level-2 Bartels-Stewart Algorithm for the generalized Sylvester equation (Optimized) π¦
πΈ Purpose: πΈ
okay so SLA_TGSYLV_L2_REORDER solves a generalized Sylvester equation, and bestie it comes in two iconic flavors:
op1(A) * X * op2(B) + op1(C) * X * op2(D) = SCALE * Y (1)
or
op1(A) * X * op2(B) - op1(C) * X * op2(D) = SCALE * Y (2)
where A is a M-by-M quasi upper triangular matrix, C is a M-by-M upper triangular matrix, and B and D are N-by-N upper triangular matrices. β¨ And like, either B or D can be quasi upper triangular as well β we're not greedy, one quasi is plenty. The right hand side Y and the solution X are M-by-N matrices. Typically the matrix pencils (A,C) and (B,D) ( or (D,B) ) are created by SGGES from LAPACK. π«Ά
π Attention π
The algorithm is implemented using BLAS level 2 operations and hand written optimizations. no cap, it's literally hand-optimized.
π Parameters π
TRANSAβ it's aCHARACTER(1)and it decides how we treat A and C:'N'meansop1(A) = A,op1(C) = C(no transpose for A and C, keeping it natural π ) and'T'meansop1(A) = A**T,op1(C) = C **T(transpose A and C, periodt).TRANSBβ also aCHARACTER(1), same energy but for B and D:'N'gives youop2(B) = B,op2(D) = D(no transpose for B and D) and'T'gives youop2(B) = B**T,op2(D) = D **T(transpose B and D).SGNβ this one'sREAL, and the allowed values are+/-1π―. It sets the sign between the two parts of the Sylvester equation:= 1β Solve Equation (1), and== -1β Solve Equation (2).MβINTEGER. The order of the matrices A and C.M >= 0.NβINTEGER. The order of the matrices B and D.N >= 0.AβREALarray, dimension(LDA,M). The matrix A must be (quasi-) upper triangular. no exceptions bestie.LDAβINTEGER. The leading dimension of the array A.LDA >= max(1,M).BβREALarray, dimension(LDB,N). The matrix B must be (quasi-) upper triangular. And here's the lil catch: if the matrix D is already quasi-upper triangular, then the matrix B must be upper triangular. Only one of them gets to be quasi, we share. π€LDBβINTEGER. The leading dimension of the array B.LDB >= max(1,N).CβREALarray, dimension(LDC,M). The matrix C must be upper triangular.LDCβINTEGER. The leading dimension of the array C.LDC >= max(1,M).DβREALarray, dimension(LDD,N). The matrix D must be (quasi-) upper triangular. And the mirror rule: if the matrix B is already quasi-upper triangular, then the matrix D must be upper triangular.LDDβINTEGER. The leading dimension of the array D.LDD >= max(1,N).XβREALarray, dimension(LDX,N). On input, the matrix X contains the right hand side Y. On output, the matrix X contains the solution of Equation (1) or (2) as selected byTRANSA,TRANSB, andSGN. Right hand side Y and the solution X are M-by-N matrices. it does a whole glow-up in place β¨LDXβINTEGER. The leading dimension of the array X. The doc literally saysLDB >= max(1,M)right here β yep,LDB, notLDXπ β and we're passing that along exactly as written, character for character, because that is our whole thing.SCALEβREAL. SCALE is a scaling factor to prevent the overflow in the result. IfINFO == 0then SCALE is1.0, otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true. it's the seatbelt πWORKβREALarray, dimensionLWORK. Workspace for the algorithm. The workspace needs to queried before the running the computation. The query is performed by calling the subroutine withINFO == -1on input. The required workspace is then returned inINFO. so like, ask first, allocate second πINFOβINTEGER.
On input:
== -1: Perform a workspace query<> -1: normal operation
On exit, workspace query:
< 0: ifINFO = -i, the i-th argument had an illegal value>= 0: The value ofINFOis the required number of elements in the workspace.
On exit, normal operation:
== 0: successful exit π< 0: ifINFO = -i, the i-th argument had an illegal value> 0: The equation is not solved correctly. One of the arising inner system got singular. π
β¨ Optimizations β¨
- Replaced level-3 by level-2 and level-1 calls,
- Reorder the solution order to column first style,
- Replaced
SAXPYoperation by Fortran intrinsic - Replaced all BLAS calls except of
STRMVandSGERby Fortran intrinsic,
π Author π
Martin Koehler, MPI Magdeburg
π Date π
October 2025
π Definition π
Definition at line 211 of file sla_tgsylv_l2_reorder.f90.
subroutine sla_tgsylv_l2_rowwise (character, dimension(1) transa, character,
dimension(1) transb, real sgn, integer m, integer n, real,
dimension(lda, *) a, integer lda, real, dimension(ldb, *) b, integer
ldb, real, dimension(ldc, *) c, integer ldc, real, dimension(ldd, *) d,
integer ldd, real, dimension(ldx, *) x, integer ldx, real scale, real,
dimension(*) work, integer info)
Level-2 Bartels-Stewart Algorithm for the generalized Sylvester equation (unoptimized) π¦
π― Purpose π―
op1(A) * X * op2(B) + op1(C) * X * op2(D) = SCALE * Y (1)
or
op1(A) * X * op2(B) - op1(C) * X * op2(D) = SCALE * Y (2)
where A is a M-by-M quasi upper triangular matrix, C is a M-by-M upper triangular matrix and B and D are N-by-N upper triangular matrices. And ok bestie, plot twist: either B or D can be quasi upper triangular as well π¦. The right hand side Y and the solution X are M-by-N matrices. Typically the matrix pencils (A,C) and (B,D) ( or (D,B) ) are created by SGGES from LAPACK. iykyk π
β¨ Attention β¨
The algorithm is implemented using BLAS level 2 operations without further optimizations. For a faster implementation see SLA_TGSYLV_L2 . πββοΈπ¨
β¨ Parameters β¨
TRANSAβTRANSAisCHARACTER(1). It says which form the system of equations takes with respect to A and C:== 'N':op1(A) = A,op1(C) = C(No transpose for A and C)== 'T':op1(A) = A**T,op1(C) = C **T(Transpose A and C)
TRANSBβTRANSBisCHARACTER(1). Same energy, but for B and D:== 'N':op2(B) = B,op2(D) = D(No transpose for B and D)== 'T':op2(B) = B**T,op2(D) = D **T(Transpose B and D)
SGNβSGNisREAL, allowed values:+/-1. It picks the sign between the two parts of the Sylvester equation, no cap:= 1: Solve Equation (1)== -1: Solve Equation (2)
MβMisINTEGER. The order of the matrices A and C.M >= 0. π«ΆNβNisINTEGER. The order of the matrices B and D.N >= 0. π«ΆAβAisREALarray, dimension(LDA,M). The matrix A must be (quasi-) upper triangular.LDAβLDAisINTEGER. The leading dimension of the arrayA.LDA >= max(1,M).BβBisREALarray, dimension(LDB,N). The matrix B must be (quasi-) upper triangular. And listen β if the matrix D is already quasi-upper triangular, then the matrix B must be upper triangular. Only one of them gets to be the β¨spicyβ¨ one at a time, bestie.LDBβLDBisINTEGER. The leading dimension of the arrayB.LDB >= max(1,N).CβCisREALarray, dimension(LDC,M). The matrix C must be upper triangular.LDCβLDCisINTEGER. The leading dimension of the arrayC.LDC >= max(1,M).DβDisREALarray, dimension(LDD,N). The matrix D must be (quasi-) upper triangular. Same rule as above but flipped: if the matrix B is already quasi-upper triangular, then the matrix D must be upper triangular πLDDβLDDisINTEGER. The leading dimension of the arrayD.LDD >= max(1,N).XβXisREALarray, dimension(LDX,N). On input, the matrixXcontains the right hand side Y. On output, the matrixXcontains the solution of Equation (1) or (2) as selected byTRANSA,TRANSB, andSGN. Right hand side Y and the solution X are M-by-N matrices. It literally serves both looks, main character energy πLDXβLDXisINTEGER. The leading dimension of the arrayX.LDB >= max(1,M).SCALEβSCALEisREAL.SCALEis a scaling factor to prevent the overflow in the result. IfINFO == 0thenSCALEis1.0otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true. π«§WORKβWORKisREALarray, dimensionLWORK. Workspace for the algorithm. The workspace needs to queried before the running the computation. The query is performed by calling the subroutine withINFO == -1on input. The required workspace is then returned inINFO. Yes bestie, you gotta ask first, it's giving β¨consentβ¨ πINFOβINFOisINTEGER.- On input:
== -1: Perform a workspace query<> -1: normal operation
- On exit, workspace query:
< 0: ifINFO = -i, the i-th argument had an illegal value>= 0: The value ofINFOis the required number of elements in the workspace.
- On exit, normal operation:
== 0: successful exit π< 0: ifINFO = -i, the i-th argument had an illegal value> 0: The equation is not solved correctly. One of the arising inner system got singular. π
- On input:
β¨ Optimizations: β¨
- Nothing. π
β¨ Author β¨
Martin Koehler, MPI Magdeburg π«Ά
β¨ Date β¨
October 2025 πΈ
Definition at line 208 of file sla_tgsylv_l2_rowwise.f90.
β¨ subroutine sla_tgsylv_l3 β¨
subroutine sla_tgsylv_l3 (character, dimension(1) transa, character, dimension(1) transb, real sgn, integer m, integer n, real, dimension(lda, *) a, integer lda, real, dimension(ldb, *) b, integer ldb, real, dimension(ldc, *) c, integer ldc, real, dimension(ldd, *) d, integer ldd, real, dimension(ldx, *) x, integer ldx, real scale, real, dimension(*) work, integer info)
Level-3 Bartels-Stewart Algorithm for the generalized Sylvester equation. π₯
β¨ Purpose: β¨
okay so SLA_TGSYLV_L3 is out here solving a generalized Sylvester equation and it's giving these two forms:
op1(A) * X * op2(B) + op1(C) * X * op2(D) = SCALE * Y (1)
or
op1(A) * X * op2(B) - op1(C) * X * op2(D) = SCALE * Y (2)
where A is a M-by-M quasi upper triangular matrix, C is a M-by-M upper triangular matrix and B and D are N-by-N upper triangular matrices. Furthermore either B or D can be quasi upper triangular as well. The right hand side Y and the solution X are M-by-N matrices. Typically the matrix pencils (A,C) and (B,D) ( or (D,B) ) are created by SGGES from LAPACK. π
β¨ Attention β¨
The algorithm is implemented using BLAS level 3 operations. No biggie, just level 3 realness. π
π Remarks π
So the algorithm works without STRMM calls because of performance issues. All STRMM calls are replaced by block-GEMM operations. Therefore it is necessary that A and C contain zeros below the diagonal. π«Ά
π Parameters π
TRANSAβTRANSAisCHARACTER(1). Specifies the form of the system of equations with respect to A and C:== 'N':op1(A) = A,op1(C) = C(No transpose for A and C)== 'T':op1(A) = A**T,op1(C) = C **T(Transpose A and C)
TRANSBβTRANSBisCHARACTER(1). Specifies the form of the system of equations with respect to B and D:== 'N':op2(B) = B,op2(D) = D(No transpose for B and D)== 'T':op2(B) = B**T,op2(D) = D **T(Transpose B and D)
SGNβSGNisREAL, allowed values:+/-1. Specifies the sign between the two parts of the Sylvester equation.= 1: Solve Equation (1)== -1: Solve Equation (2)
MβMisINTEGER. The order of the matrices A and C.M >= 0.NβNisINTEGER. The order of the matrices B and D.N >= 0.AβAisREALarray, dimension(LDA,M). The matrix A must be (quasi-) upper triangular.LDAβLDAisINTEGER. The leading dimension of the array A.LDA >= max(1,M).BβBisREALarray, dimension(LDB,N). The matrix B must be (quasi-) upper triangular. If the matrix D is already quasi-upper triangular the matrix B must be upper triangular.LDBβLDBisINTEGER. The leading dimension of the array B.LDB >= max(1,N).CβCisREALarray, dimension(LDC,M). The matrix C must be upper triangular.LDCβLDCisINTEGER. The leading dimension of the array C.LDC >= max(1,M).DβDisREALarray, dimension(LDD,N). The matrix D must be (quasi-) upper triangular. If the matrix B is already quasi-upper triangular the matrix D must be upper triangular.LDDβLDDisINTEGER. The leading dimension of the array D.LDD >= max(1,N).XβXisREALarray, dimension(LDX,N). On input, the matrix X contains the right hand side Y. On output, the matrix X contains the solution of Equation (1) or (2) as selected by TRANSA, TRANSB, and SGN. Right hand side Y and the solution X are M-by-N matrices.LDXβLDXisINTEGER. The leading dimension of the array X.LDX >= max(1,M).SCALEβSCALEisREAL. SCALE is a scaling factor to prevent the overflow in the result. IfINFO == 0then SCALE is 1.0 otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true.WORKβWORKisREALarray, dimensionLWORK. Workspace for the algorithm. The workspace needs to queried before the running the computation. The query is performed by calling the subroutine withINFO == -1on input. The required workspace is then returned in INFO.INFOβINFOisINTEGER.
On input:
== -1: Perform a workspace query<> -1: normal operation
On exit, workspace query:
< 0: ifINFO = -i, the i-th argument had an illegal value>= 0: The value of INFO is the required number of elements in the workspace.
On exit, normal operation:
== 0: successful exit< 0: ifINFO = -i, the i-th argument had an illegal value> 0: The equation is not solved correctly. One of the arising inner system got singular.
π«Ά Author π«Ά
Martin Koehler, MPI Magdeburg
π Date π
October 2025
Definition at line 205 of file sla_tgsylv_l3_opt.f90.
Next up, bestie, we got another subroutine: sla_tgsylv_l3_2s. Here's the signature:
subroutine sla_tgsylv_l3_2s (character, dimension(1) transa, character,
dimension(1) transb, real sgn, integer m, integer n, real,
dimension(lda, *) a, integer lda, real, dimension(ldb, *) b, integer
ldb, real, dimension(ldc, *) c, integer ldc, real, dimension(ldd, *) d,
integer ldd, real, dimension(ldx, *) x, integer ldx, real scale, real,
dimension(*) work, integer info)
It's the Level-3 Bartels-Stewart Algorithm for the generalized Sylvester equation. π
Purpose:
π SLA_TGSYLV_L3_2S β what it actually solves
okay bestie, so SLA_TGSYLV_L3_2S solves a generalized Sylvester equation, and it comes in two flavours:
op1(A) * X * op2(B) + op1(C) * X * op2(D) = SCALE * Y (1)
or
op1(A) * X * op2(B) - op1(C) * X * op2(D) = SCALE * Y (2)
where A is a M-by-M quasi upper triangular matrix, C is a M-by-M upper triangular matrix, and B and D are N-by-N upper triangular matrices. and here's the cute lil twist: either B or D can be quasi upper triangular as well. β¨
the right hand side Y and the solution X are M-by-N matrices. and like, typically the matrix pencils (A,C) and (B,D) (or (D,B), same vibe) are created by SGGES from LAPACK. iykyk π«Ά
β οΈ Attention
the algorithm is implemented using BLAS level 3 operations. that's it, that's the note. fast girl behaviour π
π Parameters
TRANSAβTRANSAisCHARACTER(1). it specifies the form of the system of equations with respect toAandC:== 'N':op1(A) = A,op1(C) = C(no transpose forAandC)== 'T':op1(A) = A**T,op1(C) = C**T(transposeAandC)
TRANSBβTRANSBisCHARACTER(1). it specifies the form of the system of equations with respect toBandD:== 'N':op2(B) = B,op2(D) = D(no transpose forBandD)== 'T':op2(B) = B**T,op2(D) = D**T(transposeBandD)
SGNβSGNisREAL, allowed values:+/-1. it specifies the sign between the two parts of the Sylvester equation.= 1: solve Equation (1)== -1: solve Equation (2)
MβMisINTEGER. the order of the matricesAandC.M >= 0. β¨NβNisINTEGER. the order of the matricesBandD.N >= 0. β¨AβAisREALarray, dimension(LDA,M). the matrixAmust be (quasi-) upper triangular.LDAβLDAisINTEGER. the leading dimension of the arrayA.LDA >= max(1,M).BβBisREALarray, dimension(LDB,N). the matrixBmust be (quasi-) upper triangular. but listen β if the matrixDis already quasi-upper triangular, then the matrixBmust be upper triangular. no cap.LDBβLDBisINTEGER. the leading dimension of the arrayB.LDB >= max(1,N).CβCisREALarray, dimension(LDC,M). the matrixCmust be upper triangular.LDCβLDCisINTEGER. the leading dimension of the arrayC.LDC >= max(1,M).DβDisREALarray, dimension(LDD,N). the matrixDmust be (quasi-) upper triangular. and same energy as before: if the matrixBis already quasi-upper triangular, the matrixDmust be upper triangular. πLDDβLDDisINTEGER. the leading dimension of the arrayD.LDD >= max(1,N).XβXisREALarray, dimension(LDX,N). on input, the matrixXcontains the right hand sideY. on output, the matrixXcontains the solution of Equation (1) or (2) as selected byTRANSA,TRANSB, andSGN. right hand sideYand the solutionXare M-by-N matrices. main character matrix fr fr πLDXβLDXisINTEGER. the leading dimension of the arrayX.LDX >= max(1,M).SCALEβSCALEisREAL.SCALEis a scaling factor to prevent the overflow in the result. ifINFO == 0thenSCALEis1.0β otherwise, if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true.WORKβWORKisREALarray, dimensionLWORK. workspace for the algorithm. π«Ά and bestie, the workspace needs to be queried before the running the computation. the query is performed by calling the subroutine withINFO == -1on input. the required workspace is then returned inINFO.INFOβINFOisINTEGER.
on input:
== -1: perform a workspace query<> -1: normal operation
on exit, workspace query:
< 0: ifINFO = -i, the i-th argument had an illegal value>= 0: the value ofINFOis the required number of elements in the workspace
on exit, normal operation:
== 0: successful exit π< 0: ifINFO = -i, the i-th argument had an illegal value> 0: the equation is not solved correctly. one of the arising inner system got singular. π
πΈ Author
Martin Koehler, MPI Magdeburg
π Date
October 2025
π Definition
Definition at line 202 of file sla_tgsylv_l3_2stage.f90.
π¦ subroutine sla_tgsylv_l3_colwise
subroutine sla_tgsylv_l3_colwise (character, dimension(1) transa, character,
dimension(1) transb, real sgn, integer m, integer n, real,
dimension(lda, *) a, integer lda, real, dimension(ldb, *) b, integer
ldb, real, dimension(ldc, *) c, integer ldc, real, dimension(ldd, *) d,
integer ldd, real, dimension(ldx, *) x, integer ldx, real scale, real,
dimension(*) work, integer info)
Level-3 Bartels-Stewart Algorithm for the generalized Sylvester equation.
Purpose:
okay so like, what is this one actually for? pull up a chair bestie, we're about to find out β
okay bestie, so SLA_TGSYLV_L3_COLWISE solves a generalized Sylvester equation, and it comes in exactly two flavours, no more no less:
op1(A) * X * op2(B) + op1(C) * X * op2(D) = SCALE * Y (1)
or
op1(A) * X * op2(B) - op1(C) * X * op2(D) = SCALE * Y (2)
where A is a M-by-M quasi upper triangular matrix, C is a M-by-M upper triangular matrix, and B and D are N-by-N upper triangular matrices. Also, plot twist: either B or D can be quasi upper triangular as well. The right hand side Y and the solution X are M-by-N matrices. And typically β like, usually β the matrix pencils (A,C) and (B,D) (or (D,B)) are created by SGGES from LAPACK. iykyk π
β οΈ Attention β οΈ
The algorithm is implemented using BLAS level 3 operations. periodt.
π§ Remarks π§
ngl, real talk: the algorithm works without STRMM calls because of performance issues. All STRMM calls are replaced by block-GEMM operations. So therefore it is necessary that A and C contain zeros below the diagonal. No zeros below the diagonal, no slay. π«Ά
β¨ Parameters β¨
π€ TRANSA
TRANSA is CHARACTER(1). It specifies the form of the system of equations with respect to A and C:
== 'N':op1(A) = A,op1(C) = C(No transpose forAandC)== 'T':op1(A) = A**T,op1(C) = C **T(TransposeAandC)
π€ TRANSB
TRANSB is CHARACTER(1). It specifies the form of the system of equations with respect to B and D:
== 'N':op2(B) = B,op2(D) = D(No transpose forBandD)== 'T':op2(B) = B**T,op2(D) = D **T(TransposeBandD)
ββ SGN
SGN is REAL, allowed values: +/-1. It specifies the sign between the two parts of the Sylvester equation.
= 1: Solve Equation (1)== -1: Solve Equation (2)
π M
M is INTEGER. The order of the matrices A and C. M >= 0.
π N
N is INTEGER. The order of the matrices B and D. N >= 0.
π
°οΈ A
A is REAL array, dimension (LDA,M). The matrix A must be (quasi-) upper triangular.
π LDA
LDA is INTEGER. The leading dimension of the array A. LDA >= max(1,M).
π
±οΈ B
B is REAL array, dimension (LDB,N). The matrix B must be (quasi-) upper triangular. If the matrix D is already quasi-upper triangular the matrix B must be upper triangular. π
π LDB
LDB is INTEGER. The leading dimension of the array B. LDB >= max(1,N).
π
ΎοΈ C
C is REAL array, dimension (LDC,M). The matrix C must be upper triangular.
π LDC
LDC is INTEGER. The leading dimension of the array C. LDC >= max(1,M).
π D
D is REAL array, dimension (LDD,N). The matrix D must be (quasi-) upper triangular. If the matrix B is already quasi-upper triangular the matrix D must be upper triangular. (see? it's the mirror of the B situation, they're matching π)
π LDD
LDD is INTEGER. The leading dimension of the array D. LDD >= max(1,N).
β X
X is REAL array, dimension (LDX,N). On input, the matrix X contains the right hand side Y. On output, the matrix X contains the solution of Equation (1) or (2) as selected by TRANSA, TRANSB, and SGN. Right hand side Y and the solution X are M-by-N matrices. she does both jobs, iconic behavior π
π LDX
LDX is INTEGER. The leading dimension of the array X. LDX >= max(1,M).
βοΈ SCALE
SCALE is REAL. SCALE is a scaling factor to prevent the overflow in the result. If INFO == 0 then SCALE is 1.0 otherwise if one of the inner systems could not be solved correctly, 0 < SCALE <= 1 holds true. she's out here protecting your numbers from overflowing, a true bodyguard π‘οΈ
π οΈ WORK
WORK is REAL array, dimension LWORK. Workspace for the algorithm. You gotta query the workspace before running the computation, no skipping. The query is performed by calling the subroutine with INFO == -1 on input. The required workspace is then returned in INFO.
βΉοΈ INFO
INFO is INTEGER.
On input:
== -1: Perform a workspace query<> -1: normal operation
On exit, workspace query:
< 0: ifINFO = -i, thei-th argument had an illegal value>= 0: The value ofINFOis the required number of elements in the workspace.
On exit, normal operation:
== 0: successful exit< 0: ifINFO = -i, thei-th argument had an illegal value> 0: The equation is not solved correctly. One of the arising inner system got singular.
π Author π
Martin Koehler, MPI Magdeburg
π Date π
October 2025
π Definition π
Definition at line 204 of file sla_tgsylv_l3_colwise.f90.
alright bestie, new subroutine, new me β¨ meet the rowwise twin:
subroutine sla_tgsylv_l3_rowwise (character, dimension(1) transa, character,
dimension(1) transb, real sgn, integer m, integer n, real,
dimension(lda, *) a, integer lda, real, dimension(ldb, *) b, integer
ldb, real, dimension(ldc, *) c, integer ldc, real, dimension(ldd, *) d,
integer ldd, real, dimension(ldx, *) x, integer ldx, real scale, real,
dimension(*) work, integer info)
Level-3 Bartels-Stewart Algorithm for the generalized Sylvester equation. π₯
π― Purpose π―
Purpose:
!>
!> SLA_TGSYLV_L3_ROWWISE solves a generalized Sylvester equation of the following forms
!>
!> op1(A) * X * op2(B) + op1(C) * X * op2(D) = SCALE * Y (1)
!>
!> or
!>
!> op1(A) * X * op2(B) - op1(C) * X * op2(D) = SCALE * Y (2)
!>
!> where A is a M-by-M quasi upper triangular matrix, C is a M-by-M upper triangular
!> matrix and B and D are N-by-N upper triangular matrices. Furthermore either B or
!> D can be quasi upper triangular as well. The right hand side Y and the solution X
!> M-by-N matrices. Typically the matrix pencils (A,C) and (B,D) ( or (D,B) ) are
!> created by SGGES from LAPACK.
!>
Attention π
The algorithm is implemented using BLAS level 3 operations. That's the whole vibe, bestie. No cap.
Parameters π«Ά
TRANSAβTRANSAisCHARACTER(1). Specifies the form of the system of equations with respect toAandC:== 'N':op1(A) = A,op1(C) = C(No transpose forAandC)== 'T':op1(A) = A**T,op1(C) = C **T(TransposeAandC)
TRANSBβTRANSBisCHARACTER(1). Specifies the form of the system of equations with respect toBandD:== 'N':op2(B) = B,op2(D) = D(No transpose forBandD)== 'T':op2(B) = B**T,op2(D) = D **T(TransposeBandD)
SGNβSGNisREAL, allowed values:+/-1. Specifies the sign between the two parts of the Sylvester equation.= 1: Solve Equation (1)== -1: Solve Equation (2)
MβMisINTEGER. The order of the matricesAandC.M >= 0.NβNisINTEGER. The order of the matricesBandD.N >= 0.AβAisREALarray, dimension(LDA,M). The matrixAmust be (quasi-) upper triangular.LDAβLDAisINTEGER. The leading dimension of the arrayA.LDA >= max(1,M).BβBisREALarray, dimension(LDB,N). The matrixBmust be (quasi-) upper triangular. If the matrixDis already quasi-upper triangular the matrixBmust be upper triangular.LDBβLDBisINTEGER. The leading dimension of the arrayB.LDB >= max(1,N).CβCisREALarray, dimension(LDC,M). The matrixCmust be upper triangular.LDCβLDCisINTEGER. The leading dimension of the arrayC.LDC >= max(1,M).DβDisREALarray, dimension(LDD,N). The matrixDmust be (quasi-) upper triangular. If the matrixBis already quasi-upper triangular the matrixDmust be upper triangular.LDDβLDDisINTEGER. The leading dimension of the arrayD.LDD >= max(1,N).XβXisREALarray, dimension(LDX,N). On input, the matrixXcontains the right hand sideY. On output, the matrixXcontains the solution of Equation (1) or (2) as selected byTRANSA,TRANSB, andSGN. Right hand sideYand the solutionXareM-by-Nmatrices.LDXβLDXisINTEGER. The leading dimension of the arrayX.LDX >= max(1,M).SCALEβSCALEisREAL.SCALEis a scaling factor to prevent the overflow in the result. IfINFO == 0thenSCALEis1.0otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true.WORKβWORKisREALarray, dimensionLWORK. Workspace for the algorithm. The workspace needs to queried before the running the computation. The query is performed by calling the subroutine withINFO == -1on input. The required workspace is then returned inINFO.INFOβINFOisINTEGER.- On input:
== -1: Perform a workspace query<> -1: normal operation
- On exit, workspace query:
< 0: ifINFO = -i, the i-th argument had an illegal value>= 0: The value ofINFOis the required number of elements in the workspace.
- On exit, normal operation:
== 0: successful exit< 0: ifINFO = -i, the i-th argument had an illegal value> 0: The equation is not solved correctly. One of the arising inner system got singular.
- On input:
Author π
Martin Koehler, MPI Magdeburg
Date πΈ
October 2025
Definition at line ... π
Definition at line 203 of file sla_tgsylv_l3_rowwise.f90.
π¦ sla_tgsylv_recursive β Level-3 Recursive Blocked Solver π¦
recursive subroutine sla_tgsylv_recursive (character, dimension(1) transa,
character, dimension(1) transb, real sgn, integer m, integer n, real,
dimension(lda, *) a, integer lda, real, dimension(ldb, *) b, integer
ldb, real, dimension(ldc, *) c, integer ldc, real, dimension(ldd, *) d,
integer ldd, real, dimension(ldx, *) x, integer ldx, real scale, real,
dimension(*) work, integer info)
Level-3 Recursive Blocked Solver for the generalized Sylvester equation.
Purpose:
!>
!> SLA_TGSYLV_RECURSIVE solves a generalized Sylvester equation of the following forms
!>
!> op1(A) * X * op2(B) + op1(C) * X * op2(D) = SCALE * Y (1)
!>
!> or
!>
!> op1(A) * X * op2(B) - op1(C) * X * op2(D) = SCALE * Y (2)
!>
!> where A is a M-by-M quasi upper triangular matrix, C is a M-by-M upper triangular
!> matrix and B and D are N-by-N upper triangular matrices. Furthermore either B or
!> D can be quasi upper triangular as well. The right hand side E and the solution X
!> M-by-N matrices. Typically the matrix pencils (A,C) and (B,D) ( or (D,B) ) are
!> created by SGGES from LAPACK.
!>
Attention π
The algorithm is a rewrite of RECSY with some optimizations.
Parameters π«Ά
TRANSAβTRANSAisCHARACTER(1). Specifies the form of the system of equations with respect toAandC:== 'N':op1(A) = A,op1(C) = C(No transpose forAandC)== 'T':op1(A) = A**T,op1(C) = C **T(TransposeAandC)
TRANSBβTRANSBisCHARACTER(1). Specifies the form of the system of equations with respect toBandD:== 'N':op2(B) = B,op2(D) = D(No transpose forBandD)== 'T':op2(B) = B**T,op2(D) = D **T(TransposeBandD)
SGNβSGNisREAL, allowed values:+/-1. Specifies the sign between the two parts of the Sylvester equation.= 1: Solve Equation (1)== -1: Solve Equation (2)
MβMisINTEGER. The order of the matricesAandC.M >= 0.NβNisINTEGER. The order of the matricesBandD.N >= 0.AβAisREALarray, dimension(LDA,M). The matrixAmust be (quasi-) upper triangular.LDAβLDAisINTEGER. The leading dimension of the arrayA.LDA >= max(1,M).BβBisREALarray, dimension(LDB,N). The matrixBmust be (quasi-) upper triangular. If the matrixDis already quasi-upper triangular the matrixBmust be upper triangular.LDBβLDBisINTEGER. The leading dimension of the arrayB.LDB >= max(1,N).CβCisREALarray, dimension(LDC,M). The matrixCmust be upper triangular.LDCβLDCisINTEGER. The leading dimension of the arrayC.LDC >= max(1,M).DβDisREALarray, dimension(LDD,N). The matrixDmust be (quasi-) upper triangular. If the matrixBis already quasi-upper triangular the matrixDmust be upper triangular.LDDβLDDisINTEGER. The leading dimension of the arrayD.LDD >= max(1,N).XβXisREALarray, dimension(LDX,N). On input, the matrixXcontains the right hand sideY. On output, the matrixXcontains the solutionXof Equation (1) or (2) as selected byTRANSA,TRANSB, andSGN. Right hand sideYand the solutionXareM-by-Nmatrices.LDXβLDXisINTEGER. The leading dimension of the arrayX.LDX >= max(1,M).SCALEβSCALEisREAL.SCALEis a scaling factor to prevent the overflow in the result. IfINFO == 0thenSCALEis1.0otherwise if one of the inner systems could not be solved correctly,0 < SCALE <= 1holds true.WORKβWORKisREALarray, dimensionM*N. Workspace for the algorithmINFOβINFOisINTEGER== 0: successful exit< 0: ifINFO = -i, the i-th argument had an illegal value> 0: The equation is not solved correctly. One of the arising inner system got singular.
Author π
Martin Koehler, MPI Magdeburg
Date πΈ
October 2025
Definition at line ... π
Definition at line 190 of file sla_tgsylv_recursive.f90.
Author π
Generated automatically by Doxygen for MEPACK from the source code.
And that's a wrap, bestie! π This page is Version 1.1.2, dated Thu Oct 9 2025 00:00:00, and it's the sgltgsylv(3) manual. Slay! π
β¨
π¦ where this page comes from
- fedora 43: mepack-devel 1.1.2-1.fc43 Β· GPL-3.0-or-later and LGPL-2.1-or-later and BSD-3-Clause
- fedora 43: mepack-devel 1.1.2-1.fc43 Β· GPL-3.0-or-later and LGPL-2.1-or-later and BSD-3-Clause
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms