Skip to content

Commit 7cbbe4b

Browse files
authored
Concrete derivatives may preserve OneElement coefficients (#333)
* Concrete derivatives mat preserve OneElement coefficients * Test for OneElement coeffs conditionally * Concrete derivatie for NormalizedJacobi and test fixes * Revert concrete derivative for NormalizedJacobi * Test for OneElement if it's defined
1 parent e9b80aa commit 7cbbe4b

File tree

5 files changed

+144
-9
lines changed

5 files changed

+144
-9
lines changed

src/Spaces/PolynomialSpace.jl

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -545,10 +545,13 @@ function getindex(C::ConcreteConversion{S,NormalizedPolynomialSpace{S,D,R},T},k:
545545
end
546546
end
547547

548+
const MaybeNormalized{S<:PolynomialSpace} = Union{S, NormalizedPolynomialSpace{S}}
549+
const MaybeNormalizedTensorSpace{P1,P2} = TensorSpace{<:Tuple{MaybeNormalized{P1},MaybeNormalized{P2}}}
550+
548551
# this is only evaluated if FillArrays >= v1 is used
549552
@static if isdefined(FillArrays, :OneElement)
550553
## Special OneElement conversion
551-
function _mul_coefficients_concreteconv(C, v)
554+
function _mul_coefficients_concreteconv(C, v::OneElement)
552555
Base.require_one_based_indexing(v)
553556
nzind = v.ind[1]
554557
Cnzind = C[nzind, nzind]
@@ -562,6 +565,17 @@ end
562565
v::OneElement{<:Any,1}) where {S<:PolynomialSpace}
563566
_mul_coefficients_concreteconv(C, v)
564567
end
568+
function _mul_coefficients_deriv(D::ConcreteDerivative, v::OneElement)
569+
Base.require_one_based_indexing(v)
570+
nzind = v.ind[1]
571+
order = D.order
572+
rowind = nzind-D.order
573+
Dnzind = D[rowind, nzind]
574+
OneElement(Dnzind * v.val, rowind, rowind)
575+
end
576+
function mul_coefficients(C::ConcreteDerivative{<:MaybeNormalized}, v::OneElement{<:Any,1})
577+
_mul_coefficients_deriv(C, v)
578+
end
565579
end
566580

567581
# Evaluation
@@ -600,8 +614,6 @@ function _hasconversion_tensor(A, B)
600614

601615
_stripnorm(A1) == _stripnorm(B1) && _stripnorm(A2) == _stripnorm(B2)
602616
end
603-
const MaybeNormalized{S<:PolynomialSpace} = Union{S, NormalizedPolynomialSpace{S}}
604-
const MaybeNormalizedTensorSpace{P1,P2} = TensorSpace{<:Tuple{MaybeNormalized{P1},MaybeNormalized{P2}}}
605617

606618
function hasconversion(A::MaybeNormalizedTensorSpace{<:P1, <:P2},
607619
B::MaybeNormalizedTensorSpace{<:P1, <:P2}) where {P1<:PolynomialSpace,P2<:PolynomialSpace}

test/ChebyshevTest.jl

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module ChebyshevTest
33
using ApproxFunOrthogonalPolynomials
44
using ApproxFunBase
55
using DualNumbers
6+
using FillArrays
67
using LinearAlgebra
78
using Test
89
using ApproxFunBase: transform!, itransform!
@@ -351,6 +352,40 @@ include("testutils.jl")
351352
g = Chebyshev()(3)
352353
f = Conversion(Chebyshev(), NormalizedChebyshev()) * g
353354
@test f Fun(x->-3x+4x^3, NormalizedChebyshev())
355+
@test space(f) == NormalizedChebyshev()
356+
@static if isdefined(FillArrays, :OneElement)
357+
if coefficients(g) isa OneElement
358+
@test coefficients(f) isa OneElement
359+
end
360+
end
361+
362+
g = NormalizedChebyshev()(3)
363+
f = Conversion(NormalizedChebyshev(), Chebyshev()) * g
364+
@test f g
365+
@test space(f) == Chebyshev()
366+
@static if isdefined(FillArrays, :OneElement)
367+
if coefficients(g) isa OneElement
368+
@test coefficients(f) isa OneElement
369+
end
370+
end
371+
end
372+
373+
@testset "Derivative * OneElement" begin
374+
g = Chebyshev()(3)
375+
@test Derivative() * g == Derivative() * Fun(space(g), collect(coefficients(g)))
376+
@static if isdefined(FillArrays, :OneElement)
377+
if coefficients(g) isa OneElement
378+
@test coefficients(Derivative() * g) isa OneElement
379+
end
380+
end
381+
382+
g = NormalizedChebyshev()(3)
383+
@test Derivative() * g == Derivative() * Fun(space(g), collect(coefficients(g)))
384+
@static if isdefined(FillArrays, :OneElement)
385+
if coefficients(g) isa OneElement
386+
@test coefficients(Derivative() * g) isa OneElement
387+
end
388+
end
354389
end
355390
end
356391

test/JacobiTest.jl

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@ module JacobiTest
22

33
using ApproxFunOrthogonalPolynomials
44
using ApproxFunBase
5-
using Test
6-
using SpecialFunctions
7-
using LinearAlgebra
85
using ApproxFunBase: maxspace, NoSpace, hasconversion,
96
reverseorientation, ReverseOrientation, transform!, itransform!
107
using ApproxFunBaseTest: testbandedbelowoperator, testbandedoperator, testspace, testtransforms,
@@ -14,10 +11,14 @@ using BandedMatrices
1411
using BandedMatrices: isbanded
1512
using BlockArrays
1613
using BlockBandedMatrices
17-
using StaticArrays: SVector
18-
using Static
14+
using FillArrays
1915
using HalfIntegers
16+
using LinearAlgebra
2017
using OddEvenIntegers
18+
using SpecialFunctions
19+
using StaticArrays: SVector
20+
using Static
21+
using Test
2122

2223
include("testutils.jl")
2324

@@ -757,6 +758,52 @@ include("testutils.jl")
757758
S = @inferred maxspace(NormalizedChebyshev(), NormalizedJacobi(Ultraspherical(2)))
758759
@test S == NormalizedJacobi(Ultraspherical(2))
759760
end
761+
762+
@testset "Conversion * OneElement" begin
763+
g = Legendre()(3)
764+
f = Conversion(Legendre(), NormalizedLegendre()) * g
765+
@test f g
766+
@test space(f) == NormalizedLegendre()
767+
768+
g = NormalizedLegendre()(3)
769+
f = Conversion(NormalizedLegendre(), Legendre()) * g
770+
@test f g
771+
@test space(f) == Legendre()
772+
end
773+
774+
@testset "Derivative * OneElement" begin
775+
g = Legendre()(3)
776+
@test Derivative() * g == Derivative() * Fun(space(g), collect(coefficients(g)))
777+
@static if isdefined(FillArrays, :OneElement)
778+
if coefficients(g) isa OneElement
779+
@test coefficients(Derivative() * g) isa OneElement
780+
end
781+
end
782+
783+
g = Jacobi(1.5,2)(3)
784+
@test Derivative() * g == Derivative() * Fun(space(g), collect(coefficients(g)))
785+
@static if isdefined(FillArrays, :OneElement)
786+
if coefficients(g) isa OneElement
787+
@test coefficients(Derivative() * g) isa OneElement
788+
end
789+
end
790+
791+
g = NormalizedLegendre()(3)
792+
@test Derivative() * g == Derivative() * Fun(space(g), collect(coefficients(g)))
793+
@static if isdefined(FillArrays, :OneElement)
794+
if coefficients(g) isa OneElement
795+
@test_broken coefficients(Derivative() * g) isa OneElement
796+
end
797+
end
798+
799+
g = NormalizedJacobi(1,2.5)(3)
800+
@test Derivative() * g == Derivative() * Fun(space(g), collect(coefficients(g)))
801+
@static if isdefined(FillArrays, :OneElement)
802+
if coefficients(g) isa OneElement
803+
@test_broken coefficients(Derivative() * g) isa OneElement
804+
end
805+
end
806+
end
760807
end
761808

762809
@testset "casting bug ApproxFun.jl#770" begin

test/MiscAFBTest.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ Base.:(==)(a::UniqueInterval, b::UniqueInterval) = (@assert a.parentinterval ==
257257
for ST in Any[Chebyshev, Legendre,
258258
(x...) -> Jacobi(2,2,x...), (x...) -> Jacobi(1.5,2.5,x...)]
259259
S1 = ST(d...)
260-
for S in [S1, NormalizedPolynomialSpace(S1)]
260+
@testset for S in [S1, NormalizedPolynomialSpace(S1)]
261261
@test Derivative(S) == Derivative(S,1)
262262
@test Derivative(S)^2 == Derivative(S,2)
263263
f = Fun(x->x^3, S)

test/UltrasphericalTest.jl

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ using ApproxFunOrthogonalPolynomials
44
using ApproxFunBase
55
using BandedMatrices
66
using BandedMatrices: isbanded
7+
using FillArrays
78
using HalfIntegers
89
using LinearAlgebra
910
using OddEvenIntegers
@@ -298,6 +299,46 @@ include("testutils.jl")
298299
E = Evaluation(S, 0.5, 2)
299300
@test Number(E * f) 6 * (0.5)
300301
end
302+
303+
@testset "Conversion * OneElement" begin
304+
g = Ultraspherical(3)(3)
305+
f = Conversion(Ultraspherical(3), NormalizedUltraspherical(3)) * g
306+
@test f g
307+
@test space(f) == NormalizedUltraspherical(3)
308+
@static if isdefined(FillArrays, :OneElement)
309+
if coefficients(g) isa OneElement
310+
@test coefficients(f) isa OneElement
311+
end
312+
end
313+
314+
g = NormalizedUltraspherical(3)(3)
315+
f = Conversion(NormalizedUltraspherical(3), Ultraspherical(3)) * g
316+
@test f g
317+
@test space(f) == Ultraspherical(3)
318+
@static if isdefined(FillArrays, :OneElement)
319+
if coefficients(g) isa OneElement
320+
@test coefficients(f) isa OneElement
321+
end
322+
end
323+
end
324+
325+
@testset "Derivative * OneElement" begin
326+
g = Ultraspherical(3)(3)
327+
@test Derivative() * g == Derivative() * Fun(space(g), collect(coefficients(g)))
328+
@static if isdefined(FillArrays, :OneElement)
329+
if coefficients(g) isa OneElement
330+
@test coefficients(Derivative() * g) isa OneElement
331+
end
332+
end
333+
334+
g = NormalizedUltraspherical(3)(3)
335+
@test Derivative() * g == Derivative() * Fun(space(g), collect(coefficients(g)))
336+
@static if isdefined(FillArrays, :OneElement)
337+
if coefficients(g) isa OneElement
338+
@test coefficients(Derivative() * g) isa OneElement
339+
end
340+
end
341+
end
301342
end
302343

303344
@testset "inplace transform" begin

0 commit comments

Comments
 (0)