Skip to content
Merged
6 changes: 4 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -58,7 +58,7 @@ Q, R = fact.Q, fact.R
<p>

```julia
using BenchmarkTools, FastAlmostBandedMatrices, SparseArrays, FillArrays, LinearAlgebra
using BandedMatrices, BenchmarkTools, FastAlmostBandedMatrices, SparseArrays, FillArrays, LinearAlgebra
import SemiseparableMatrices

m = 5
Expand Down
1 change: 0 additions & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ makedocs(;
authors = "Avik Pal et al.",
modules = [FastAlmostBandedMatrices],
clean = true,
doctest = false,
linkcheck = false,
checkdocs = :exports,
format = Documenter.HTML(;
Expand Down
2 changes: 1 addition & 1 deletion docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
46 changes: 29 additions & 17 deletions src/FastAlmostBandedMatrices.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
# ------------------
Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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))
Expand Down Expand Up @@ -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)
```
Expand Down Expand Up @@ -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
```
"""
Expand All @@ -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)
```
"""
Expand All @@ -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
```
"""
Expand All @@ -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)
```
"""
Expand All @@ -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
```
"""
Expand Down Expand Up @@ -529,15 +539,17 @@ 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

# Band size not yet expanded!
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

Expand Down Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions test/Project.toml
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -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"
30 changes: 24 additions & 6 deletions test/core_tests.jl
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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))

Expand All @@ -30,7 +48,7 @@ end
end

@safetestset "Copy" begin
using FastAlmostBandedMatrices
using BandedMatrices, FastAlmostBandedMatrices

n = 5
m = 2
Expand All @@ -48,7 +66,7 @@ end
end

@safetestset "QR" begin
using LinearAlgebra, FastAlmostBandedMatrices
using BandedMatrices, LinearAlgebra, FastAlmostBandedMatrices
import MatrixFactorizations: QRPackedQ

n = 80
Expand Down Expand Up @@ -76,7 +94,7 @@ end
end

@safetestset "Triangular" begin
using LinearAlgebra, ArrayLayouts, FastAlmostBandedMatrices
using BandedMatrices, LinearAlgebra, ArrayLayouts, FastAlmostBandedMatrices
import FastAlmostBandedMatrices: AlmostBandedLayout

n = 80
Expand All @@ -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)
Expand Down
1 change: 1 addition & 0 deletions test/qa/alloc_tests.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using AllocCheck
using BandedMatrices
using FastAlmostBandedMatrices
using FastAlmostBandedMatrices: DisjointRange
using ArrayLayouts: colsupport, rowsupport
Expand Down
12 changes: 2 additions & 10 deletions test/qa/qa.jl
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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,),
)
Loading