Skip to content

Commit

Permalink
Add lazy BlockVec (#93)
Browse files Browse the repository at this point in the history
* Add lazy BlockVec

* BlockVec MemoryLayout

* increase cov

* Just use ApplyArray

* simplify muladd!

* Update LazyBandedMatrices.jl
  • Loading branch information
dlfivefifty authored Mar 28, 2023
1 parent b344a4b commit 9347183
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 12 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "LazyBandedMatrices"
uuid = "d7e5e226-e90b-4449-9968-0f923699bf6f"
authors = ["Sheehan Olver <solver@mac.com>"]
version = "0.8.6"
version = "0.8.7"

[deps]
ArrayLayouts = "4c555306-a7a7-4459-81d9-ec55ddd5c99a"
Expand Down
17 changes: 9 additions & 8 deletions src/LazyBandedMatrices.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import LinearAlgebra
import MatrixFactorizations: ql, ql!, QLPackedQ, QRPackedQ, reflector!, reflectorApply!,
QLPackedQLayout, QRPackedQLayout, AdjQLPackedQLayout, AdjQRPackedQLayout

import Base: BroadcastStyle, similar, OneTo, oneto, copy, *, axes, size, getindex, tail, convert, resize!, tuple_type_tail
import Base: BroadcastStyle, similar, OneTo, oneto, copy, *, axes, size, getindex, tail, convert, resize!, tuple_type_tail, view
import Base.Broadcast: Broadcasted, broadcasted, instantiate
import LinearAlgebra: kron, hcat, vcat, AdjOrTrans, AbstractTriangular, BlasFloat, BlasComplex, BlasReal,
lmul!, rmul!, checksquare, StructuredMatrixStyle, adjoint, transpose,
Expand Down Expand Up @@ -42,7 +42,7 @@ import BlockBandedMatrices: BlockSlice, Block1, AbstractBlockBandedLayout,
AbstractBandedBlockBandedLayout, BandedBlockBandedLayout, BandedBlockBandedStyle, BlockBandedStyle,
blockcolsupport, BlockRange1, blockrowsupport, BlockIndexRange1,
BlockBandedColumnMajor
import BlockArrays: BlockSlice1, BlockLayout, AbstractBlockStyle, block, blockindex, BlockKron, viewblock, blocks, BlockSlices, AbstractBlockLayout
import BlockArrays: BlockSlice1, BlockLayout, AbstractBlockStyle, block, blockindex, BlockKron, viewblock, blocks, BlockSlices, AbstractBlockLayout, blockvec

# for bidiag/tridiag
import Base: -, +, *, /, \, ==, AbstractMatrix, Matrix, Array, size, conj, real, imag, copy,
Expand Down Expand Up @@ -343,15 +343,16 @@ function materialize!(M::MatMulVecAdd{<:AllBlockBandedLayout,<:PaddedLayout,<:Pa
α,A,x,β,y = M.α,M.A,M.B,M.β,M.C
length(y) == size(A,1) || throw(DimensionMismatch())
length(x) == size(A,2) || throw(DimensionMismatch())
= paddeddata(y)

if !blockisequal(axes(A,2), axes(x,1))
return muladd!(α, A, PseudoBlockVector(x, (axes(A,2),)), β, y)
x2 = PseudoBlockVector(x, (axes(A,2),))
x̃2 = paddeddata(x)
muladd!(α, view(A, axes(ỹ,1), axes(x̃2,1)), x̃2, β, ỹ)
else
= paddeddata(x)
muladd!(α, view(A, axes(ỹ,1), axes(x̃,1)), x̃, β, ỹ)
end

= paddeddata(y)
= paddeddata(x)

muladd!(α, view(A, axes(ỹ,1), axes(x̃,1)) , x̃, β, ỹ)
y
end

Expand Down
22 changes: 22 additions & 0 deletions src/blockconcat.jl
Original file line number Diff line number Diff line change
Expand Up @@ -522,3 +522,25 @@ end
MemoryLayout(::Type{BlockBroadcastArray{T,N,FF,Args}}) where {T,N,FF,Args} = blockbroadcastlayout(FF, tuple_type_memorylayouts(Args)...)

resize!(c::BlockBroadcastVector{T,typeof(vcat)}, N::Block{1}) where T = BlockBroadcastVector{T}(vcat, resize!.(c.args, N)...)

####
# BlockVec
####

const BlockVec{T, M<:AbstractMatrix{T}} = ApplyVector{T, typeof(blockvec), <:Tuple{M}}

BlockVec{T}(M::AbstractMatrix{T}) where T = ApplyVector{T}(blockvec, M)
BlockVec(M::AbstractMatrix{T}) where T = BlockVec{T}(M)
axes(b::BlockVec) = (blockedrange(Fill(size(b.args[1])...)),)

view(b::BlockVec, K::Block{1}) = view(b.args[1], :, Int(K))
Base.@propagate_inbounds getindex(b::BlockVec, k::Int) = b.args[1][k]
Base.@propagate_inbounds setindex!(b::BlockVec, v, k::Int) = setindex!(b.args[1], v, k)

_resize!(A::AbstractMatrix, m, n) = A[1:m, 1:n]
_resize!(At::Transpose, m, n) = transpose(transpose(At)[1:n, 1:m])
_resize!(Ac::Adjoint, m, n) = (Ac')[1:n, 1:m]'
resize!(b::BlockVec, K::Block{1}) = BlockVec(_resize!(b.args[1], size(b.args[1],1), Int(K)))

applylayout(::Type{typeof(blockvec)}, ::PaddedLayout) = PaddedLayout{ApplyLayout{typeof(blockvec)}}()
paddeddata(b::BlockVec) = BlockVec(paddeddata(b.args[1]))
35 changes: 32 additions & 3 deletions test/test_blockconcat.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
using LazyBandedMatrices, BlockBandedMatrices, BlockArrays, StaticArrays, FillArrays, LazyArrays, ArrayLayouts, BandedMatrices, Test
import LazyBandedMatrices: BlockBroadcastArray, ApplyLayout, blockcolsupport, blockrowsupport, arguments, paddeddata, resizedata!
import LazyBandedMatrices: BlockBroadcastArray, ApplyLayout, blockcolsupport, blockrowsupport, arguments, paddeddata, resizedata!, BlockVec, BlockVecLayout
import BlockArrays: blockvec
import LinearAlgebra: Adjoint, Transpose
import LazyArrays: PaddedArray
import LazyArrays: PaddedArray, PaddedLayout

@testset "unitblocks" begin
a = unitblocks(Base.OneTo(5))
Expand Down Expand Up @@ -142,7 +143,6 @@ end
end
end


@testset "BlockHcat" begin
@testset "vec hcat" begin
a = BlockHcat(1:5, 10:14)
Expand Down Expand Up @@ -406,3 +406,32 @@ end
@test subblockbandwidths(C) == (0,0)
end
end

@testset "BlockVec" begin
X = randn(5,4)
b = BlockVec(X)
@test MemoryLayout(b) isa ApplyLayout{typeof(blockvec)}
@test b == vec(X)
@test view(b, Block(3)) view(X, :, 3)
@test b[Block(3)] isa Vector
b[5] = 6
@test X[5] == 6
@test resize!(b, Block(2)) == b[Block.(1:2)]

c = BlockVec(X')
@test c == vec(X')
@test view(c, Block(3)) view(X', :, 3)
@test resize!(c, Block(2)) == c[Block.(1:2)]

c = BlockVec(transpose(X))
@test c == vec(transpose(X))
@test view(c, Block(3)) view(transpose(X), :, 3)
@test resize!(c, Block(2)) == c[Block.(1:2)]

X = cache(Zeros(5,6));
X[1,1] = 2
c = BlockVec(X);
@test MemoryLayout(c) isa PaddedLayout
@test paddeddata(c) isa BlockVec
@test paddeddata(c) == [2]
end

2 comments on commit 9347183

@dlfivefifty
Copy link
Member Author

Choose a reason for hiding this comment

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

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

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

Registration pull request created: JuliaRegistries/General/80508

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.8.7 -m "<description of version>" 9347183553d1d25905334f001767833b9f821f0a
git push origin v0.8.7

Please sign in to comment.