-
Notifications
You must be signed in to change notification settings - Fork 42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make LinearMap a subtype of AbstractMatrix to increase code compatibility? #180
Comments
It would be neat to support (e.g.) Alternatively, we could have a wrapper (Example use case: we do solve |
I asked @ChrisRackauckas for advice, good defaults might me julia> import DensityInterface # To get some Pkg init stuff out of the way
julia> @time_imports using LinearMaps, Krylov
104.9 ms LinearMaps
10.3 ms Krylov |
This was discussed in #38. Nice to see another vote in favor of |
Thanks for the link @JeffFessler , I hadn't been aware of LinearMapsAA and I had overlooked #38. I do get the arguments in #38 regarding getindex - but an ineffecient getindex hasn't stopped GPU arrays from being very successful. There is a lot of code that asks for an |
There's also the issue that code that want's to support both |
@oschulz , is there any reason to "depend on" LinearMaps.jl for compatibility? Why not just be generic and leave argument types unspecified; any user input that can multiply with a vector and produce a new vector would be accepted? That was at least the advice that was given to me by Steven Johnson when I started using Julia in 2014 and started working on this package. The choice for not making It seems the lack of formal interface specifications, and the potential issues that arise from that, start to pop up in various places in the Julia ecosystem. |
But that's basically saying "don't use multiple dispatch". Code may need to distinguish between "array-like" object and other types, e.g. scalars, to implement optimized methods. The
I couldn't agree more - and it leads to a web of complicated (semver-unsafe) Since Julia doesn't have multiple dispatch (directly), we can't really have an "operator-like" supertype for |
In an ideal world (which I realise is not what we always live in), that optimisation should be done at the level of the methods that implement "linear map (of any kind)" * vector, no? By scalar I assume you mean, scalar times the identity matrix? I do assume you don't want to have completely different behaviour if the argument is a scalar instead of a matrix? Cause that would be abusing multiple dispatch; completely different behaviour would imply different methods. Note that It is not that I am radically against making |
For example, but also more general let's say you have something like
A
for the case that
Well, just on the purely practical side I guess many algorithms in packages (and possibly std libs as well) that could efficiently utilize Also, just speaking for myself, I do like restricting method arguments - types carry semantic meaning, and can make code more readable and wrong types get caught earlier. And multiple-dispatch needs good type hierarchies. |
True, there's several "linear operator/map" kinds around ... we have LinearMaps.jl, LinearOperators.jl (very similar but different type - maybe some synergy potential there), FFTW.jl plans support at least part of the "linear operator interface" (CC @stevengj) and maybe there's more as well. It would be nice to have an |
CC @dpo, @abelsiqueira and @geoffroyleconte (LinearOperators.jl). |
When I first brought up #38, I also felt pretty strongly that a I agree that it could be beneficial to have a |
Many things have been said already, so let me add my two cents here. First, making julia> using LinearMaps
WARNING: Method definition hcat(Union{LinearAlgebra.UniformScaling{T} where T<:Number, Union{AbstractArray{T, 1}, AbstractArray{T, 2}} where T}...) in module LinearAlgebra at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.7/LinearAlgebra/src/uniformscaling.jl:408 overwritten in module LinearMaps at /Users/karrasch/.julia/dev/LinearMaps/src/blockmap.jl:84.
** incremental compilation may be fatally broken for this module **
WARNING: Method definition vcat(Union{LinearAlgebra.UniformScaling{T} where T<:Number, Union{AbstractArray{T, 1}, AbstractArray{T, 2}} where T}...) in module LinearAlgebra at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.7/LinearAlgebra/src/uniformscaling.jl:408 overwritten in module LinearMaps at /Users/karrasch/.julia/dev/LinearMaps/src/blockmap.jl:122.
** incremental compilation may be fatally broken for this module **
WARNING: Method definition hvcat(Tuple{Vararg{Int64}}, Union{LinearAlgebra.UniformScaling{T} where T<:Number, Union{AbstractArray{T, 1}, AbstractArray{T, 2}} where T}...) in module LinearAlgebra at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.7/LinearAlgebra/src/uniformscaling.jl:427 overwritten in module LinearMaps at /Users/karrasch/.julia/dev/LinearMaps/src/blockmap.jl:167.
** incremental compilation may be fatally broken for this module ** That is, we would not be able to unambiguously concatenate And, in fact, I have worked hard in Long story short: (a) I don't think making Regarding the solving issue, we now have |
I suspect that a trait is better than a supertype for this. (For one thing, a package that defines a |
From a viewpoint of dispatch/ambiguity, e.g. with functions that deal with operators and functions (since function already have no clear supertype), I think an abstract supertype would be helpful. We could still have traits for "efficient getindex" and so on, and functions that can handle operators and matrices could dispatch on |
Oh, right, that would be a problem. Ok, no making it an array. :-) |
My apologies in case this has been discussed before. @dkarrasch would you consider making
LinearMap{T}
a subtype ofAbstractMatrix{T}
?I've really grow to love the flexibility of
LinearMap
s and the ability to use them as drop-in replacements for matrices in many applications. But sometimes that's not easy because generic code in packages frequently requires anAbstractMatrix
as the argument type - aLinearMap
would often work well since a lot of code only uses high-level linear algebra operations, butLinearMap
andAbstractMatrix
just have no common supertype that typical package code would dispatch on.To me, a
LinearMap
feels like a matrix in almost every way already - is has a size, element type, etc. What it currently doesn't have isgetindex
- but I think it could.A[:,:]
andA[:,j]
would be efficient, and ifA
is transposable thenA[i,:]
would be efficient as well. Even views would be somewhat efficient I guess, justA[i,j]
would be horribly inefficient of course. But the same is true for Julia GPU arrays likeCuArray
- one could adopt the same warning/error mechanism implemented there that alerts users that serial/element-wise access is inefficient (or even prevents it).The text was updated successfully, but these errors were encountered: