Hi,
This is related to a discussion within the lengthy tread that spun off Yuri’s blog post. I don’t want to make that thread even longer with off-topic material.
In that thread, when discussing Julia’s ecosystem @juliohm asked why we have 3 packages for iterative solvers, and he cited IterativeSolvers.jl, Krylov.jl, and KrylovKit.jl.
As I’m very interested in iterative solvers and this kind of “package ecosystem” issues, I dug a little bit into this and I think I found the answer in KrylovKit docs:
KrylovKit accepts general functions to represent the linear map or operator that defines the problem, without having to wrap them in a
LinearMap
orLinearOperator
type. Of course, subtypes ofAbstractMatrix
are also supported. If the linear map (always the first argument) is a subtype ofAbstractMatrix
, matrix-vector multiplication is used, otherwise, it is applied as a function call.
The magic is, of course, achieved via multiple-dispatch.
See the extremely simple and elegant apply.jl code in that package, which contains lines like:
apply(A::AbstractMatrix, x::AbstractVector) = A * x
apply(f, x) = f(x)
which are then used:
function GMRES(operator, ...)
y₀ = apply(operator, x₀)
(...)
end
I believe this is both a pretty elegant example of multiple dispatch (actually, I’m going to make this my example of multiple-dispatch in my blog’s tutorial (I still don’t have one) and that this is also the most “Julian” way to write an Iterative solver, so I guess I’m going to start recommending this package as well in my numerical computing tutorial (after testing it, of course).
Now, a few thoughts about the ecosystem.
As Julia developed, many great package names were available, like “IterativeSolvers”, which will win Google rankings in a trivial way (by direct keyword hit). This package is also maintained by an organization called JuliaLinearAlgebra, which lead one to think that, somehow, IterativeSolvers.jl is the “official” Julia package for iterative solvers.
However, I believe InterativeSolvers.jl is simply the oldest package, and, for some reason, the creators of both Krylov.jl and KrylovKit.jl decided to create a separate package instead of creating PRs to the existing one, maybe because that was easier.
As for Krylov.jl, they list in their docs:
All solvers in Krylov.jl have an in-place version, are compatible with GPU, and work in any floating-point data type.
So I guess it was one of those features that made them deviate from the other packages.
I guess in situations like this, the different package authors can learn from each other, and yes, eventually it would be desirable that someone merges all the contributions into a single package, to avoid duplicated efforts, and to give all users the best possible experience.
However, I’m not really sure how this could be accomplished. Maybe it’s just a matter of letting the individual contributors decide to which package they are willing to contribute to, and let the more motivated/friendlier package maintainer summarize the best efforts.