Skip to content

BigFloat compatibility for qr_jacobimatrix #146

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jul 30, 2023
Merged

BigFloat compatibility for qr_jacobimatrix #146

merged 7 commits into from
Jul 30, 2023

Conversation

TSGut
Copy link
Member

@TSGut TSGut commented Jul 26, 2023

@dlfivefifty @MikaelSlevinsky This PR restores BigFloat compatibility to the QR variants of jacobimatrix computation. The fix in theory also addresses Cholesky but that remains broken because of a similar issue in InfiniteLinearAlgebra.jl exemplified by

julia> P = Normalized(legendre(big(0)..big(1)))
Normalized(Legendre{BigFloat}() affine mapped to 0..1)

julia> X = jacobimatrix(P)
ℵ₀×ℵ₀ LazyBandedMatrices.SymTridiagonal{BigFloat, Fill{BigFloat, 1, Tuple{InfiniteArrays.OneToInf{Int64}}}, BroadcastVector{BigFloat, typeof(sqrt), Tuple{BroadcastVector{BigFloat, typeof(*), Tuple{BroadcastVector{BigFloat, typeof(/), Tuple{BroadcastVector{BigFloat, typeof(/), Tuple{InfiniteArrays.InfStepRange{BigFloat, BigFloat}, InfiniteArrays.InfStepRange{Int64, Int64}}}, BigFloat}}, BroadcastVector{BigFloat, typeof(/), Tuple{BroadcastVector{BigFloat, typeof(/), Tuple{InfiniteArrays.InfStepRange{BigFloat, BigFloat}, InfiniteArrays.InfStepRange{Int64, Int64}}}, BigFloat}}}}}}} with indices OneToInf()×OneToInf():
 0.5       0.288675                                                         
 0.288675  0.5       0.258199                                                 
          0.258199  0.5       0.253546                                        
                   0.253546  0.5       0.251976                               
                            0.251976  0.5       0.251259                      
                                     0.251259  0.5       0.250873            
                                              0.250873  0.5       0.25064     
                                                       0.25064   0.5         
                                                                0.25049     
                                                                                

julia> cholesky(Symmetric(X^2)).U[1,1]
ERROR: UndefRefError: access to undefined reference
Stacktrace:
  [1] getindex
    @ ./essentials.jl:14 [inlined]
  [2] getindex
    @ ./subarray.jl:286 [inlined]
  [3] _getindex
    @ ./abstractarray.jl:1344 [inlined]
  [4] getindex
    @ ./abstractarray.jl:1294 [inlined]
  [5] macro expansion
    @ ~/Documents/Backends/julia-1.9.0/share/julia/stdlib/v1.9/LinearAlgebra/src/generic.jl:221 [inlined]
  [6] macro expansion
    @ ./simdloop.jl:77 [inlined]
  [7] lmul!(s::BigFloat, X::SubArray{BigFloat, 2, Matrix{BigFloat}, Tuple{UnitRange{Int64}, UnitRange{Int64}}, false})
    @ LinearAlgebra ~/Documents/Backends/julia-1.9.0/share/julia/stdlib/v1.9/LinearAlgebra/src/generic.jl:220
  [8] _banded_lmul!
    @ ~/.julia/packages/BandedMatrices/qLIMl/src/generic/broadcast.jl:938 [inlined]
  [9] banded_lmul!
    @ ~/.julia/packages/BandedMatrices/qLIMl/src/generic/broadcast.jl:947 [inlined]
 [10] materialize!
    @ ~/.julia/packages/BandedMatrices/qLIMl/src/generic/broadcast.jl:950 [inlined]
 [11] #lmul!#10
    @ ~/.julia/packages/ArrayLayouts/3K92Y/src/lmul.jl:47 [inlined]
 [12] lmul!
    @ ~/.julia/packages/ArrayLayouts/3K92Y/src/lmul.jl:47 [inlined]
 [13] default_blasmul!::BigFloat, A::Adjoint{BigFloat, SubArray{BigFloat, 2, BandedMatrix{BigFloat, Matrix{BigFloat}, Base.OneTo{Int64}}, Tuple{UnitRange{Int64}, UnitRange{Int64}}, false}}, B::SubArray{BigFloat, 2, BandedMatrix{BigFloat, Matrix{BigFloat}, Base.OneTo{Int64}}, Tuple{UnitRange{Int64}, UnitRange{Int64}}, false}, β::BigFloat, C::SubArray{BigFloat, 2, BandedMatrix{BigFloat, Matrix{BigFloat}, Base.OneTo{Int64}}, Tuple{UnitRange{Int64}, UnitRange{Int64}}, false})
    @ ArrayLayouts ~/.julia/packages/ArrayLayouts/3K92Y/src/muladd.jl:172
 [14] materialize!(M::ArrayLayouts.MulAdd{BandedMatrices.BandedRows{ArrayLayouts.DenseColumnMajor}, BandedMatrices.BandedColumns{ArrayLayouts.DenseColumnMajor}, BandedMatrices.BandedColumns{ArrayLayouts.DenseColumnMajor}, BigFloat, Adjoint{BigFloat, SubArray{BigFloat, 2, BandedMatrix{BigFloat, Matrix{BigFloat}, Base.OneTo{Int64}}, Tuple{UnitRange{Int64}, UnitRange{Int64}}, false}}, SubArray{BigFloat, 2, BandedMatrix{BigFloat, Matrix{BigFloat}, Base.OneTo{Int64}}, Tuple{UnitRange{Int64}, UnitRange{Int64}}, false}, SubArray{BigFloat, 2, BandedMatrix{BigFloat, Matrix{BigFloat}, Base.OneTo{Int64}}, Tuple{UnitRange{Int64}, UnitRange{Int64}}, false}})
    @ ArrayLayouts ~/.julia/packages/ArrayLayouts/3K92Y/src/muladd.jl:241
 [15] muladd!
    @ ~/.julia/packages/ArrayLayouts/3K92Y/src/muladd.jl:70 [inlined]
 [16] partialcholesky!(F::InfiniteLinearAlgebra.AdaptiveCholeskyFactors{BigFloat, BandedMatrix{BigFloat, Matrix{BigFloat}, Base.OneTo{Int64}}, ApplyArray{BigFloat, 2, typeof(*), Tuple{LazyBandedMatrices.SymTridiagonal{BigFloat, Fill{BigFloat, 1, Tuple{InfiniteArrays.OneToInf{Int64}}}, BroadcastVector{BigFloat, typeof(sqrt), Tuple{BroadcastVector{BigFloat, typeof(*), Tuple{BroadcastVector{BigFloat, typeof(/), Tuple{BroadcastVector{BigFloat, typeof(/), Tuple{InfiniteArrays.InfStepRange{BigFloat, BigFloat}, InfiniteArrays.InfStepRange{Int64, Int64}}}, BigFloat}}, BroadcastVector{BigFloat, typeof(/), Tuple{BroadcastVector{BigFloat, typeof(/), Tuple{InfiniteArrays.InfStepRange{BigFloat, BigFloat}, InfiniteArrays.InfStepRange{Int64, Int64}}}, BigFloat}}}}}}}, LazyBandedMatrices.SymTridiagonal{BigFloat, Fill{BigFloat, 1, Tuple{InfiniteArrays.OneToInf{Int64}}}, BroadcastVector{BigFloat, typeof(sqrt), Tuple{BroadcastVector{BigFloat, typeof(*), Tuple{BroadcastVector{BigFloat, typeof(/), Tuple{BroadcastVector{BigFloat, typeof(/), Tuple{InfiniteArrays.InfStepRange{BigFloat, BigFloat}, InfiniteArrays.InfStepRange{Int64, Int64}}}, BigFloat}}, BroadcastVector{BigFloat, typeof(/), Tuple{BroadcastVector{BigFloat, typeof(/), Tuple{InfiniteArrays.InfStepRange{BigFloat, BigFloat}, InfiniteArrays.InfStepRange{Int64, Int64}}}, BigFloat}}}}}}}}}}, n::Int64)
    @ InfiniteLinearAlgebra ~/.julia/packages/InfiniteLinearAlgebra/y1GuF/src/infcholesky.jl:35
 [17] getindex(F::InfiniteLinearAlgebra.AdaptiveCholeskyFactors{BigFloat, BandedMatrix{BigFloat, Matrix{BigFloat}, Base.OneTo{Int64}}, ApplyArray{BigFloat, 2, typeof(*), Tuple{LazyBandedMatrices.SymTridiagonal{BigFloat, Fill{BigFloat, 1, Tuple{InfiniteArrays.OneToInf{Int64}}}, BroadcastVector{BigFloat, typeof(sqrt), Tuple{BroadcastVector{BigFloat, typeof(*), Tuple{BroadcastVector{BigFloat, typeof(/), Tuple{BroadcastVector{BigFloat, typeof(/), Tuple{InfiniteArrays.InfStepRange{BigFloat, BigFloat}, InfiniteArrays.InfStepRange{Int64, Int64}}}, BigFloat}}, BroadcastVector{BigFloat, typeof(/), Tuple{BroadcastVector{BigFloat, typeof(/), Tuple{InfiniteArrays.InfStepRange{BigFloat, BigFloat}, InfiniteArrays.InfStepRange{Int64, Int64}}}, BigFloat}}}}}}}, LazyBandedMatrices.SymTridiagonal{BigFloat, Fill{BigFloat, 1, Tuple{InfiniteArrays.OneToInf{Int64}}}, BroadcastVector{BigFloat, typeof(sqrt), Tuple{BroadcastVector{BigFloat, typeof(*), Tuple{BroadcastVector{BigFloat, typeof(/), Tuple{BroadcastVector{BigFloat, typeof(/), Tuple{InfiniteArrays.InfStepRange{BigFloat, BigFloat}, InfiniteArrays.InfStepRange{Int64, Int64}}}, BigFloat}}, BroadcastVector{BigFloat, typeof(/), Tuple{BroadcastVector{BigFloat, typeof(/), Tuple{InfiniteArrays.InfStepRange{BigFloat, BigFloat}, InfiniteArrays.InfStepRange{Int64, Int64}}}, BigFloat}}}}}}}}}}, k::Int64, j::Int64)
    @ InfiniteLinearAlgebra ~/.julia/packages/InfiniteLinearAlgebra/y1GuF/src/infcholesky.jl:42
 [18] getindex(A::UpperTriangular{BigFloat, InfiniteLinearAlgebra.AdaptiveCholeskyFactors{BigFloat, BandedMatrix{BigFloat, Matrix{BigFloat}, Base.OneTo{Int64}}, ApplyArray{BigFloat, 2, typeof(*), Tuple{LazyBandedMatrices.SymTridiagonal{BigFloat, Fill{BigFloat, 1, Tuple{InfiniteArrays.OneToInf{Int64}}}, BroadcastVector{BigFloat, typeof(sqrt), Tuple{BroadcastVector{BigFloat, typeof(*), Tuple{BroadcastVector{BigFloat, typeof(/), Tuple{BroadcastVector{BigFloat, typeof(/), Tuple{InfiniteArrays.InfStepRange{BigFloat, BigFloat}, InfiniteArrays.InfStepRange{Int64, Int64}}}, BigFloat}}, BroadcastVector{BigFloat, typeof(/), Tuple{BroadcastVector{BigFloat, typeof(/), Tuple{InfiniteArrays.InfStepRange{BigFloat, BigFloat}, InfiniteArrays.InfStepRange{Int64, Int64}}}, BigFloat}}}}}}}, LazyBandedMatrices.SymTridiagonal{BigFloat, Fill{BigFloat, 1, Tuple{InfiniteArrays.OneToInf{Int64}}}, BroadcastVector{BigFloat, typeof(sqrt), Tuple{BroadcastVector{BigFloat, typeof(*), Tuple{BroadcastVector{BigFloat, typeof(/), Tuple{BroadcastVector{BigFloat, typeof(/), Tuple{InfiniteArrays.InfStepRange{BigFloat, BigFloat}, InfiniteArrays.InfStepRange{Int64, Int64}}}, BigFloat}}, BroadcastVector{BigFloat, typeof(/), Tuple{BroadcastVector{BigFloat, typeof(/), Tuple{InfiniteArrays.InfStepRange{BigFloat, BigFloat}, InfiniteArrays.InfStepRange{Int64, Int64}}}, BigFloat}}}}}}}}}}}, i::Int64, j::Int64)
    @ LinearAlgebra ~/Documents/Backends/julia-1.9.0/share/julia/stdlib/v1.9/LinearAlgebra/src/triangular.jl:232
 [19] top-level scope

Once that is fixed we can remove the _broken from the test added here.

@codecov
Copy link

codecov bot commented Jul 26, 2023

Codecov Report

Patch coverage: 100.00% and project coverage change: +0.01% 🎉

Comparison is base (aaa182b) 91.76% compared to head (729870c) 91.78%.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #146      +/-   ##
==========================================
+ Coverage   91.76%   91.78%   +0.01%     
==========================================
  Files          17       17              
  Lines        1822     1825       +3     
==========================================
+ Hits         1672     1675       +3     
  Misses        150      150              
Files Changed Coverage Δ
src/choleskyQR.jl 100.00% <100.00%> (ø)

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@TSGut
Copy link
Member Author

TSGut commented Jul 26, 2023

Ok @dlfivefifty , after some digging: the error above for Cholesky appears to live in this line https://github.com/JuliaLinearAlgebra/InfiniteLinearAlgebra.jl/blob/0fc35261c6e8a8ce2bb4b647cbf935855e4b81ec/src/infcholesky.jl#L35

ArrayLayouts fails to materialize MulAdd for certain BigFloat matrices. I can avoid this by special casing the line including muladd!() to just to the lazy multiplication α * A * B + β C for T==BigFloat without the fancy BLAS-like machinery. Any alternative ideas I am missing before I do that?

( btw which entry does muladd!() overwrite? is it A? the docs are a bit unclear at https://github.com/JuliaLinearAlgebra/ArrayLayouts.jl/blob/master/src/muladd.jl )

@dlfivefifty
Copy link
Member

🤷‍♂️ I can't find the code where I had to work around this. But definitely don't specialise to T == BigFloat, just use isprimitivetype

@TSGut
Copy link
Member Author

TSGut commented Jul 27, 2023

I wasn't aware of isprimitivetype but it's exactly what I was looking for, nice.

@TSGut
Copy link
Member Author

TSGut commented Jul 27, 2023

We technically don't need Cholesky to work for SemiclassicalOPs but it would feel silly to leave that part of the issue open. I think we just need muladd!() to have a method for bigfloats, even if it isn't as elegant.

# we fill 1 entry on the first run
dv = zeros(T,2)
# we fill 1 entry on the first run and circumvent BigFloat issue
dv = zeros(T,2)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try not to add extra spaces to ends of lines

@dlfivefifty dlfivefifty merged commit f193783 into JuliaApproximation:main Jul 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants