Implement solve (\) for general rectangular static matrices#1313
Implement solve (\) for general rectangular static matrices#1313cgarling wants to merge 9 commits intoJuliaArrays:masterfrom
\) for general rectangular static matrices#1313Conversation
src/solve.jl
Outdated
| R₁ = SMatrix{Sa[2], Sa[2]}(q.R[SOneTo(Sa[2]), SOneTo(Sa[2])]) | ||
| R₁ \ y | ||
| else | ||
| q.R' * ((q.R * q.R') \ y) |
There was a problem hiding this comment.
| q.R' * ((q.R * q.R') \ y) | |
| q.R' * (q.R' \ (q.R \ y)) |
should be a lot faster, if q.R is annotated as UpperTriangular (you could wrap it if not).
There was a problem hiding this comment.
Thanks for the review, couple questions:
q.R has dimensions (Sa[1], Sa[2]) with Sa[1] < Sa[2]. I don't see how to use UpperTriangular on a non-square matrix as, for example, UpperTriangular(rand(2,3)) gives ERROR: DimensionMismatch: matrix is not square: dimensions are (2, 3). Am I missing something?
Using the expression q.R' * (q.R' \ (q.R \ y)) you provided results in a stack overflow error, I believe because of the (q.R \ y) which will recurse infinitely because q.R has the same dimensions as argument a and y has the same dimensions as argument b. Any suggestions to improve this are welcome
|
It's a good idea but why don't just copy the logic from https://github.com/JuliaLang/LinearAlgebra.jl/blob/16f64e78769d788376df0f36447affdb7b1b3df6/src/qr.jl#L700 and adapt to StaticArrays.jl? Also, I'd prefer to have the logic for wide/thin case in I also support the use of the |
|
Updates implementing suggestions have been pushed |
|
Thanks for the updates. Could you also address the last remaining point from my post? To be more specific, I think we could use the logic of |
|
I spent some time look at the code in Is your concern one of accuracy/correctness or performance? If my solution is correct, I would ask that it be accepted as it is many times faster than the current LinearAlgebra fallback and does not allocate, which solves issues like #1292. I could add a |
…voted QR by default in solve
|
I've ported that method myself and added some tests which revealed a problem. The good news is that it works fast, without any allocations (Julia can stack-allocate non-escaping mutable structs). The bad news is that LinearAlgebra by default uses pivoted QR which is necessary for rank-deficient problems (see the new test case 4). Which is slower and currently not handled correctly by So, the two remaining issues:
Could you address point 2? It's actually a matter of correctness as you can see in the failing tests. |
|
Thanks for the help! One new problem is that with the pivoted QR we need to permute the result from Edit: It's our |
|
One risk of calling a non- |
This should close #1292. Results are much faster now that it no longer falls back to LinearAlgebra.jl.
Note that in the calculation for the underdetermined case on line 77,
q.R' * ((q.R * q.R') \ y)is an approximation for the pseudoinversepinvwhich in general may be more accurate, but it also seemed a lot slower in my testing so I did not use it here. It looks like there might a better-conditioned way to calculate it using the results of the QR decomposition but I am not a linear algebra expect so some help there would be appreciated.