Skip to content

Commit 875bf05

Browse files
authored
getindex for Cos/SinSpace ConcreteEvaluation (#89)
* getindex for Cos/SinSpace ConcreteEvaluation * Number arguments in SinSpace * ConcreteEvaluation for Fourier * ConcreteEvaluation for Laurent * rename _eval to _conceval
1 parent fd97768 commit 875bf05

File tree

5 files changed

+159
-4
lines changed

5 files changed

+159
-4
lines changed

Project.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "ApproxFunFourier"
22
uuid = "59844689-9c9d-51bf-9583-5b794ec66d30"
3-
version = "0.3.19"
3+
version = "0.3.20"
44

55
[deps]
66
AbstractFFTs = "621f4979-c628-5d54-868e-fcf4e3e8185c"
@@ -17,7 +17,7 @@ StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
1717

1818
[compat]
1919
AbstractFFTs = "0.5, 1"
20-
ApproxFunBase = "0.8.9"
20+
ApproxFunBase = "0.8.16"
2121
ApproxFunBaseTest = "0.1"
2222
ApproxFunOrthogonalPolynomials = "0.6"
2323
Aqua = "0.5"

src/ApproxFunFourier.jl

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ import ApproxFunBase: Fun, SumSpace, SubSpace, NoSpace, IntervalOrSegment,
3535
reverseeven!, negateeven!, cfstype, alternatesign!, extremal_args,
3636
hesseneigvals, chebyshev_clenshaw, roots, EmptyDomain,
3737
chebmult_getindex, components, affine_setdiff, complexroots,
38-
assert_integer, companion_matrix, InterlaceOperator_Diagonal
38+
assert_integer, companion_matrix, InterlaceOperator_Diagonal,
39+
evaluation_point, SpecialEvalPtType
3940

4041
import BandedMatrices: bandwidths
4142

@@ -261,6 +262,31 @@ function evaluate(f::AbstractVector,S::CosSpace,t)
261262
end
262263
end
263264

265+
function _conceval(C, ::CosSpace, order, x::SpecialEvalPtType, m)
266+
if iseven(order)
267+
one(eltype(C))
268+
else
269+
zero(eltype(C))
270+
end
271+
end
272+
function _conceval(C, ::CosSpace, order, x, m)
273+
y = tocanonical(domain(C), x)
274+
t = if iseven(order)
275+
cos(m * y)
276+
else
277+
sin(m * y)
278+
end
279+
convert(eltype(C), t)
280+
end
281+
function getindex(C::ConcreteEvaluation{<:CosSpace{<:PeriodicSegment}}, k::Integer)
282+
m = k - 1
283+
order = C.order
284+
L = period(domain(C))
285+
t = _conceval(C, domainspace(C), C.order, evaluation_point(C), m)
286+
s = mod(order, 4) (1,2) ? -1 : 1
287+
r = s * (m * 2pi/L)^order * t
288+
convert(eltype(C), r)
289+
end
264290

265291
points(sp::SinSpace,n)=points(domain(sp),2n+2)[2:n+1]
266292

@@ -292,7 +318,31 @@ itransform(sp::SinSpace,vals::AbstractVector,plan) = plan*vals
292318

293319
evaluate(f::AbstractVector,S::SinSpace,t) = sineshaw(f,tocanonical(S,t))
294320

295-
321+
function _conceval(C, ::SinSpace, order, x::SpecialEvalPtType, k)
322+
if iseven(order)
323+
zero(eltype(C))
324+
else
325+
one(eltype(C))
326+
end
327+
end
328+
function _conceval(C, ::SinSpace, order, x, m)
329+
y = tocanonical(domain(C), x)
330+
t = if iseven(order)
331+
sin(m * y)
332+
else
333+
cos(m * y)
334+
end
335+
convert(eltype(C), t)
336+
end
337+
function getindex(C::ConcreteEvaluation{<:SinSpace{<:PeriodicSegment}}, k::Integer)
338+
m = k
339+
order = C.order
340+
L = period(domain(C))
341+
t = _conceval(C, domainspace(C), C.order, evaluation_point(C), m)
342+
s = mod(order, 4) (0,1) ? 1 : -1
343+
r = s * (m * 2pi/L)^order * t
344+
convert(eltype(C), r)
345+
end
296346

297347
## Laurent space
298348
"""

src/FourierOperators.jl

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,3 +379,30 @@ for TYP in (:Fourier,:Laurent,:CosSpace,:SinSpace,:Taylor)
379379
end
380380
end
381381
end
382+
383+
Evaluation(F::Fourier{<:PeriodicSegment}, x, order) = ConcreteEvaluation(F, x, order)
384+
function _conceval(C, ::Fourier, order, x::SpecialEvalPtType, m, k)
385+
if (iseven(order) && isodd(k)) || (isodd(order) && iseven(k))
386+
one(eltype(C))
387+
else
388+
zero(eltype(C))
389+
end
390+
end
391+
function _conceval(C, ::Fourier, order, x, m, k)
392+
y = tocanonical(domain(C), x)
393+
t = if (iseven(order) && isodd(k)) || (isodd(order) && iseven(k))
394+
cos(m * y)
395+
else
396+
sin(m * y)
397+
end
398+
convert(eltype(C), t)
399+
end
400+
function getindex(C::ConcreteEvaluation{<:Fourier{<:PeriodicSegment}}, k::Integer)
401+
m = k ÷ 2
402+
order = C.order
403+
L = period(domain(C))
404+
t = _conceval(C, domainspace(C), C.order, evaluation_point(C), m, k)
405+
s = (-1)^((order + isodd(k))÷2)
406+
r = s * (m * 2pi/L)^order * t
407+
convert(eltype(C), r)
408+
end

src/LaurentOperators.jl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,3 +315,24 @@ function Conversion(A::Laurent{DD,RR},B::Laurent{DD,RR}) where {DD,RR}
315315
InterlaceOperator(Diagonal([Matrix(I,1,1),PermutationOperator([2,1])]))
316316
,A,B))
317317
end
318+
319+
Evaluation(F::Laurent{<:PeriodicSegment}, x, order) = ConcreteEvaluation(F, x, order)
320+
function _conceval(C, ::Laurent, order, x::SpecialEvalPtType, m, k)
321+
one(eltype(C))
322+
end
323+
flip_even(k) = isodd(k) ? 1 : -1
324+
function _conceval(C, ::Laurent, order, x, m, k)
325+
y = tocanonical(domain(C), x)
326+
s = flip_even(k)
327+
t = cis(s * m * y)
328+
convert(eltype(C), t)
329+
end
330+
function getindex(C::ConcreteEvaluation{<:Laurent{<:PeriodicSegment}}, k::Integer)
331+
m = k ÷ 2
332+
order = C.order
333+
L = period(domain(C))
334+
t = _conceval(C, domainspace(C), C.order, evaluation_point(C), m, k)
335+
s = flip_even(k)
336+
r = (im * s * m * 2pi/L)^order * t
337+
convert(eltype(C), r)
338+
end

test/runtests.jl

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,35 @@ end
110110

111111
## Bug in multiplicaiton
112112
@test Fun(SinSpace(),Float64[])^2 == Fun(SinSpace(),Float64[])
113+
114+
@testset "Evaluation" begin
115+
@testset "CosSpace" begin
116+
@testset for sp in [CosSpace(), CosSpace(1..2)]
117+
f = Fun(sp, Float64[1:8;])
118+
@test ldirichlet(sp) * f f(leftendpoint(domain(f)))
119+
@test rdirichlet(sp) * f f(rightendpoint(domain(f)))
120+
@test (lneumann(sp) * f)(leftendpoint(domain(f))) f'(leftendpoint(domain(f))) atol=1e-10
121+
@test (rneumann(sp) * f)(rightendpoint(domain(f))) f'(rightendpoint(domain(f))) atol=1e-10
122+
pt = 1.2
123+
@test Evaluation(sp, pt, 0) * f f(pt)
124+
@test Evaluation(sp, pt, 1) * f f'(pt)
125+
@test Evaluation(sp, pt, 2) * f f''(pt)
126+
end
127+
end
128+
@testset "SinSpace" begin
129+
@testset for sp in [SinSpace(), SinSpace(1..2)]
130+
f = Fun(sp, Float64[1:8;])
131+
@test (ldirichlet(sp) * f)(leftendpoint(domain(f))) f(leftendpoint(domain(f))) atol=1e-10
132+
@test (rdirichlet(sp) * f)(leftendpoint(domain(f))) f(rightendpoint(domain(f))) atol=1e-10
133+
@test lneumann(sp) * f f'(leftendpoint(domain(f)))
134+
@test rneumann(sp) * f f'(rightendpoint(domain(f)))
135+
pt = 1.2
136+
@test Evaluation(sp, pt, 0) * f f(pt)
137+
@test Evaluation(sp, pt, 1) * f f'(pt)
138+
@test Evaluation(sp, pt, 2) * f f''(pt)
139+
end
140+
end
141+
end
113142
end
114143

115144

@@ -252,6 +281,20 @@ end
252281
@test coefficients([4; zeros(4); [1, 2]; zeros(4); 3], Fourier(0..6pi), Fourier(0..2pi)) [4,1,2,3]
253282
@test coefficients([4; zeros(6); [1, 2]; zeros(6); 3], Fourier(0..8pi), Fourier(0..2pi)) [4,1,2,3]
254283
end
284+
285+
@testset "Evaluation" begin
286+
@testset for sp in [Fourier(), Fourier(1..2)]
287+
f = Fun(sp, Float64[1:8;])
288+
@test ldirichlet(sp) * f f(leftendpoint(domain(f)))
289+
@test rdirichlet(sp) * f f(rightendpoint(domain(f)))
290+
@test (lneumann(sp) * f)(leftendpoint(domain(f))) f'(leftendpoint(domain(f))) atol=1e-10
291+
@test (rneumann(sp) * f)(rightendpoint(domain(f))) f'(rightendpoint(domain(f))) atol=1e-10
292+
pt = 1.2
293+
@test Evaluation(sp, pt, 0) * f f(pt)
294+
@test Evaluation(sp, pt, 1) * f f'(pt)
295+
@test Evaluation(sp, pt, 2) * f f''(pt)
296+
end
297+
end
255298
end
256299

257300
@testset "Laurent" begin
@@ -271,6 +314,20 @@ end
271314
## Diagonal Derivative
272315
D = @inferred Derivative(Laurent())
273316
@test isdiag(D)
317+
318+
@testset "Evaluation" begin
319+
@testset for sp in [Laurent(), Laurent(1..2)]
320+
f = Fun(sp, Float64[1:8;])
321+
@test ldirichlet(sp) * f f(leftendpoint(domain(f)))
322+
@test rdirichlet(sp) * f f(rightendpoint(domain(f)))
323+
@test (lneumann(sp) * f)(leftendpoint(domain(f))) f'(leftendpoint(domain(f))) atol=1e-10
324+
@test (rneumann(sp) * f)(rightendpoint(domain(f))) f'(rightendpoint(domain(f))) atol=1e-10
325+
pt = 1.2
326+
@test Evaluation(sp, pt, 0) * f f(pt)
327+
@test Evaluation(sp, pt, 1) * f f'(pt)
328+
@test Evaluation(sp, pt, 2) * f f''(pt)
329+
end
330+
end
274331
end
275332

276333
@testset "Circle" begin

0 commit comments

Comments
 (0)