diff --git a/Project.toml b/Project.toml index 7452aec..c6f3a25 100644 --- a/Project.toml +++ b/Project.toml @@ -12,7 +12,6 @@ LazyArrays = "5078a376-72f3-5289-bfd5-ec5146d43c02" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" MatrixFactorizations = "a3b82374-2e81-5b9e-98ce-41277c0e4c87" PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a" -Reexport = "189a3867-3050-52da-a836-e630ba90ab69" [compat] ArrayInterface = "7.5" @@ -23,5 +22,8 @@ LazyArrays = "2" LinearAlgebra = "1" MatrixFactorizations = "3.1.3" PrecompileTools = "1.0.1" -Reexport = "1" +SciMLTesting = "2.10" julia = "1.10" + +[extras] +SciMLTesting = "09d9d899-5365-40a9-917a-5f67fddea283" diff --git a/README.md b/README.md index ef78070..4b760ed 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ repository. ### Basic Construction and Usage ```julia -using FastAlmostBandedMatrices, LinearAlgebra +using BandedMatrices, FastAlmostBandedMatrices, LinearAlgebra m = 2 # Fill rank n = 10 # Matrix dimension @@ -58,7 +58,7 @@ Q, R = fact.Q, fact.R
```julia -using BenchmarkTools, FastAlmostBandedMatrices, SparseArrays, FillArrays, LinearAlgebra +using BandedMatrices, BenchmarkTools, FastAlmostBandedMatrices, SparseArrays, FillArrays, LinearAlgebra import SemiseparableMatrices m = 5 diff --git a/docs/make.jl b/docs/make.jl index ff16a22..c507af4 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -5,7 +5,6 @@ makedocs(; authors = "Avik Pal et al.", modules = [FastAlmostBandedMatrices], clean = true, - doctest = false, linkcheck = false, checkdocs = :exports, format = Documenter.HTML(; diff --git a/docs/src/index.md b/docs/src/index.md index 4cd086d..0ea1cd2 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -22,7 +22,7 @@ Pkg.add("FastAlmostBandedMatrices") ## Basic Construction and Usage ```julia -using FastAlmostBandedMatrices, LinearAlgebra +using BandedMatrices, FastAlmostBandedMatrices, LinearAlgebra m = 2 # Fill rank n = 10 # Matrix dimension diff --git a/src/FastAlmostBandedMatrices.jl b/src/FastAlmostBandedMatrices.jl index c0e4b4f..d93cb49 100644 --- a/src/FastAlmostBandedMatrices.jl +++ b/src/FastAlmostBandedMatrices.jl @@ -2,8 +2,10 @@ module FastAlmostBandedMatrices import PrecompileTools: @setup_workload, @compile_workload -using ArrayInterface, ArrayLayouts, BandedMatrices, ConcreteStructs, LazyArrays, - LinearAlgebra, MatrixFactorizations, Reexport +using ArrayInterface, ArrayLayouts, ConcreteStructs, LazyArrays, LinearAlgebra, + MatrixFactorizations +import BandedMatrices +using BandedMatrices: bandwidth, bandwidths import ArrayLayouts: MemoryLayout, sublayout, MatLdivVec, materialize!, triangularlayout, triangulardata, colsupport, @@ -12,8 +14,6 @@ import BandedMatrices: _banded_qr!, banded_qr_lmul! import LinearAlgebra: ldiv! import MatrixFactorizations: QR, QRPackedQ, getQ, getR -@reexport using BandedMatrices - # ------------------ # DisjointRange - for zero-allocation colsupport # ------------------ @@ -95,7 +95,7 @@ abstract type AbstractAlmostBandedLayout <: MemoryLayout end struct AlmostBandedLayout <: AbstractAlmostBandedLayout end """ - AlmostBandedMatrix(bands::BandedMatrix, fill) + AlmostBandedMatrix(bands::BandedMatrices.BandedMatrix, fill) AlmostBandedMatrix{T}(bands, fill) AlmostBandedMatrix(::UndefInitializer, [::Type{T} = Float64], mn::NTuple{2, Integer}, lu::NTuple{2, Integer}, rank::Integer) @@ -117,6 +117,11 @@ overlapping bit. - `rank::Integer`: Number of rows in the fill component for an `undef` construction. It must be positive and no greater than `lu[2] + 1`. +# Fields + +- `bands`: Banded storage, including the part that overlaps with `fill`. +- `fill`: Dense or lazy low-rank storage for the leading rows. + # Notes Construction synchronizes the overlapping entries by copying the fill component into the @@ -144,10 +149,15 @@ part. # Example ```julia -bands = brand(Float64, 8, 8, 3, 2) +bands = BandedMatrices.brand(Float64, 8, 8, 3, 2) fill = rand(2, 8) A = AlmostBandedMatrix(bands, fill) ``` + +# Errors + +Throws `AssertionError` if `fill` has no rows, if `bands` and `fill` have different numbers +of columns, or if the lower bandwidth of `bands` is too small for the fill rank. """ @concrete struct AlmostBandedMatrix{T} <: LayoutMatrix{T} bands @@ -160,7 +170,7 @@ function AlmostBandedMatrix( ) where {T} @assert lu[2] ≥ rank - 1 @assert rank ≥ 1 "Rank 0 fill array makes it a BandedMatrix." - bands = BandedMatrix{T}(undef, mn, lu) + bands = BandedMatrices.BandedMatrix{T}(undef, mn, lu) fill = Matrix{T}(undef, rank, mn[2]) return AlmostBandedMatrix{T}(bands, fill) end @@ -180,7 +190,7 @@ function AlmostBandedMatrix( return AlmostBandedMatrix(undef, Float64, mn, lu, rank) end -function AlmostBandedMatrix(bands::BandedMatrix, fill::AbstractMatrix) +function AlmostBandedMatrix(bands::BandedMatrices.BandedMatrix, fill::AbstractMatrix) @assert size(fill, 2) == size(bands, 2) @assert size(fill, 1) ≥ 1 "Rank 0 fill array makes it a BandedMatrix." T = promote_type(eltype(fill), eltype(bands)) @@ -218,7 +228,7 @@ not mutated. # Example ```julia -A = AlmostBandedMatrix(brand(Float64, 8, 8, 3, 2), rand(2, 8)) +A = AlmostBandedMatrix(BandedMatrices.brand(Float64, 8, 8, 3, 2), rand(2, 8)) fillpart(A)[1, 1] = 1 finish_part_setindex!(A) ``` @@ -252,7 +262,7 @@ Returns the mutable `BandedMatrix` stored by `A`; it is not a copy. # Example ```julia -A = AlmostBandedMatrix(brand(Float64, 10, 10, 3, 2), rand(Float64, 2, 10)) +A = AlmostBandedMatrix(BandedMatrices.brand(Float64, 10, 10, 3, 2), rand(Float64, 2, 10)) B = bandpart(A) # Returns the BandedMatrix component ``` """ @@ -276,7 +286,7 @@ Returns the mutable fill matrix stored by `A`; it is not a copy. Call # Example ```julia -A = AlmostBandedMatrix(brand(Float64, 10, 10, 3, 2), rand(Float64, 2, 10)) +A = AlmostBandedMatrix(BandedMatrices.brand(Float64, 10, 10, 3, 2), rand(Float64, 2, 10)) F = fillpart(A) # Returns the fill matrix (2×10) ``` """ @@ -299,7 +309,7 @@ Returns a view into `bandpart(A)`, not a copy. # Example ```julia -A = AlmostBandedMatrix(brand(Float64, 10, 10, 3, 2), rand(Float64, 2, 10)) +A = AlmostBandedMatrix(BandedMatrices.brand(Float64, 10, 10, 3, 2), rand(Float64, 2, 10)) E = exclusive_bandpart(A) # Returns a view of rows 3:10 of the banded part ``` """ @@ -325,7 +335,7 @@ Returns `(l, u)`, where `l` is the lower bandwidth and `u` is the upper bandwidt # Example ```julia -A = AlmostBandedMatrix(brand(Float64, 10, 10, 3, 2), rand(Float64, 2, 10)) +A = AlmostBandedMatrix(BandedMatrices.brand(Float64, 10, 10, 3, 2), rand(Float64, 2, 10)) almostbandwidths(A) # Returns (3, 2) ``` """ @@ -351,7 +361,7 @@ Returns the number of rows in `fillpart(A)`. # Example ```julia -A = AlmostBandedMatrix(brand(Float64, 10, 10, 3, 2), rand(Float64, 2, 10)) +A = AlmostBandedMatrix(BandedMatrices.brand(Float64, 10, 10, 3, 2), rand(Float64, 2, 10)) almostbandedrank(A) # Returns 2 ``` """ @@ -529,7 +539,9 @@ function _almostbanded_qr(_, A) # Expand the bandsize for the QR factorization ## Bypass the safety checks in `AlmostBandedMatrix` return almostbanded_qr!( - AlmostBandedMatrix{eltype(A)}(BandedMatrix(copy(B), (l, l + u)), copy(L)), Val(true) + AlmostBandedMatrix{eltype(A)}( + BandedMatrices.BandedMatrix(copy(B), (l, l + u)), copy(L) + ), Val(true) ) end @@ -537,7 +549,7 @@ end function almostbanded_qr!(R::AbstractMatrix{T}, ::Val{false}) where {T} l, u = almostbandwidths(R) B, L = bandpart(R), fillpart(R) - R′ = AlmostBandedMatrix{eltype(R)}(BandedMatrix(B, (l, l + u)), L) + R′ = AlmostBandedMatrix{eltype(R)}(BandedMatrices.BandedMatrix(B, (l, l + u)), L) return almostbanded_qr!(R′, Val(true)) end @@ -754,7 +766,7 @@ end m = 2 n = 10 for T in (Float32, Float64) - B = brand(T, n, n, m + 1, m) + B = BandedMatrices.brand(T, n, n, m + 1, m) F = rand(T, m, n) @compile_workload begin diff --git a/test/Project.toml b/test/Project.toml index 5c80ac1..53e252d 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -1,5 +1,6 @@ [deps] ArrayLayouts = "4c555306-a7a7-4459-81d9-ec55ddd5c99a" +BandedMatrices = "aae01518-5342-5314-be14-df237901396f" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" MatrixFactorizations = "a3b82374-2e81-5b9e-98ce-41277c0e4c87" SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" @@ -9,6 +10,7 @@ Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [compat] ArrayLayouts = "1.12.2" +BandedMatrices = "1" MatrixFactorizations = "3.1.3" SafeTestsets = "0.1.0" SciMLTesting = "2.4" diff --git a/test/core_tests.jl b/test/core_tests.jl index 67b86ca..2b091ff 100644 --- a/test/core_tests.jl +++ b/test/core_tests.jl @@ -1,7 +1,25 @@ using SafeTestsets +@safetestset "Documented construction API" begin + using BandedMatrices, FastAlmostBandedMatrices + + exported = Set(names(FastAlmostBandedMatrices; all = false)) + @test :brand ∉ exported + @test all(name ∉ exported for name in (:Band, :BandedMatrix, :Fill, :band, :bandwidth, :brandn)) + + A = AlmostBandedMatrix(brand(Float64, 10, 10, 3, 2), rand(Float64, 2, 10)) + bands = BandedMatrices.BandedMatrix(fill(1.0, 10, 10), (3, 2)) + B = AlmostBandedMatrix(bands, rand(Float64, 2, 10)) + + @test A isa AlmostBandedMatrix + @test bandpart(A) isa BandedMatrices.BandedMatrix + @test almostbandwidths(A) == (3, 2) + @test almostbandedrank(A) == 2 + @test B isa AlmostBandedMatrix +end + @safetestset "Constructors" begin - using FastAlmostBandedMatrices + using BandedMatrices, FastAlmostBandedMatrices A = AlmostBandedMatrix{Float64}(undef, (10, 11), (2, 1), 2) A[1, 1] = 2 @@ -17,7 +35,7 @@ using SafeTestsets end @safetestset "similar" begin - using FastAlmostBandedMatrices + using BandedMatrices, FastAlmostBandedMatrices A = AlmostBandedMatrix(brand(Float64, 10, 10, 2, 1), rand(Float64, 2, 10)) @@ -30,7 +48,7 @@ end end @safetestset "Copy" begin - using FastAlmostBandedMatrices + using BandedMatrices, FastAlmostBandedMatrices n = 5 m = 2 @@ -48,7 +66,7 @@ end end @safetestset "QR" begin - using LinearAlgebra, FastAlmostBandedMatrices + using BandedMatrices, LinearAlgebra, FastAlmostBandedMatrices import MatrixFactorizations: QRPackedQ n = 80 @@ -76,7 +94,7 @@ end end @safetestset "Triangular" begin - using LinearAlgebra, ArrayLayouts, FastAlmostBandedMatrices + using BandedMatrices, LinearAlgebra, ArrayLayouts, FastAlmostBandedMatrices import FastAlmostBandedMatrices: AlmostBandedLayout n = 80 @@ -92,7 +110,7 @@ end # https://github.com/SciML/FastAlmostBandedMatrices.jl/issues/19 @safetestset "fill! on sparse array with BigFloat" begin - using FastAlmostBandedMatrices, SparseArrays + using BandedMatrices, FastAlmostBandedMatrices, SparseArrays A = sparse([1, 2], [1, 5], big.([1.0, 1.0])) A1 = AlmostBandedMatrix(brand(BigFloat, 5, 5, 1, 1), A) diff --git a/test/qa/alloc_tests.jl b/test/qa/alloc_tests.jl index c24ba51..98c9eb9 100644 --- a/test/qa/alloc_tests.jl +++ b/test/qa/alloc_tests.jl @@ -1,4 +1,5 @@ using AllocCheck +using BandedMatrices using FastAlmostBandedMatrices using FastAlmostBandedMatrices: DisjointRange using ArrayLayouts: colsupport, rowsupport diff --git a/test/qa/qa.jl b/test/qa/qa.jl index a10a599..45fb9ad 100644 --- a/test/qa/qa.jl +++ b/test/qa/qa.jl @@ -1,15 +1,7 @@ using SciMLTesting, FastAlmostBandedMatrices -const REEXPORTED_API = ( - :Band, :BandError, :BandRange, :BandedMatrices, :BandedMatrix, - :Eye, :Fill, :Ones, :Zeros, - :band, :bandrange, :bandwidth, :bandwidths, :brand, :brandn, - :colrange, :rowrange, :symrcm, -) - run_qa( FastAlmostBandedMatrices; - reexports_allow = REEXPORTED_API, # 19 method ambiguities, all in FastAlmostBandedMatrices' own ldiv!/__arguments # against ArrayLayouts/LinearAlgebra Triangular/Factorization methods. # https://github.com/SciML/FastAlmostBandedMatrices.jl/issues/71 @@ -38,8 +30,8 @@ run_qa( ), ), # 31 names implicitly imported via the package's `using ArrayInterface, ArrayLayouts, - # BandedMatrices, ConcreteStructs, LazyArrays, LinearAlgebra, ...` plus - # `@reexport using BandedMatrices`; explicit-import conversion tracked separately. + # BandedMatrices, ConcreteStructs, LazyArrays, LinearAlgebra, ...`; explicit-import + # conversion tracked separately. # https://github.com/SciML/FastAlmostBandedMatrices.jl/issues/71 ei_broken = (:no_implicit_imports,), )