From 5008c1603b78f1f7fec7a823905a4620ec674064 Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Sat, 11 Oct 2025 14:59:12 +0100 Subject: [PATCH 1/6] Add KronExpansionLayout for A*X*B' --- Project.toml | 2 +- src/bases/basiskron.jl | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Project.toml b/Project.toml index 24281ea..f575b0e 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "ContinuumArrays" uuid = "7ae1f121-cc2c-504b-ac30-9b923412ae5c" -version = "0.19.4" +version = "0.19.5" [deps] AbstractFFTs = "621f4979-c628-5d54-868e-fcf4e3e8185c" diff --git a/src/bases/basiskron.jl b/src/bases/basiskron.jl index f403400..08797ac 100644 --- a/src/bases/basiskron.jl +++ b/src/bases/basiskron.jl @@ -1,3 +1,11 @@ struct KronBasisLayout <: AbstractBasisLayout end -QuasiArrays.kronlayout(::AbstractBasisLayout...) = KronBasisLayout() \ No newline at end of file +QuasiArrays.kronlayout(::AbstractBasisLayout...) = KronBasisLayout() + +""" + KronExpansionLayout + +is a MemoryLayout corresponding to a quasi-matrix corresponding to the 2D expansion K[x,y] == A[x]*X*B[y]' +""" +struct KronExpansionLayout{LayA, LayB} <: AbstractLazyLayout end +applylayout(::Type{typeof(*)}, ::LayA, ::CoefficientLayouts, ::AdjointBasisLayout{LayB}) where {LayA <: AbstractBasisLayout, LayB <: AbstractBasisLayout} = KronExpansionLayout{LayA,LayB}() \ No newline at end of file From 26e82478e4a8ac6c0a8f94579e6148ddd6a0e097 Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Sat, 11 Oct 2025 16:55:20 +0100 Subject: [PATCH 2/6] Support for KronExpansion sum and vec for Expansios --- docs/src/index.md | 24 +++++++++++++----------- src/ContinuumArrays.jl | 2 +- src/bases/bases.jl | 11 +++++++++++ src/bases/basiskron.jl | 4 +++- 4 files changed, 28 insertions(+), 13 deletions(-) diff --git a/docs/src/index.md b/docs/src/index.md index ffa9e94..c03ffd9 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -68,38 +68,40 @@ plotgrid ```@docs ContinuumArrays.TransformFactorization ``` - ```@docs ContinuumArrays.AbstractConcatBasis ``` ```@docs -ContinuumArrays.MulPlan +ContinuumArrays.basis ``` ```@docs -ContinuumArrays.PiecewiseBasis +ContinuumArrays.HvcatBasis ``` ```@docs -ContinuumArrays.Map +ContinuumArrays.InvPlan ``` ```@docs -ContinuumArrays.MappedFactorization +ContinuumArrays.KronExpansionLayout ``` ```@docs -ContinuumArrays.basis +ContinuumArrays.Map ``` ```@docs -ContinuumArrays.InvPlan +ContinuumArrays.MappedFactorization ``` ```@docs -ContinuumArrays.VcatBasis +ContinuumArrays.MulPlan ``` ```@docs -ContinuumArrays.WeightedFactorization +ContinuumArrays.PiecewiseBasis ``` ```@docs -ContinuumArrays.HvcatBasis +ContinuumArrays.ProjectionFactorization ``` ```@docs -ContinuumArrays.ProjectionFactorization +ContinuumArrays.VcatBasis ``` +```@docs +ContinuumArrays.WeightedFactorization ``` + diff --git a/src/ContinuumArrays.jl b/src/ContinuumArrays.jl index 35fd836..2f67c24 100644 --- a/src/ContinuumArrays.jl +++ b/src/ContinuumArrays.jl @@ -19,7 +19,7 @@ import QuasiArrays: cardinality, checkindex, QuasiAdjoint, QuasiTranspose, Inclu ApplyQuasiArray, ApplyQuasiMatrix, LazyQuasiArrayApplyStyle, AbstractQuasiArrayApplyStyle, AbstractQuasiLazyLayout, LazyQuasiArray, LazyQuasiVector, LazyQuasiMatrix, LazyLayout, LazyQuasiArrayStyle, _factorize, _cutdim, AbstractQuasiFill, UnionDomain, sum_size, sum_layout, _cumsum, cumsum_layout, applylayout, equals_layout, layout_broadcasted, PolynomialLayout, dot_size, - diff_layout, diff_size, AbstractQuasiVecOrMat + diff_layout, diff_size, AbstractQuasiVecOrMat, vec_layout import InfiniteArrays: Infinity, InfAxes import AbstractFFTs: Plan diff --git a/src/bases/bases.jl b/src/bases/bases.jl index f188fae..c2770fc 100644 --- a/src/bases/bases.jl +++ b/src/bases/bases.jl @@ -793,6 +793,17 @@ function copy(M::Mul{<:AdjointMappedBasisLayouts, <:MappedBasisLayouts}) end +####### +# reshape/vec +####### + +function vec_layout(::ExpansionLayout, f) + P,c = basis(f), coefficients(f) + @assert isone(size(c,2)) + P * vec(c) +end + + include("basisconcat.jl") include("basiskron.jl") diff --git a/src/bases/basiskron.jl b/src/bases/basiskron.jl index 08797ac..d37b866 100644 --- a/src/bases/basiskron.jl +++ b/src/bases/basiskron.jl @@ -8,4 +8,6 @@ QuasiArrays.kronlayout(::AbstractBasisLayout...) = KronBasisLayout() is a MemoryLayout corresponding to a quasi-matrix corresponding to the 2D expansion K[x,y] == A[x]*X*B[y]' """ struct KronExpansionLayout{LayA, LayB} <: AbstractLazyLayout end -applylayout(::Type{typeof(*)}, ::LayA, ::CoefficientLayouts, ::AdjointBasisLayout{LayB}) where {LayA <: AbstractBasisLayout, LayB <: AbstractBasisLayout} = KronExpansionLayout{LayA,LayB}() \ No newline at end of file +applylayout(::Type{typeof(*)}, ::LayA, ::CoefficientLayouts, ::AdjointBasisLayout{LayB}) where {LayA <: AbstractBasisLayout, LayB <: AbstractBasisLayout} = KronExpansionLayout{LayA,LayB}() +sublayout(::KronExpansionLayout, inds) = sublayout(ApplyLayout{typeof(*)}(), inds) +sum_layout(::KronExpansionLayout, F, dims...) = sum_layout(ApplyLayout{typeof(*)}(), F, dims...) \ No newline at end of file From 9405d8beb1cf08b62222b0b96cbf1b5da3840872 Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Mon, 13 Oct 2025 09:37:46 +0100 Subject: [PATCH 3/6] Update Project.toml --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index f575b0e..d24f36b 100644 --- a/Project.toml +++ b/Project.toml @@ -38,7 +38,7 @@ Infinities = "0.1" IntervalSets = "0.7" LazyArrays = "2" Makie = "0.20, 0.21, 0.22, 0.24" -QuasiArrays = "0.12" +QuasiArrays = "0.12.2" RecipesBase = "1.0" StaticArrays = "1.0" julia = "1.10" From 8c066cba818dd1c384c3430493e12b0b8bf43166 Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Mon, 13 Oct 2025 09:55:53 +0100 Subject: [PATCH 4/6] increase coverage --- test/test_basiskron.jl | 10 ++++++++++ test/test_splines.jl | 6 ++++++ 2 files changed, 16 insertions(+) diff --git a/test/test_basiskron.jl b/test/test_basiskron.jl index 5cc3270..2781489 100644 --- a/test/test_basiskron.jl +++ b/test/test_basiskron.jl @@ -7,5 +7,15 @@ using ContinuumArrays, QuasiArrays, StaticArrays, Test xy = axes(K,1) f = xy -> ((x,y) = xy; exp(x*cos(y))) K \ f.(xy) +end +@testset "KronExpansion" begin + L = LinearSpline(range(0,1; length=4)) + C = reshape(Vector(1:16), 4, 4) + F = L * C * L' + @test sum(F) ≈ 8.5 + @test sum(F; dims=1)[1,0.1] ≈ 3.7 + @test sum(F; dims=2)[0.1,1] ≈ 7.3 + + @test F[0.1,:][0.2] ≈ F[:,0.2][0.1] ≈ F[0.1,0.2] end \ No newline at end of file diff --git a/test/test_splines.jl b/test/test_splines.jl index 68466c4..caeed33 100644 --- a/test/test_splines.jl +++ b/test/test_splines.jl @@ -654,4 +654,10 @@ import ContinuumArrays: basis, AdjointBasisLayout, ExpansionLayout, BasisLayout, f = x -> abs(x) ≤ 1 ? 1 : "hi" @test expand(L,f)[0.1] ≈ 1 end + + @testset "vec" begin + L = LinearSpline([-1,0,1]) + F = L * randn(3,1) + @test vec(F)[0.1] == F[0.1,1] + end end From afaa4c45de25f179ca975eba6d4a14d08c232dc4 Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Mon, 13 Oct 2025 09:56:51 +0100 Subject: [PATCH 5/6] Update ci.yml --- .github/workflows/ci.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 98dc924..2d7cd7b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,6 +49,5 @@ jobs: - uses: julia-actions/julia-processcoverage@v1 - uses: codecov/codecov-action@v5 with: - file: lcov.info token: ${{ secrets.CODECOV_TOKEN }} - fail_ci_if_error: false + file: lcov.info From 8ade08afd5b96fb10e59da572e40f2ce0ec66364 Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Mon, 13 Oct 2025 10:10:08 +0100 Subject: [PATCH 6/6] run test --- test/runtests.jl | 1 + test/test_basiskron.jl | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/test/runtests.jl b/test/runtests.jl index 6da07b3..b86344b 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -84,6 +84,7 @@ end include("test_splines.jl") include("test_chebyshev.jl") include("test_basisconcat.jl") +include("test_basiskron.jl") @testset "Grids/values" begin L = LinearSpline(1:5) diff --git a/test/test_basiskron.jl b/test/test_basiskron.jl index 2781489..9dfa5bc 100644 --- a/test/test_basiskron.jl +++ b/test/test_basiskron.jl @@ -6,7 +6,7 @@ using ContinuumArrays, QuasiArrays, StaticArrays, Test xy = axes(K,1) f = xy -> ((x,y) = xy; exp(x*cos(y))) - K \ f.(xy) + @test_broken K \ f.(xy) end @testset "KronExpansion" begin