I have the following question which virtually applies to all defined linear algebra objects in Julia/LinearAlgebra:
Why there are no consistency checks when constructing linear algebra objects?
As an example, let’s consider the Schur data type, which is defined as:
struct Schur{Ty,S<:AbstractMatrix} <: Factorization{Ty}
T::S
Z::S
values::Vector
end
This structure contains two matrices T
and Z
of the same type and a vector values
. It has nothing specific related to the Schur decomposition, as claimed by the documentation. This can be easily checked by the following construction:
julia> F = Schur(rand(3,3),rand(2,1),rand(0))
Schur{Float64, Matrix{Float64}}
T factor:
3×3 Matrix{Float64}:
0.851595 0.622935 0.416998
0.493628 0.782394 0.54265
0.522581 0.995593 0.996112
Z factor:
2×1 Matrix{Float64}:
0.6150198969878795
0.08655354595467768
eigenvalues:
Float64[]
To avoid such misconstructions, I am missing the following minimal checks: T
and Z
should be both square matrices of the same order, say n
, and values
should be a vector of length n
. More involved tests could also check that T
is quasi-upper triangular in the general real case or upper triangular in the general complex case.
I would like to add that as far as some linear algebra data types serve only to pack the computed results, this setup could be acceptable. However, if the constructed objects are arguments of other functions, then the situation is different. As an example, this lack of checks is disturbing, especially when in a next step I would like to “reorder” the eigenvalues:
ordschur(F,falses(5))
** On entry to DTRSEN parameter number 8 had an illegal value
ERROR: ArgumentError: invalid argument #8 to LAPACK call
Here ordchur
accepts the above Schur object without complaints, delivers its elements to the trsen!
wrapper to the LAPACK routine DTRSEN
, and, finally, the inconsistency is discovered only at the level of this routine with an error message which still requires further inspection of the LAPACK code.
The inconsistency could even remain undetected, leading to completely nonsense results:
ordschur(Schur(rand(3,3),rand(3,1),rand(0)),falses(5))
Schur{Float64, Matrix{Float64}}
T factor:
3×3 Matrix{Float64}:
0.848517 0.385575 0.183215
0.0834543 0.938042 0.919729
0.746262 0.886942 0.0102043
Z factor:
3×1 Matrix{Float64}:
0.3533799437577295
0.7928718694559094
0.01924732093261672
eigenvalues:
3-element Vector{ComplexF64}:
0.8485167187308525 + 0.1793818626275508im
0.9380416658902896 + 0.9031867257980865im
0.01020433757434469 - 0.9031867257980865im
I would like to hear other opinions on how much checking is necessary to build only meaningful linear algebra objects.