# A\\b vs LinearSolve.jl at JuliaCon 2022

**URL:** <https://discourse.julialang.org/t/a-b-vs-linearsolve-jl-at-juliacon-2022/85030>\
**Category:** General Usage\
**Created:** [July 30, 2022, 2:37pm UTC](https://discourse.julialang.org/t/a-b-vs-linearsolve-jl-at-juliacon-2022/85030 "2022-07-30T14:37:08Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![KZiemian](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kziemian/32/9020_2.png) [@KZiemian](https://discourse.julialang.org/u/KZiemian)\
**Post date:** [July 30, 2022, 2:37pm UTC](https://discourse.julialang.org/t/a-b-vs-linearsolve-jl-at-juliacon-2022/85030/1 "2022-07-30T14:37:08Z")

</div>

I just end watching [_LinearSolve.jl: because A\b is not good enough_](https://www.youtube.com/watch?v=JWI34_w-yYw) by Chris Rackauckas himself and I’m a bit confused. When I get basic points why such packages was developed, somethings bugs me about `A\b` being “deprecated”.

I understand why [LinearSolve.jl](https://github.com/SciML/LinearSolve.jl) was created, factor 2 in solving differential equation is something that I cannot ignore, but I just like `A\b` because of its syntax.

Also, it seems to me that even when [LinearSolve.jl](https://github.com/SciML/LinearSolve.jl) is package that unified dozens of packages under the hood, simple numerical computation in Julia become to complicated for my taste, because you have to many options to choose. Maybe I’m just to stupid to learn Julia and its ecosystem well at this point in time.

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [July 30, 2022, 2:47pm UTC](https://discourse.julialang.org/t/a-b-vs-linearsolve-jl-at-juliacon-2022/85030/2 "2022-07-30T14:47:53Z")

</div>

`A \ b` has never been optimal. It has always been the case that there are better alternatives. In particular, you can often use knowledge about the specific matrix (structures, size, sparsity, …) to pick a better solver.

However, in some cases `A \ b` is good enough – not all programs spend the majority of time in the linear solver. `A \ b` is not being deprecated, and you can still use it.

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [July 30, 2022, 3:13pm UTC](https://discourse.julialang.org/t/a-b-vs-linearsolve-jl-at-juliacon-2022/85030/3 "2022-07-30T15:13:46Z")

</div>

One thing worth noting is that we will probably at some point make `A\b` smarter. There’s no reason `A\b` needs to be slower than the default `LinearSolve` solver. The big advantage of `LinearSolve` is that it provides an interface for customization, but that’s a fairly advanced use case. For 90% of users, we can make `A\b` as good.

---

<div class="post-metadata">

**Author:** ![KZiemian](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kziemian/32/9020_2.png) [@KZiemian](https://discourse.julialang.org/u/KZiemian)\
**Post date:** [July 30, 2022, 6:18pm UTC](https://discourse.julialang.org/t/a-b-vs-linearsolve-jl-at-juliacon-2022/85030/4 "2022-07-30T18:18:53Z")

</div>

From what I understand form Rackauckas talk, the biggest stumbling block is that some algorithms need more information that knowing `A` and `b` in `A\b`, like relative error of the method (result?). People with much more knowledge of Julia internals are need to answer how serious problem it is.

But, when in the cases that all information is in `A` and `b` making some multiple dispatch magic to make algorithm smarter doesn’t seems impossible. Are they some catches here?

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [July 30, 2022, 7:29pm UTC](https://discourse.julialang.org/t/a-b-vs-linearsolve-jl-at-juliacon-2022/85030/5 "2022-07-30T19:29:49Z")

</div>

> [@KZiemian](#):
>
> I understand why [LinearSolve.jl](https://github.com/SciML/LinearSolve.jl) was created, factor 2 in solving differential equation is something that I cannot ignore, but I just like `A\b` because of its syntax.

> [@fredrikekre](#):
>
> However, in some cases `A \ b` is good enough – not all programs spend the majority of time in the linear solver. `A \ b` is not being deprecated, and you can still use it.

`A\b` is fine. It’s not going to go anywhere. Deprecating it would be silly. But, if you’re going to write a package that needs to allow customizability of the linear solver in order for the algorithm to be optimal in all possible cases, then `A\b` is a bad interface to build off of. At no time do I advocate for getting rid of `A\b`, in fact I say that it has quite a bit of smarts in it. But, it’s just not good enough for many applications, and it will never be a standard library since it would have to allow hooks for a ton of (very large) artifact dependencies and a lot of other cruft that doesn’t deserve to be in the standard library.

> [@KZiemian](#):
>
> From what I understand form Rackauckas talk, the biggest stumbling block is that some algorithms need more information that knowing `A` and `b` in `A\b`, like relative error of the method (result?). People with much more knowledge of Julia internals are need to answer how serious problem it is.

It actually goes pretty deep, and it takes a bit of implementing to really see why. One naïve thing you can do is say, okay, what about `\(A,b;kwargs...)` as the interface? But you end up with a lot of weird behavior really quickly. For example, if you do `\(method(A),b;abstol,reltol)`, you might think that `lu` would work right off the bat, i.e. `\(lu(A),b;abstol,reltol)`. But psych, if you do that today you’d get a `MethodNotFound()` error because the `\` dispatch on `LU` does not match any keyword arguments. So you can go through and either

1. Write out (and ignore) all keyword arguments that would make a common interface (pretty messy for Base).
2. Have every `\` on a factorization dispatch splat keyword arguments (this is an awful idea for the standard library because now it won’t throw errors when keyword arguments are misspelled, it’ll just ignore them 😅 You can then create separate error parsing and…).
3. Target the standard interface at a different level to leave `\` alone to avoid having to add more methods (and deal with ambiguities).

If we did go down this route (which is one I championed for about 5 years BTW), you still would have to have all downstream libraries adopt it, and it’s not necessarily easy. You’d have to create a lazy `IterativeSolvers.cg(A)` that doesn’t do anything until `\(IterativeSolvers.cg(A),b;abstol,reltol)`. Cool, that’s just a bit of code churn. But then some of the harder to wrap libraries can have increasingly difficult issues with how to make that call nicely lazy because you’re also then trying to reuse that syntax for reuse.

What I mean is that `luA = lu!(A); \(luA,b;abstol,reltol); \(luA,b2;abstol,reltol)` reuses the LU-factorization of `A`. What is effectively going on now is that you’re mixing the notation of lazy call for method selection with the notation for factorization reuse. And if you actually want that to be efficient, then you need to make sure it’s actually a sufficient syntax for factorization reuse in all cases. In order for that to be the case with sparse matrices, you would need to know the sparsity pattern of the previous matrix in order to know whether to save the symbolic factorization. So instead the syntax would need to be something like `\(lu(luA,A2),b;abstol,reltol)` where `luA` is either the previous factorization (it cannot be the matrix itself because only the factorization object holds the symbolic factorization result, and it also needs to check the sparsity pattern).

Now I bet you $20 that if you had to go around telling people “we’re deprecating `A\b` for `\(lu!(nothing,A),b;abstol,reltol)` because it’s a cleaner syntax to generalize to iterative solvers and optimally using sparse matrices purely by dispatching on `method` and `A`!”, people would be pissed. No, that is absolutely worse for most cases!

That’s why it’s a separate interface, built off of (in many cases) tools first made in Base.LinearAlgebra, that is focused on a `problem`/`solve` syntax that works no matter the choice of `A` and `method`. The reason is because that’s exactly the kind of thing that a generic library needs to use: a generic library needs to handle any input someone throws at it with as minimal special casing as possible. LinearSolve.jl does that special casing.

But, I and hopefully many others will continue to use `A\b` in the REPL. It’s good enough for that, but not for everything else we need to build.

(There are other things I’m skipping too, like how for fully non-allocating `lu!`/`ldiv!` you need to allocate and store the workspace / pivot vectors somewhere, which is handled only when you get to the `\(lu!(nothing,A),b;abstol,reltol)` idea, so the sparse factorization stuff actually improves the dense case as well, but these are details)

---

<div class="post-metadata">

**Author:** ![KZiemian](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kziemian/32/9020_2.png) [@KZiemian](https://discourse.julialang.org/u/KZiemian)\
**Post date:** [July 31, 2022, 10:50am UTC](https://discourse.julialang.org/t/a-b-vs-linearsolve-jl-at-juliacon-2022/85030/6 "2022-07-31T10:50:44Z")

</div>

From things written in this thread and discussed in JuliaCon talk, I draw two points.

1. `A\b` is fine when you work in REPL, but, hopefully, we can make it better.
2. Ecosystem for solving system of linear equations must be very broad, but at the same time, more order in it is welcomed.

I wish that my skill would be good enough to help with second point, but at this moment I need to study Git, not Julia.
