From 814d8efa4414eee64ec06c71182d82eefcf95266 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Sun, 22 Feb 2026 03:30:10 -0600 Subject: [PATCH 1/3] Describe `LinearOperator{T, S}(args...)` in docs Add documentation for #383 Also cleans up an unnecessarily large number of `LinearOperator(M)` methods, preferring to consolidate them by supplying `M`-specific defaults for the `symmetric` and `hermitian` keyword arguments. --- src/abstract.jl | 9 +++++- src/constructors.jl | 71 ++++++++++++++++++++------------------------- 2 files changed, 39 insertions(+), 41 deletions(-) diff --git a/src/abstract.jl b/src/abstract.jl index 7f8ba015..709614a5 100644 --- a/src/abstract.jl +++ b/src/abstract.jl @@ -124,6 +124,13 @@ LinearOperator{T}( nctprod, ) +""" + LinearOperator{T, S}(nrow, ncol, symmetric, hermitian, prod!, tprod!, ctprod! = nothing) where {T, S} + +Construct a linear operator with a specific temporary array storage type `S`, which should typically have element type `T`. + +This is an inferrable variant of constructors that supply `S` as a keyword argument, and is recommended for performance-sensitive applications. +""" LinearOperator{T, S}( nrow::I, ncol::I, @@ -131,7 +138,7 @@ LinearOperator{T, S}( hermitian::Bool, prod!, tprod!, - ctprod!, + ctprod! = nothing, ) where {T, S, I <: Integer} = LinearOperator{T, S}(nrow, ncol, symmetric, hermitian, prod!, tprod!, ctprod!, 0, 0, 0) diff --git a/src/constructors.jl b/src/constructors.jl index 42d282bf..e10bb839 100644 --- a/src/constructors.jl +++ b/src/constructors.jl @@ -1,17 +1,26 @@ # Constructors. """ - LinearOperator(M::AbstractMatrix{T}; symmetric=false, hermitian=false, S = Vector{T}) where {T} -Construct a linear operator from a dense or sparse matrix. -Use the optional keyword arguments to indicate whether the operator -is symmetric and/or hermitian. -Change `S` to use LinearOperators on GPU. + LinearOperator(M::AbstractMatrix{T}; symmetric=defaultsymmetric(M), hermitian=defaulthermitian(M), S = Vector{T}) where {T} +Construct a linear operator from a dense or sparse matrix. Use the optional +keyword arguments to indicate whether the operator is symmetric and/or +hermitian. Change `S` to use LinearOperators on GPU. + +!!! tip + In performance-sensitive applications, it may be advisable to use + + LinearOperator{T, S}(M; kwargs...) + + instead. """ function LinearOperator( M::AbstractMatrix{T}; - symmetric = false, - hermitian = false, S = storage_type(M), + kwargs..., ) where {T} + return LinearOperator{T, S}(M; kwargs...) +end + +function LinearOperator{T, S}(M::AbstractMatrix{T}; symmetric = defaultsymmetric(M), hermitian = defaulthermitian(M)) where {T, S} nrow, ncol = size(M) prod! = @closure (res, v, α, β) -> mul!(res, M, v, α, β) tprod! = @closure (res, u, α, β) -> mul!(res, transpose(M), u, α, β) @@ -19,39 +28,14 @@ function LinearOperator( LinearOperator{T, S}(nrow, ncol, symmetric, hermitian, prod!, tprod!, ctprod!) end -""" - LinearOperator(M::Symmetric{T}, S = Vector{T}) where {T <: Real} = - -Construct a linear operator from a symmetric real square matrix `M`. -Change `S` to use LinearOperators on GPU. -""" -LinearOperator(M::Symmetric{T}, S = Vector{T}) where {T <: Real} = - LinearOperator(M, symmetric = true, hermitian = true, S = S) - -""" - LinearOperator(M::SymTridiagonal{T}, S = Vector{T}) where {T} - -Constructs a linear operator from a symmetric tridiagonal matrix. If -its elements are real, it is also Hermitian, otherwise complex -symmetric. -Change `S` to use LinearOperators on GPU. -""" -function LinearOperator(M::SymTridiagonal{T}, S = Vector{T}) where {T} - hermitian = eltype(M) <: Real - LinearOperator(M, symmetric = true, hermitian = hermitian, S = S) -end - -""" - LinearOperator(M::Hermitian{T}, S = Vector{T}) where {T} - -Constructs a linear operator from a Hermitian matrix. If -its elements are real, it is also symmetric. -Change `S` to use LinearOperators on GPU. -""" -function LinearOperator(M::Hermitian{T}, S = Vector{T}) where {T} - symmetric = eltype(M) <: Real - LinearOperator(M, symmetric = symmetric, hermitian = true, S = S) -end +defaultsymmetric(M) = false +defaulthermitian(M) = false +defaultsymmetric(M::Symmetric) = true +defaulthermitian(M::Symmetric{<:Real}) = true +defaultsymmetric(M::Hermitian) = eltype(M) <: Real +defaulthermitian(M::Hermitian) = true +defaultsymmetric(M::SymTridiagonal) = true +defaulthermitian(M::SymTridiagonal{<:Real}) = true """ LinearOperator(type::Type{T}, nrow, ncol, symmetric, hermitian, prod!, @@ -104,6 +88,13 @@ op = LinearOperator(Float64, 2, 2, false, false, ``` The 3-args `mul!` also works when applying the operator on a matrix. + +!!! tip + In performance-sensitive applications, it may be advisable to use + + LinearOperator{T, S}(nrow, ncol, symmetric, hermitian, prod!, tprod!=nothing, ctprod!=nothing) + + instead. """ function LinearOperator( ::Type{T}, From d96078edff203a8bc73de7a372524e7ac90ef5b6 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Sun, 22 Feb 2026 13:04:55 -0600 Subject: [PATCH 2/3] Add `nothing` default for `tprod!` --- src/abstract.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/abstract.jl b/src/abstract.jl index 709614a5..30c24d2f 100644 --- a/src/abstract.jl +++ b/src/abstract.jl @@ -137,7 +137,7 @@ LinearOperator{T, S}( symmetric::Bool, hermitian::Bool, prod!, - tprod!, + tprod! = nothing, ctprod! = nothing, ) where {T, S, I <: Integer} = LinearOperator{T, S}(nrow, ncol, symmetric, hermitian, prod!, tprod!, ctprod!, 0, 0, 0) From 70a5f287e598ab2801c72cb404bb7f869f299735 Mon Sep 17 00:00:00 2001 From: Alexis Montoison <35051714+amontoison@users.noreply.github.com> Date: Sun, 22 Feb 2026 15:39:59 -0500 Subject: [PATCH 3/3] Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/constructors.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/constructors.jl b/src/constructors.jl index e10bb839..5195a2c3 100644 --- a/src/constructors.jl +++ b/src/constructors.jl @@ -92,7 +92,7 @@ The 3-args `mul!` also works when applying the operator on a matrix. !!! tip In performance-sensitive applications, it may be advisable to use - LinearOperator{T, S}(nrow, ncol, symmetric, hermitian, prod!, tprod!=nothing, ctprod!=nothing) + LinearOperator{T, S}(nrow, ncol, symmetric, hermitian, prod!, tprod! = nothing, ctprod! = nothing) instead. """