LinearAlgebra.jl icon indicating copy to clipboard operation
LinearAlgebra.jl copied to clipboard

Remove implicit pinvs of vectors

Open antoine-levitt opened this issue 4 years ago • 8 comments

This is breaking, so probably has to wait until 2.0. At that point, can we remove /(x::Number, v::AbstractVector)? Its (marginal) utility is outmatched by its potential for confusion for new users and subtle bugs even for more experienced coders. More generally there are two and only two places where we call pinv on vectors implicitly:

(\)(a::AbstractVector, b::AbstractArray) = pinv(a) * b
/(x::Number, v::AbstractVector) = x*pinv(v)

I think we should just remove both. Pinv of a vector is just too confusing to be called implicitly. In fact, this is even more confusing because we don't allow number / matrix or matrix \ number, although pinv of a matrix makes way more sense than pinv of a vector. The fact that nobody has bothered adding this makes me think this function won't be missed.

antoine-levitt avatar Mar 11 '21 20:03 antoine-levitt

Yes, it does seem like we need to wait until 2.0.

We could prepare a PR and run package evaluator to see how breaking it is. If not, we could just roll it out.

ViralBShah avatar May 07 '21 22:05 ViralBShah

One could argue that matrix \ vector for least squares is also confusing and that there should be a separate syntax when matrix is not-invertible, e.g., matrix \\ vector, when a user actually really does want least squares

dlfivefifty avatar May 11 '21 19:05 dlfivefifty

That'd be even more breaking and a lot more controversial, but I'd be in favor also.

Another possibility is to keep \ as is, but remove / entirely. It's very rarely useful as a matrix-vector op (because of the "vectors are columns" convention), and many people don't even know it exists. I've only ever used it for change of basis (eg P * D / P)

antoine-levitt avatar May 11 '21 19:05 antoine-levitt

I use / all the time... e.g. 1 / 2....

I like the principle of / and \ being just left and right versions of the same operation. Anything else feels arbitrary from a mathematical perspective (though I do agree anyone coming from Matlab will only ever use \ for linear algebra.)

It's the fact that either uses least squares that's the problem, particularly since it's completely inconsistent between square and rectangular matrices:

julia> zeros(1,1) \ [1]
1-element Vector{Float64}:
 Inf

julia> zeros(2,1) \ [1,1]
1-element Vector{Float64}:
 0.0

julia> pinv(zeros(1,1)) * [1]
1-element Vector{Float64}:
 0.0

Having a distinct syntax would fix this.

dlfivefifty avatar May 11 '21 19:05 dlfivefifty

Pseudo-inverses are A^+, so possibly /+ and \+ could be made to parse as operators? Although you can certainly use least squares without being aware of pseudoinverses, so it might not be useful to reference pseudo inverses

antoine-levitt avatar May 11 '21 19:05 antoine-levitt

Agree that removing the \ for least squares could be very disruptive, and is something to be considered 2.0.

ViralBShah avatar May 11 '21 20:05 ViralBShah

Also ref. JuliaLang/LinearAlgebra.jl#554 regarding making / and \ only do division in the narrower sense. I'd be in favor, but agree that it's obviously 2.0-stuff.

martinholters avatar May 17 '21 10:05 martinholters

Fix for the scalar case in https://github.com/JuliaLang/julia/pull/44358

ViralBShah avatar Mar 13 '22 05:03 ViralBShah