Skip to content

Commit 811f506

Browse files
committed
Support expanding columns of 2D functions
1 parent 0bbdf26 commit 811f506

File tree

5 files changed

+72
-19
lines changed

5 files changed

+72
-19
lines changed

Project.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,19 @@ MultivariateOrthogonalPolynomialsStatsBaseExt = "StatsBase"
3232
[compat]
3333
ArrayLayouts = "1.11"
3434
BandedMatrices = "1"
35-
BlockArrays = "1.0"
35+
BlockArrays = "1.7.3"
3636
BlockBandedMatrices = "0.13"
3737
ClassicalOrthogonalPolynomials = "0.15.8"
3838
ContinuumArrays = "0.20"
3939
DomainSets = "0.7"
4040
FastTransforms = "0.17"
4141
FillArrays = "1.0"
42-
HarmonicOrthogonalPolynomials = "0.7"
42+
HarmonicOrthogonalPolynomials = "0.7.1"
4343
InfiniteArrays = "0.15"
4444
InfiniteLinearAlgebra = "0.9, 0.10"
4545
LazyArrays = "2.3.1"
4646
LazyBandedMatrices = "0.11.3"
47-
QuasiArrays = "0.13"
47+
QuasiArrays = "0.13.1"
4848
Random = "1"
4949
RecurrenceRelationships = "0.2"
5050
SpecialFunctions = "1, 2"

examples/christoffelsampling.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
using ClassicalOrthogonalPolynomials, MultivariateOrthogonalPolynomials, StatsBase, Plots
2+
3+
x,y = coordinates(ChebyshevInterval() ^ 2)
4+
qr([one(x) x y])

src/MultivariateOrthogonalPolynomials.jl

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module MultivariateOrthogonalPolynomials
22
using StaticArrays: iszero
3-
using QuasiArrays: AbstractVector
3+
using QuasiArrays: AbstractVector, _getindex
44
using ClassicalOrthogonalPolynomials, FastTransforms, BlockBandedMatrices, BlockArrays, DomainSets,
55
QuasiArrays, StaticArrays, ContinuumArrays, InfiniteArrays, InfiniteLinearAlgebra,
66
LazyArrays, SpecialFunctions, LinearAlgebra, BandedMatrices, LazyBandedMatrices, ArrayLayouts,
@@ -18,10 +18,10 @@ import BlockArrays: block, blockindex, BlockSlice, viewblock, blockcolsupport, A
1818
import BlockBandedMatrices: _BandedBlockBandedMatrix, AbstractBandedBlockBandedMatrix, _BandedMatrix, blockbandwidths, subblockbandwidths
1919
import LinearAlgebra: factorize
2020
import LazyArrays: arguments, paddeddata, LazyArrayStyle, LazyLayout, PaddedLayout, applylayout, LazyMatrix, ApplyMatrix
21-
import LazyBandedMatrices: LazyBandedBlockBandedLayout, AbstractBandedBlockBandedLayout, AbstractLazyBandedBlockBandedLayout, _krontrav_axes, DiagTravLayout, invdiagtrav, ApplyBandedBlockBandedLayout, krontrav
21+
import LazyBandedMatrices: LazyBandedBlockBandedLayout, AbstractBandedBlockBandedLayout, AbstractLazyBandedBlockBandedLayout, _krontrav_axes, DiagTravLayout, diagtrav, invdiagtrav, ApplyBandedBlockBandedLayout, krontrav
2222
import InfiniteArrays: InfiniteCardinal, OneToInf
2323

24-
import ClassicalOrthogonalPolynomials: jacobimatrix, Weighted, orthogonalityweight, HalfWeighted, WeightedBasis, pad, recurrencecoefficients, clenshaw, weightedgrammatrix, Clenshaw, OPLayout
24+
import ClassicalOrthogonalPolynomials: jacobimatrix, Weighted, orthogonalityweight, HalfWeighted, WeightedBasis, pad, recurrencecoefficients, clenshaw, weightedgrammatrix, Clenshaw, OPLayout, normalized
2525
import HarmonicOrthogonalPolynomials: BivariateOrthogonalPolynomial, MultivariateOrthogonalPolynomial, Plan,
2626
AngularMomentum, angularmomentum, BlockOneTo, BlockRange1, interlace,
2727
MultivariateOPLayout, AbstractMultivariateOPLayout, MAX_PLOT_BLOCKS
@@ -38,7 +38,8 @@ export MultivariateOrthogonalPolynomial, BivariateOrthogonalPolynomial,
3838

3939
laplacian_axis(::Inclusion{<:SVector{2}}, A; dims...) = diff(A, (2,0); dims...) + diff(A, (0, 2); dims...)
4040
abslaplacian_axis(::Inclusion{<:SVector{2}}, A; dims...) = -(diff(A, (2,0); dims...) + diff(A, (0, 2); dims...))
41-
coordinates(P) = (first.(axes(P,1)), last.(axes(P,1)))
41+
coordinates(P::AbstractQuasiArray) = (first.(axes(P,1)), last.(axes(P,1)))
42+
coordinates(P::Domain) = coordinates(Inclusion(P))
4243

4344
function diff_layout(::AbstractBasisLayout, a, (k,j)::NTuple{2,Int}; dims...)
4445
(k < 0 || j < 0) && throw(ArgumentError("order must be non-negative"))

src/rect.jl

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ const RectPolynomial{T, PP} = KronPolynomial{2, T, PP}
2929
axes(P::KronPolynomial) = (Inclusion(×(map(domain, axes.(P.args, 1))...)), _krontrav_axes(axes.(P.args, 2)...))
3030

3131

32+
normalized(P::KronPolynomial) = KronPolynomial(map(normalized, P.args))
33+
3234
function getindex(P::RectPolynomial{T}, xy::StaticVector{2}, Jj::BlockIndex{1})::T where T
3335
a,b = P.args
3436
J,j = Int(block(Jj)),blockindex(Jj)
@@ -109,12 +111,20 @@ function checkpoints(P::RectPolynomial)
109111
SVector.(x, y')
110112
end
111113

112-
function plan_transform(P::KronPolynomial{d,<:Any,<:Fill}, B::Tuple{Block{1}}, dims=1:1) where d
113-
@assert dims == 1
114+
function plan_transform(P::KronPolynomial{d,<:Any,<:Fill}, (B,)::Tuple{Block{1}}, dims=1:1) where d
115+
@assert only(dims) == 1
116+
117+
T = first(P.args)
118+
@assert d == 2
119+
ApplyPlan(diagtrav, plan_transform(T, tuple(Fill(Int(B),d)...)))
120+
end
121+
122+
function plan_transform(P::KronPolynomial{d,<:Any,<:Fill}, (B,n)::Tuple{Block{1},Int}, dims=1:1) where d
123+
@assert only(dims) == 1
114124

115125
T = first(P.args)
116126
@assert d == 2
117-
ApplyPlan(DiagTrav, plan_transform(T, tuple(Fill(Int(B[1]),d)...)))
127+
ApplyPlan(A -> diagtrav(A; dims=1:d), plan_transform(T, tuple(Fill(Int(B),d)...,n), 1:d))
118128
end
119129

120130
function grid(P::RectPolynomial, B::Block{1})
@@ -133,7 +143,7 @@ function plan_transform(P::KronPolynomial{d}, B::Tuple{Block{1}}, dims=1:1) wher
133143
@assert d == 2
134144
N = Int(B[1])
135145
Fx,Fy = plan_transform(P.args[1], (N,N), 1),plan_transform(P.args[2], (N,N), 2)
136-
ApplyPlan(DiagTrav, TensorPlan(Fx,Fy))
146+
ApplyPlan(diagtrav, TensorPlan(Fx,Fy))
137147
end
138148

139149
applylayout(::Type{typeof(*)}, ::Lay, ::DiagTravLayout) where Lay <: AbstractBasisLayout = ExpansionLayout{Lay}()

test/test_rect.jl

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using MultivariateOrthogonalPolynomials, ClassicalOrthogonalPolynomials, StaticArrays, LinearAlgebra, BlockArrays, FillArrays, Base64, LazyBandedMatrices, ArrayLayouts, Random, StatsBase, Test
22
using ClassicalOrthogonalPolynomials: expand, coefficients, recurrencecoefficients
33
using MultivariateOrthogonalPolynomials: weaklaplacian, ClenshawKron
4-
using ContinuumArrays: plotgridvalues, ExpansionLayout
4+
using ContinuumArrays: plotgridvalues, ExpansionLayout, basis, grid
55
using Base: oneto
66

77
Random.seed!(3242)
@@ -32,17 +32,39 @@ Random.seed!(3242)
3232
@test T²ₙ \ one.(x) == [1; zeros(14)]
3333
@test (T² \ x)[1:5] [0;1;zeros(3)]
3434

35-
f = expand(T², splat((x,y) -> exp(x*cos(y-0.1))))
36-
@test f[SVector(0.1,0.2)] exp(0.1*cos(0.1))
35+
f = splat((x,y) -> exp(x*cos(y-0.1)))
36+
𝐟 = expand(T², f)
37+
@test 𝐟[SVector(0.1,0.2)] f(SVector(0.1,0.2))
3738

3839
= RectPolynomial(Fill(U, 2))
39-
40-
@test f[SVector(0.1,0.2)] exp(0.1cos(0.1))
40+
𝐟 = expand(U², f)
41+
@test 𝐟[SVector(0.1,0.2)] f(SVector(0.1,0.2))
4142

4243
TU = RectPolynomial(T,U)
43-
x,F = ClassicalOrthogonalPolynomials.plan_grid_transform(TU, Block(5))
44-
f = expand(TU, splat((x,y) -> exp(x*cos(y-0.1))))
45-
@test f[SVector(0.1,0.2)] exp(0.1*cos(0.1))
44+
𝐟 = expand(TU, f)
45+
@test 𝐟[SVector(0.1,0.2)] f(SVector(0.1,0.2))
46+
47+
@testset "matrix" begin
48+
N = 10
49+
𝐱 = grid(T², Block(N))
50+
51+
@test T²[𝐱,1] == ones(N,N)
52+
@test T²[𝐱,2] == first.(𝐱)
53+
@test T²[𝐱,1:3] == T²[𝐱,Block.(Base.OneTo(2))] == T²[𝐱,[Block(1),Block(2)]] == [ones(N,N) ;;; first.(𝐱) ;;; last.(𝐱)]
54+
@test T²[𝐱,Block(1)] == [ones(N,N) ;;;]
55+
@test T²[𝐱,[1 2; 3 4]] [T²[𝐱,[1,3]] ;;;; T²[𝐱,[2,4]]]
56+
57+
58+
F = plan_transform(T², Block(N))
59+
@test F * f.(𝐱) transform(T², f)[Block.(1:N)] atol=1E-6
60+
61+
x,y = coordinates(ChebyshevInterval()^2)
62+
A = [one(x) x y]
63+
F = plan_transform(T², (Block(N), 3), 1)
64+
@test F * A[𝐱,:] [I(3); zeros(52,3)]
65+
66+
@test\ A [I(3); Zeros(∞,3)]
67+
end
4668
end
4769

4870
@testset "Jacobi matrices" begin
@@ -254,4 +276,20 @@ Random.seed!(3242)
254276
@test sample(f) isa SVector
255277
@test sum(sample(f, 100_000))/100_000 [sum(x .* f)/sum(f),sum(y .* f)/sum(f)] rtol=1E-1
256278
end
279+
280+
@testset "qr" begin
281+
x,y = coordinates(ChebyshevInterval()^2)
282+
A = [one(x) x y]
283+
284+
@test A[SVector(0.1,0.2),1] 1
285+
@test A[SVector(0.1,0.2),1:3] A[SVector(0.1,0.2),:] [1,0.1,0.2]
286+
287+
P = basis(x)
288+
P\A
289+
290+
291+
B[0.1,:]
292+
293+
P \ A
294+
end
257295
end

0 commit comments

Comments
 (0)