Skip to content

StructuredMatrixStyle{OffDiagonal} broadcasting - #458

Merged
dlfivefifty merged 2 commits into
masterfrom
offdiagonal-broadcast
Oct 13, 2026
Merged

dlfivefifty merged 2 commits into
masterfrom
offdiagonal-broadcast

Conversation

@dlfivefifty

Copy link
Copy Markdown
Member

OffDiagonal now has BroadcastStyle LinearAlgebra.StructuredMatrixStyle{OffDiagonal}, so zero-preserving broadcasts keep the single-band structure:

julia> sin.(Eye(5)[2:end,:])
4×5 FillArrays.OffDiagonal{Float64, Fill{Float64, 1, Tuple{Base.OneTo{Int64}}}, …}
  • Zero preservation is detected with LinearAlgebra's fzeropreserving, as for Diagonal etc. (fzero(::OffDiagonal) is defined like for RectDiagonal).
  • The result is an OffDiagonal only if every OffDiagonal argument lies on the same band and has the same axes as the result. Otherwise (different bands, a 1×1 OffDiagonal broadcast out, non-scalar non-OffDiagonal arguments, or non-zero-preserving functions such as cos or .+ 1) it falls back to a dense Matrix.
  • copy broadcasts over the bands themselves, so lazy bands stay lazy: sin.(Eye(5)[2:end,:]) ≡ OffDiagonal(Fill(sin(1.0), 4), 1, 4, 5).
  • In-place dest .= f.(A) with dest::OffDiagonal on the same band only writes the band. Other cases fall back to the generic copyto!, which throws when writing a non-zero entry off the band.
  • structured_broadcast_alloc is defined so that similar(bc, T) also gives an OffDiagonal.

Tests cover zero-preserving functions (sin, abs, scaling, .^2, A .+ A, A .* A, round.(Int, A), nested broadcasts), dense fallbacks, mismatched bands, in-place broadcasting and lazy bands. They pass on Julia 1.10 and 1.13. On 1.11 the only failure is Aqua's ambiguities check being an unexpected pass, which also happens on master.

Downstream: with this change BandedMatrix .+ OffDiagonal would become a dense Matrix instead of a BandedMatrix, as BandedMatrices only defines BroadcastStyle rules between BandedStyle and the StructuredMatrixStyles of specific types. Adding :OffDiagonal to that list in src/interfaceimpl.jl (e.g. in JuliaLinearAlgebra/BandedMatrices.jl#511) restores a BandedMatrix result. ArrayLayouts, LazyArrays and BandedMatrices (#511 plus that one-line change) test suites pass with this PR.

🤖 Generated with Claude Code

Zero-preserving broadcasts over OffDiagonals on the same band return an OffDiagonal,
broadcasting over the bands so that lazy bands stay lazy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (3f8b7e9) to head (155cce9).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff            @@
##            master      #458   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           11        11           
  Lines         1316      1346   +30     
=========================================
+ Hits          1316      1346   +30     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

dlfivefifty added a commit to JuliaLinearAlgebra/BandedMatrices.jl that referenced this pull request Oct 13, 2026
Keeps BandedMatrix .+ OffDiagonal banded once OffDiagonal has its own
broadcast style (JuliaArrays/FillArrays.jl#458).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dlfivefifty
dlfivefifty merged commit 6599ecc into master Oct 13, 2026
28 checks passed
dlfivefifty added a commit to JuliaLinearAlgebra/BandedMatrices.jl that referenced this pull request Oct 15, 2026
…alLayout (require ArrayLayouts v1.15) (#511)

* Support FillArrays.OffDiagonal and remove sublayout piracy for DiagonalLayout

Require ArrayLayouts v1.15, which adds OffDiagonalLayout and returns it for
views of a DiagonalLayout matrix by unit ranges. Remove the pirated
sublayout(::DiagonalLayout, ...) methods, which would otherwise overwrite
ArrayLayouts' method, and add bandwidths, inbands_getindex/inbands_setindex!
and BandedMatrix conversion for OffDiagonalLayout.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Update downstream.yml

* Update interfaceimpl.jl

* Update BandedMatrix.jl

* Update BandedMatrix.jl

* Update BandedMatrix.jl

* BandedStyle wins over StructuredMatrixStyle{OffDiagonal}

Keeps BandedMatrix .+ OffDiagonal banded once OffDiagonal has its own
broadcast style (JuliaArrays/FillArrays.jl#458).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant