Conversation
Codecov Report❌ Patch coverage is
... and 1 file with indirect coverage changes 🚀 New features to boost your workflow:
|
63b2cb2 to
fc70f25
Compare
| S⁻¹ = minS ./ S | ||
| # sum the series on the smaller side only, the other side follows from Yᴴ = Y₀ᴴ + S⁻¹ X' AP; | ||
| # for m > n, work with the adjoint problem, which swaps X and Yᴴ | ||
| m > n && ((AP, X₀, Y₀ᴴ) = (AP', Y₀ᴴ', X₀')) |
There was a problem hiding this comment.
This looks like it results in some type instability, but I'm not sure if the compiler just union-splits this correctly.
In any case, it might be better to make this a bit more explicit and manually write out the two cases, either duplicating the code or introducing a function barrier?
There was a problem hiding this comment.
I would also prefer to see this separated in the two cases 😄 .
There was a problem hiding this comment.
I separated the two cases, and I split off the actual doubling iteration in a separate _smith_iteration! routine that is now used in both the SVD and eigh pullbacks. I was told the doubling method is usually referred to as a "squared Smith iteration", hence the method name. The warning inside still says "Sylvester iteration", which I thought was fine since it makes it more clear we're solving a Sylvester equation.
|
Ok, very nice, and also somewhat trivial in hindsight. Very stupid of me to not spot this when I was deriving this. |
Co-authored-by: Jutho <Jutho@users.noreply.github.com>
4dd40de to
90af904
Compare
| is_leading_index(ind::AbstractVector, p::Int) = length(ind) == p && all(ind .== 1:p) | ||
|
|
||
| """ | ||
| _smith_iteration!(X, Xₙ, G, w, atol, maxiter) |
There was a problem hiding this comment.
According to
https://www.sciencedirect.com/science/article/pii/S0893965909000263
this is the "Smith accelerative iteration", for which they also refer to this original Smith paper:
https://www.jstor.org/stable/pdf/2099416.pdf
Could you maybe add the reference and also change the name to
accelerative_smith_iteration!
I don't think the leading underscore is necessary; this can be a useful method to be used for other things as well.
svd_trunc_pullback!sums the Neumann series of both complement equations by doubling, forXwithAP * AP'(m × m) and forYᴴwithAP' * AP(n × n). The two are not independent:Yᴴ = Y₀ᴴ + S⁻¹ X' AP. This PR sums the series on the smaller side only and gets the other one from that single product (form > nit works with the adjoint problem, which swapsXandYᴴ). Each doubling step then squares one Gram matrix instead of two, and the stopping criterion checks the summed side only.It's the same series with the same stopping criterion: on the cases below the result agrees with
mainto at most 2.4e-15 (relative), and it is 2.0–2.6× faster for the square and small cases and 3.5–5.4× for the large rectangular ones, where the larger of the two Gram matrices drops out (except 1.6× for real 1400×1000; laptop timings, minimum of 5).Benchmark (time and error against the full-spectrum `svd_pullback!`)
On
main:With this PR: