From 4c3d8522f3cf112fb2a62fc0ef8735f492327970 Mon Sep 17 00:00:00 2001 From: Matthew Fishman Date: Mon, 13 Jul 2026 09:48:20 -0400 Subject: [PATCH] Add flattenlinear and make it and tryflattenlinear public `flattenlinear(bc)` is the throwing counterpart to `tryflattenlinear`, raising an `ArgumentError` when the broadcast expression is not linear instead of returning `nothing`, following the `parse`/`tryparse` convention. Both are now public. Co-Authored-By: Claude Opus 4.8 (1M context) --- Project.toml | 2 +- src/TensorAlgebra.jl | 2 +- src/linearbroadcasted.jl | 13 +++++++++++++ test/test_exports.jl | 7 ++++--- test/test_linearbroadcasted.jl | 15 +++++++++++++++ 5 files changed, 34 insertions(+), 5 deletions(-) diff --git a/Project.toml b/Project.toml index 04ce6120..ba2eff70 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "TensorAlgebra" uuid = "68bd88dc-f39d-4e12-b2ca-f046b68fcc6a" -version = "0.17.3" +version = "0.17.4" authors = ["ITensor developers and contributors"] [workspace] diff --git a/src/TensorAlgebra.jl b/src/TensorAlgebra.jl index 725b3787..a24d6c8f 100644 --- a/src/TensorAlgebra.jl +++ b/src/TensorAlgebra.jl @@ -9,7 +9,7 @@ export contract, contract!, eig_full, eig_trunc, eig_vals, eigh_full, eigh_trunc if VERSION >= v"1.11.0-DEV.469" eval( Meta.parse( - "public biperm, bipartition, contractopadd!, data, datatype, label_type, matricizeopperm, permutedims, permutedims!, scalar, similar_map, to_range, tr, ungrade, zero!, scale!, permuteddims, PermutedDims" + "public biperm, bipartition, contractopadd!, data, datatype, flattenlinear, label_type, matricizeopperm, permutedims, permutedims!, scalar, similar_map, to_range, tr, tryflattenlinear, ungrade, zero!, scale!, permuteddims, PermutedDims" ) ) end diff --git a/src/linearbroadcasted.jl b/src/linearbroadcasted.jl index aaafdd03..4d113091 100644 --- a/src/linearbroadcasted.jl +++ b/src/linearbroadcasted.jl @@ -399,6 +399,19 @@ function tryflattenlinear(bc::BC.Broadcasted) return linearbroadcasted(bc.f, args...) end +""" + flattenlinear(bc::Broadcasted) -> LinearBroadcasted + +Like [`tryflattenlinear`](@ref), but throw an `ArgumentError` when the expression is not +linear instead of returning `nothing`. The erroring counterpart to `tryflattenlinear`, +following the `parse`/`tryparse` convention. +""" +function flattenlinear(bc) + lb = tryflattenlinear(bc) + isnothing(lb) && throw(ArgumentError("broadcast expression is not linear")) + return lb +end + # BroadcastStyle for LinearBroadcasted subtypes — delegate to the wrapped array type. function BC.BroadcastStyle(::Type{<:ScaledBroadcasted{<:Any, A}}) where {A} return BC.BroadcastStyle(A) diff --git a/test/test_exports.jl b/test/test_exports.jl index b7e516e6..7975506f 100644 --- a/test/test_exports.jl +++ b/test/test_exports.jl @@ -38,9 +38,10 @@ using Test: @test, @testset append!( exports, [ - :biperm, :bipartition, :contractopadd!, :data, :datatype, :label_type, - :matricizeopperm, :permutedims, :permutedims!, :scalar, :similar_map, - :to_range, :tr, :ungrade, :zero!, :scale!, :permuteddims, :PermutedDims, + :biperm, :bipartition, :contractopadd!, :data, :datatype, :flattenlinear, + :label_type, :matricizeopperm, :permutedims, :permutedims!, :scalar, + :similar_map, :to_range, :tr, :tryflattenlinear, :ungrade, :zero!, :scale!, + :permuteddims, :PermutedDims, ] ) end diff --git a/test/test_linearbroadcasted.jl b/test/test_linearbroadcasted.jl index fa444c77..e18050a2 100644 --- a/test/test_linearbroadcasted.jl +++ b/test/test_linearbroadcasted.jl @@ -55,6 +55,21 @@ using Test: @test, @test_throws, @testset @test TA.tryflattenlinear(BC.broadcasted(exp, a)) === nothing @test TA.tryflattenlinear(BC.broadcasted(+, a, BC.broadcasted(exp, b))) === nothing end + @testset "flattenlinear" begin + a = randn(ComplexF64, 2, 2) + b = randn(ComplexF64, 2, 2) + + # Linear expressions convert successfully, matching `tryflattenlinear` + @test TA.flattenlinear(BC.broadcasted(*, 2, a)) ≡ linearbroadcasted(*, 2, a) + bc = BC.broadcasted(+, BC.broadcasted(*, 2, a), BC.broadcasted(*, 3, b)) + @test copy(TA.flattenlinear(bc)) ≈ 2a + 3b + + # Nonlinear expression throws instead of returning nothing + @test_throws ArgumentError TA.flattenlinear(BC.broadcasted(exp, a)) + @test_throws ArgumentError TA.flattenlinear( + BC.broadcasted(+, a, BC.broadcasted(exp, b)) + ) + end @testset "linearbroadcasted algebra" begin a = randn(ComplexF64, 3, 3)