Skip to content
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

v1.0 #255

Merged
merged 25 commits into from
May 17, 2024
Merged

v1.0 #255

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
ef6234d
Compact show for `BlockRange` (#248)
jishnub Apr 3, 2023
27bc4e1
Merge branch 'master' into release-1.0
jishnub Mar 22, 2024
3fb6573
Fetch changes to convert for BlockedUnitRange
jishnub Mar 22, 2024
ab3dce9
Merge branch 'master' into release-1.0
jishnub Mar 28, 2024
aab5fa8
Merge branch 'master' into release-1.0
jishnub Apr 1, 2024
222a79a
Merge branch 'master' into release-1.0
jishnub Apr 1, 2024
9d8a552
Bump version to v1.0.0-dev
jishnub Apr 1, 2024
3c352fa
Merge branch 'master' into release-1.0
jishnub Apr 2, 2024
c89df62
Merge branch 'master' into release-1.0
jishnub Apr 3, 2024
7766ac9
Merge branch 'master' into release-1.0
jishnub Apr 4, 2024
4ee907e
Add `BlockedOneTo` as the axis type for a `BlockedArray` (#348)
jishnub Apr 4, 2024
94e7ca3
Infinite broadcast tests (#383)
jishnub Apr 4, 2024
4a7b1df
Specialize blockedrange BroadcastStyle for LazyArrayStyle (#384)
jishnub Apr 7, 2024
6987f0b
Merge branch 'master' into release-1.0
jishnub Apr 7, 2024
b361279
Define dataids for PseudoBlockArrays (#364) (#385)
jishnub Apr 7, 2024
d02efe6
Banded Matrix extension (#388)
dlfivefifty Apr 23, 2024
8639776
Generalize the element type of `BlockedUnitRange` (#337)
mtfishman Apr 23, 2024
465569a
Allow non-Int eltypes in BlockedOneTo (#395)
jishnub Apr 27, 2024
e3e69c7
Move LazyArrays extension to LazyArrays.jl (#393)
dlfivefifty May 1, 2024
928dea7
Use FillArrays accumulate overloads (#397)
dlfivefifty May 7, 2024
ee57d11
Redefine blocksizes (#399)
mtfishman May 14, 2024
3c9abe3
Rename PseudoBlockArray to BlockedArray (#401)
mtfishman May 16, 2024
8621223
v1.0, add README
dlfivefifty May 16, 2024
11e1f26
rename files
dlfivefifty May 16, 2024
70e6e02
Update README.md
dlfivefifty May 17, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/CompatHelper.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
run: which julia
continue-on-error: true
- name: Install Julia, but only if it is not already available in the PATH
uses: julia-actions/setup-julia@v1
uses: julia-actions/setup-julia@v2
with:
version: '1'
arch: ${{ runner.arch }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:
- x64
steps:
- uses: actions/checkout@v4
- uses: julia-actions/setup-julia@v1
- uses: julia-actions/setup-julia@v2
with:
version: ${{ matrix.version }}
arch: ${{ matrix.arch }}
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: julia-actions/setup-julia@v1
- uses: julia-actions/setup-julia@v2
with:
version: '1.10'
- uses: julia-actions/cache@v1
- uses: julia-actions/cache@v2
- name: Install dependencies
run: julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'
run: julia --project=docs/ -e 'using Pkg; Pkg.update(); Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'
- name: Build and deploy
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # If authenticating with GitHub Actions token
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/downstream.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:

steps:
- uses: actions/checkout@v4
- uses: julia-actions/setup-julia@v1
- uses: julia-actions/setup-julia@v2
with:
version: ${{ matrix.julia-version }}
arch: x64
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ src/.DS_Store
Manifest.toml
Manifest-v*.*.toml
.DS_Store
.*.swp
build
19 changes: 14 additions & 5 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
name = "BlockArrays"
uuid = "8e7c35d0-a365-5155-bbbb-fb81a777f24e"
version = "0.16.44-dev"
version = "1.0.0"

[deps]
ArrayLayouts = "4c555306-a7a7-4459-81d9-ec55ddd5c99a"
BandedMatrices = "aae01518-5342-5314-be14-df237901396f"
FillArrays = "1a297f60-69ca-5386-bcde-b61e274b549b"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"

[weakdeps]
BandedMatrices = "aae01518-5342-5314-be14-df237901396f"

[extensions]
BlockArraysBandedMatricesExt = "BandedMatrices"

[compat]
Aqua = "0.8"
ArrayLayouts = "1.0.8"
Documenter = "1"
FillArrays = "1"
BandedMatrices = "1.0"
Documenter = "1.0"
FillArrays = "1.11"
LinearAlgebra = "1.6"
OffsetArrays = "1"
OffsetArrays = "1.0"
Random = "1.6"
SparseArrays = "1.6"
StaticArrays = "1.6"
Expand All @@ -22,6 +30,7 @@ julia = "1.6"

[extras]
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
BandedMatrices = "aae01518-5342-5314-be14-df237901396f"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Expand All @@ -30,4 +39,4 @@ StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Aqua", "Documenter", "OffsetArrays", "SparseArrays", "StaticArrays", "Test", "Random"]
test = ["Aqua", "BandedMatrices", "Documenter", "OffsetArrays", "SparseArrays", "StaticArrays", "Test", "Random"]
36 changes: 35 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@

A block array is a partition of an array into blocks or subarrays, see [wikipedia](https://en.wikipedia.org/wiki/Block_matrix) for a more extensive description. This package has two purposes. Firstly, it defines an interface for an `AbstractBlockArray` block arrays that can be shared among types representing different types of block arrays. The advantage to this is that it provides a consistent API for block arrays.

Secondly, it also implements two different type of block arrays that follow the `AbstractBlockArray` interface. The type `BlockArray` stores each block contiguously while the type `PseudoBlockArray` stores the full matrix contiguously. This means that `BlockArray` supports fast non copying extraction and insertion of blocks while `PseudoBlockArray` supports fast access to the full matrix to use in in for example a linear solver.
Secondly, it also implements two different type of block arrays that follow the `AbstractBlockArray` interface. The type `BlockArray` stores each block contiguously while the type `BlockedArray` stores the full matrix contiguously. This means that `BlockArray` supports fast non copying extraction and insertion of blocks while `BlockedArray` supports fast access to the full matrix to use in in for example a linear solver.

A simple way to produce `BlockArray`s is via `mortar`, which combines an array of arrays into a `BlockArray`:
```julia
julia> using BlockArrays

julia> mortar([randn(3), randn(4)])
2-blocked 7-element BlockVector{Float64}:
-0.19808699390960527
Expand All @@ -33,11 +35,43 @@ julia> mortar(reshape([randn(2,2), randn(1,2), randn(2,3), randn(1,3)],2,2))
0.430093 -0.0263753 │ -1.31275 0.278447 -0.139579
```

Alternatively, one can add block structure on top of an existing array by wrapping the array in `BlockedArray`, where the extra arguments give the sizes of the blocks:
```julia
julia> BlockedArray(randn(7), [3,4])
2-blocked 7-element BlockedVector{Float64}:
-0.17348560551451797
-0.5680124317024628
1.699007590285868
─────────────────────
-0.7437814954416642
-0.018198226033108045
1.3335354818213445
-0.03512135185007728

julia> BlockedArray(randn(3,5), [2,1], [2,3])
2×2-blocked 3×5 BlockedMatrix{Float64}:
0.444186 0.788823 │ 0.743428 -0.815026 0.715779
-0.721074 -0.43783 │ 1.07413 -0.336926 0.539873
──────────────────────┼─────────────────────────────────
0.128836 -0.350202 │ -2.71365 1.67605 -0.25611
```


## Documentation

- [**STABLE**][docs-stable-url] — **most recently tagged version of the documentation.**
- [**LATEST**][docs-dev-url] — *in-development version of the documentation.*

## Changes in v1.0

We are excited to release v1.0! There are some important breaking changes from previous versions of BlockArrays.jl:

- `BlockedArray` replaces `PseudoBlockArray`.
- Axes are now typically `BlockedOneTo` instead of `BlockUnitRange`.
- Support for some simple block-banded matrices has been moved here from BlockBandedMatrices.jl.
- The definition of `blocksizes(array::AbstractArray)` is changed from `blocklengths.(axes(array))` to an iterator of size `blocksize(array)` over the sizes of each block of `array`.
- `BlockedUnitRange` is now parametrized by the element type instead of hardcoded to `Int`.

## Contributing

Possible ways of contributing to this package include:
Expand Down
2 changes: 1 addition & 1 deletion benchmark/runbenchmarks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ g = addgroup!(SUITE, "indexing")
g_size = addgroup!(SUITE, "size")

for n = (5,)
for BT in (BlockArray, PseudoBlockArray)
for BT in (BlockArray, BlockedArray)
block_vec = BT(rand(n), [1,3,1])
block_mat = BT(rand(n,n), [1,3,1], [4,1])
block_arr = BT(rand(n,n,n), [1,3,1], [4,1], [3, 2])
Expand Down
2 changes: 1 addition & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ makedocs(
"Manual" => [
"man/abstractblockarrayinterface.md",
"man/blockarrays.md",
"man/pseudoblockarrays.md",
"man/blockedarrays.md",
],
"API" => [
"lib/public.md",
Expand Down
4 changes: 2 additions & 2 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

A block array is a partition of an array into multiple blocks or subarrays, see [wikipedia](https://en.wikipedia.org/wiki/Block_matrix) for a more extensive description. This package has two purposes. Firstly, it defines an interface for an `AbstractBlockArray` block arrays that can be shared among types representing different types of block arrays. The advantage to this is that it provides a consistent API for block arrays.

Secondly, it also implements two concrete types of block arrays that follow the `AbstractBlockArray` interface. The type `BlockArray` stores each single block contiguously, by wrapping an `AbstractArray{<:AbstractArray{T,N},N}` to concatenate all blocks – the complete array is thus not stored contiguously. Conversely, a `PseudoBlockArray` stores the full matrix contiguously (by wrapping only one `AbstractArray{T, N}`) and only superimposes a block structure. This means that `BlockArray` supports fast non copying extraction and insertion of blocks, while `PseudoBlockArray` supports fast access to the full matrix to use in, for example, a linear solver.
Secondly, it also implements two concrete types of block arrays that follow the `AbstractBlockArray` interface. The type `BlockArray` stores each single block contiguously, by wrapping an `AbstractArray{<:AbstractArray{T,N},N}` to concatenate all blocks – the complete array is thus not stored contiguously. Conversely, a `BlockedArray` stores the full matrix contiguously (by wrapping only one `AbstractArray{T, N}`) and only superimposes a block structure. This means that `BlockArray` supports fast non copying extraction and insertion of blocks, while `BlockedArray` supports fast access to the full matrix to use in, for example, a linear solver.


## Terminology
Expand Down Expand Up @@ -39,7 +39,7 @@ A block array layout is specified its _block sizes_ – a tuple of `AbstractArra
## Manual Outline

```@contents
Pages = ["man/abstractblockarrayinterface.md", "man/blockarrays.md", "man/pseudoblockarrays.md"]
Pages = ["man/abstractblockarrayinterface.md", "man/blockarrays.md", "man/blockedarrays.md"]
Depth = 2
```

Expand Down
2 changes: 2 additions & 0 deletions docs/src/lib/internals.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ Pages = ["internals.md"]
```@docs
blockcolsupport
blockrowsupport
blockedrange
BlockedOneTo
BlockedUnitRange
BlockRange
BlockIndexRange
Expand Down
8 changes: 4 additions & 4 deletions docs/src/lib/public.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,12 @@ Base.popfirst!
```


## PseudoBlockArray
## BlockedArray

```@docs
PseudoBlockArray
PseudoBlockVector
PseudoBlockMatrix
BlockedArray
BlockedVector
BlockedMatrix
Base.resize!
```

Expand Down
6 changes: 3 additions & 3 deletions docs/src/man/abstractblockarrayinterface.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# The block axis interface

A block array's block structure is dictated by its axes, which
are typically a `BlockedUnitRange` but may also be a `UnitRange`,
which is assumed to be a single block, or other type that implements
A block array's block structure is dictated by its axes. These
are typically `BlockedOneTo`s, but may also be standard and non-blocked `AbstractUnitRange`s
(which are assumed to correspond to a single block), or other type that implements
the block axis interface.


Expand Down
8 changes: 4 additions & 4 deletions docs/src/man/blockarrays.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ julia> BlockArray(Array(reshape(1:16, 4, 4)), [2,2], [1,1,2])
julia> S = spzeros(4,5); S[1,2] = S[4,3] = 1;

julia> block_array_sparse = BlockArray(S, [1,3], [2,3])
2×2-blocked 4×5 BlockMatrix{Float64, Matrix{SparseMatrixCSC{Float64, Int64}}, Tuple{BlockedUnitRange{Vector{Int64}}, BlockedUnitRange{Vector{Int64}}}}:
2×2-blocked 4×5 BlockMatrix{Float64, Matrix{SparseMatrixCSC{Float64, Int64}}, Tuple{BlockedOneTo{Int64, Vector{Int64}}, BlockedOneTo{Int64, Vector{Int64}}}}:
⋅ 1.0 │ ⋅ ⋅ ⋅
──────────┼───────────────
⋅ ⋅ │ ⋅ ⋅ ⋅
Expand Down Expand Up @@ -67,7 +67,7 @@ The `block_type` should be an array type. It specifies the internal block type,

```jldoctest
julia> BlockArray(undef_blocks, SparseVector{Float64, Int}, [1,2])
2-blocked 3-element BlockVector{Float64, Vector{SparseVector{Float64, Int64}}, Tuple{BlockedUnitRange{Vector{Int64}}}}:
2-blocked 3-element BlockVector{Float64, Vector{SparseVector{Float64, Int64}}, Tuple{BlockedOneTo{Int64, Vector{Int64}}}}:
#undef
──────
#undef
Expand Down Expand Up @@ -151,7 +151,7 @@ julia> view(A, Block(2)) .= [3,4]; A[Block(2)]
4.0

julia> view(A, Block.(1:2))
3-element view(::BlockVector{Float64, Vector{Vector{Float64}}, Tuple{BlockedUnitRange{ArrayLayouts.RangeCumsum{Int64, UnitRange{Int64}}}}}, BlockSlice(BlockRange(1:2),1:1:3)) with eltype Float64 with indices 1:1:3:
3-element view(::BlockVector{Float64, Vector{Vector{Float64}}, Tuple{BlockedOneTo{Int64, ArrayLayouts.RangeCumsum{Int64, UnitRange{Int64}}}}}, BlockSlice(BlockRange(1:2),1:1:3)) with eltype Float64 with indices BlockedOneTo([1, 3]):
1.0
3.0
4.0
Expand All @@ -167,7 +167,7 @@ An array can be repacked into a `BlockArray` with `BlockArray(array, block_sizes
julia> S = spzeros(4,5); S[1,2] = S[4,3] = 1;

julia> block_array_sparse = BlockArray(S, [1,3], [2,3])
2×2-blocked 4×5 BlockMatrix{Float64, Matrix{SparseMatrixCSC{Float64, Int64}}, Tuple{BlockedUnitRange{Vector{Int64}}, BlockedUnitRange{Vector{Int64}}}}:
2×2-blocked 4×5 BlockMatrix{Float64, Matrix{SparseMatrixCSC{Float64, Int64}}, Tuple{BlockedOneTo{Int64, Vector{Int64}}, BlockedOneTo{Int64, Vector{Int64}}}}:
⋅ 1.0 │ ⋅ ⋅ ⋅
──────────┼───────────────
⋅ ⋅ │ ⋅ ⋅ ⋅
Expand Down
24 changes: 12 additions & 12 deletions docs/src/man/pseudoblockarrays.md → docs/src/man/blockedarrays.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# PseudoBlockArrays
# BlockedArrays

```@meta
DocTestSetup = quote
Expand All @@ -8,22 +8,22 @@ DocTestSetup = quote
end
```

A `PseudoBlockArray` is similar to a [`BlockArray`](@ref) except the full array is stored
A `BlockedArray` is similar to a [`BlockArray`](@ref) except the full array is stored
contiguously instead of block by block. This means that is not possible to insert and retrieve
blocks without copying data. On the other hand, converting a `PseudoBlockArray` to the "full" underlying array is instead instant since
blocks without copying data. On the other hand, converting a `BlockedArray` to the "full" underlying array is instead instant since
it can just return the wrapped array.

When iteratively solving a set of equations with a gradient method the Jacobian typically has a block structure. It can be convenient
to use a `PseudoBlockArray` to build up the Jacobian block by block and then pass the resulting matrix to
to use a `BlockedArray` to build up the Jacobian block by block and then pass the resulting matrix to
a direct solver using `Matrix`.

## Creating PseudoBlockArrays
## Creating BlockedArrays

Creating a `PseudoBlockArray` works in the same way as a `BlockArray`.
Creating a `BlockedArray` works in the same way as a `BlockArray`.

```jldoctest A
julia> pseudo = PseudoBlockArray(reshape([1:9;], 3, 3), [1,2], [2,1])
2×2-blocked 3×3 PseudoBlockMatrix{Int64}:
julia> pseudo = BlockedArray(reshape([1:9;], 3, 3), [1,2], [2,1])
2×2-blocked 3×3 BlockedMatrix{Int64}:
1 4 │ 7
──────┼───
2 5 │ 8
Expand All @@ -38,8 +38,8 @@ This "takes ownership" of the passed in array so no copy of the array is made.
A block array can be created with uninitialized entries using the `BlockArray{T}(undef, block_sizes...)`
function. The block_sizes are each an `AbstractVector{Int}` which determines the size of the blocks in that dimension. We here create a `[1,2]×[3,2]` block matrix of `Float32`s:
```julia
julia> PseudoBlockArray{Float32}(undef, [1,2], [3,2])
2×2-blocked 3×5 PseudoBlockMatrix{Float32}:
julia> BlockedArray{Float32}(undef, [1,2], [3,2])
2×2-blocked 3×5 BlockedMatrix{Float32}:
1.02295e-43 0.0 1.09301e-43 │ 0.0 1.17709e-43
───────────────────────────────────────┼──────────────────────────
0.0 1.06499e-43 0.0 │ 1.14906e-43 0.0
Expand Down Expand Up @@ -79,9 +79,9 @@ The underlying array is accessed with `Array` just like for `BlockArray`.

## Views of blocks

We can also view and modify views of blocks of `PseudoBlockArray` using the `view` syntax:
We can also view and modify views of blocks of `BlockedArray` using the `view` syntax:
```jldoctest
julia> A = PseudoBlockArray(ones(6), 1:3);
julia> A = BlockedArray(ones(6), 1:3);

julia> view(A, Block(2))
2-element view(::Vector{Float64}, 2:3) with eltype Float64:
Expand Down
30 changes: 30 additions & 0 deletions ext/BlockArraysBandedMatricesExt.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module BlockArraysBandedMatricesExt

using BandedMatrices, BlockArrays
using BlockArrays.ArrayLayouts
import BandedMatrices: isbanded, AbstractBandedLayout, bandeddata, bandwidths
import BlockArrays: blockcolsupport, blockrowsupport, AbstractBlockedUnitRange
import ArrayLayouts: sub_materialize


bandeddata(P::BlockedMatrix) = bandeddata(P.blocks)
bandwidths(P::BlockedMatrix) = bandwidths(P.blocks)

function blockcolsupport(::AbstractBandedLayout, B, j)
m,n = axes(B)
cs = colsupport(B,n[j])
findblock(m,first(cs)):findblock(m,last(cs))
end

function blockrowsupport(::AbstractBandedLayout, B, k)
m,n = axes(B)
rs = rowsupport(B,m[k])
findblock(n,first(rs)):findblock(n,last(rs))
end

# ambiguity
sub_materialize(::AbstractBandedLayout, V, ::Tuple{AbstractBlockedUnitRange,Base.OneTo{Int}}) = BandedMatrix(V)
sub_materialize(::AbstractBandedLayout, V, ::Tuple{Base.OneTo{Int},AbstractBlockedUnitRange}) = BandedMatrix(V)


end
Loading
Loading