-
Notifications
You must be signed in to change notification settings - Fork 31
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
Operations under which block-matrices return block-matrices #31
Comments
Yeah, operations that are not specialized will fall back to the |
Hmm yeah. It's not even clear to me what should define broadcast-able arrays in this context. Do we view a block-arrays as a special representation of a regular arrays, meaning that you could broadcast a B = BlockArray(Matrix{Float64}, [2, 2], [2, 2]) or is it more appropriate to say that it would be valid to broadcast A = BlockArray(Matrix{Float64}, [2, 2], [2]) since in some sense it's a I guess there are similar questions to be asked about the reduction interface: for example, does a reduction over a block matrix whose blocks are all of size I think certain unary linear algebra operations are quite simple to do e.g. the transpose of a block matrix is always a block matrix, so it seems pretty clear-cut what should happen there. Similarly with matrix multiplication; the result will be a block matrix if each of the blocks that you have to multiply are conformal, but otherwise the result should probably be dense (if you start with dense matrices, I'm not sure about sparse). |
WIth broadcast I meant stuff like Linear Algebra would be nice to have. |
Oh okay, so you're just interested in the unary case for now? I was referring the more general case, so things like If you have no objections, I'll put together a PR for transposition to start with. |
Sounds good! |
I'd add matrix algebra to this: for example: julia> A = BlockArray(rand(4,4), [2,2], [2,2])
2×2-blocked 4×4 BlockArrays.BlockArray{Float64,2,Array{Float64,2}}:
0.302873 0.193358 │ 0.411812 0.830986
0.658837 0.932453 │ 0.0245708 0.415494
──────────────────────┼─────────────────────
0.973492 0.00193905 │ 0.731272 0.953296
0.292634 0.343203 │ 0.105658 0.417385
julia> B = BlockArray(rand(3,4), [1,1,1], [2,2])
3×2-blocked 3×4 BlockArrays.BlockArray{Float64,2,Array{Float64,2}}:
0.506225 0.752294 │ 0.534993 0.347013
────────────────────┼────────────────────
0.398445 0.591069 │ 0.699823 0.783644
────────────────────┼────────────────────
0.189798 0.712026 │ 0.485311 0.626346
julia> B*A # expected BlockArray(..., [1,1,1], [2,2])
3×4 Array{Float64,2}:
1.27132 0.919495 0.654844 1.38808
1.42069 0.898492 0.773167 1.57091
1.18233 0.916535 0.516729 1.17764 I'm not sure what to do if the block sizes are not compatible. Maybe make them compatible by taking the "union" of the block sizes? That is, add blocks to get the "least common divisor"-analogue of the block sizes? |
Here's another one: |
What is the status of this work? Especially I am interested in efficient BlockMatrix*BlockMatrix multiplication. |
BlockBandedMatrices.jl has a nice template for how to implement this. It would be good to have it here. |
Do you require 5-argument variants? (E.g., analogues to The alternative is to overload |
I need to have 5-arguments. Judging from your previous comment I thought that you want LazyArrays.jl to be used. I started reading this package but it is still not really clear for me, so if it is ok with you I will prefer using |
The reason we would want LazyArrays.jl is that it is much more flexible. For example, the high performance implementation of A = BlockMatrix(...)
B = BlockMatrix(...)
V = view(A, Block.(1:3), Block.(3:4)) # take a subrange of blocks, then transpose them
C .= α.*Mul(V, B) .+ β.*C # alternative to mul!(C, V, B, α, β), automatically calls fast block multiply (BLAS) routines
C .= Mul(V',B) # alternative to mul!(C, V', B), automatically calls fast block multiply (BLAS) routines Accomplishing this with standard LazyArrays.jl is a bit complicated if you are not familiar with If you only need |
I also need some related operations like I think another benefit of going toward LazyArrays.jl way is that we can "amortize" block size analysis if the same multiply-add is computed repeatedly, that is: ma = MulAdd(α, A, B, β, C) # block sizes are analyzed here
for _ in a_lot
my_compute_input!(ma.B)
materialize!(ma)
end
That would be great!
It would be a good bait for getting alpha testers :) |
I don't quite see what you want to analyse. The expensive part of block size creation is done when the matrix
Maybe I'll prepare a PR and we can have a conversation whether it's premature or not. The only serious outstanding issue that I can think of is whether |
I was referring to "least common divisor"-analogue you mentioned in #31 (comment)
That would depend on the ratio of number of blocks and average block size, right? Especially when it's block diagonal (which is actually what I have in mind). I know we shouldn't be worrying about performance before any benchmarks, but I just thought it is worth mentioning that there is an optimization opportunity.
It seems If you want to expose an API, how about a macro (say) |
It still means to change it you have to put upper bounds in METADATA on dependent packages, but it's not that big of a deal.
There already is the shorthand |
FYI it looks like @jagot just wrote a "block join" multiplication code: JuliaLinearAlgebra/BlockBandedMatrices.jl#21 |
But isn't it impossible to evaluate such an expression without calling |
I just added support for broadcasting. Let's get that merged before moving on to |
I was wondering whether there is interest in someone (me?) implementing operations under which block-matrices are potentially closed (i.e. perhaps return another block-matrix), such as multiplication, inversion, transposition and certain factorisations, at the level of the
AbstractBlockMatrix
and / orAbstractBlockVector
. For example, it would be really nice if in the followingboth
A
andB.'
were also a block matrices. At the moment these operations appear to return regular dense matrices.This would be very useful for block matrices who's blocks have special structures where the same structure pops out the other side of such operations (I'm really interested in being able to operate on block-matrices whose blocks are circulant and have sensible things happen).
The text was updated successfully, but these errors were encountered: