Skip to content

Commit a943adf

Browse files
committed
Tests pass
1 parent ca0586a commit a943adf

File tree

6 files changed

+210
-24
lines changed

6 files changed

+210
-24
lines changed

src/ApproxFunFourier.jl

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,32 +11,33 @@ import FFTW: plan_r2r!, fftwNumber, REDFT10, REDFT01, REDFT00, RODFT00, R2HC, HC
1111
r2r!, r2r, plan_fft, plan_ifft, plan_ifft!, plan_fft!
1212

1313
import ApproxFunBase: normalize!, flipsign, FiniteRange, MatrixFun, UnsetSpace, VFun, RowVector,
14-
UnivariateSpace, AmbiguousSpace, SumSpace, SubSpace,
14+
UnivariateSpace, AmbiguousSpace, SumSpace, SubSpace, NoSpace, Space,
1515
IntervalOrSegment, RaggedMatrix, AlmostBandedMatrix,
1616
AnyDomain, ZeroSpace, TrivialInterlacer, BlockInterlacer,
1717
AbstractTransformPlan, TransformPlan, ITransformPlan,
1818
ConcreteConversion, ConcreteMultiplication, ConcreteDerivative, ConcreteIntegral,
19-
MultiplicationWrapper, ConversionWrapper, DerivativeWrapper,
19+
MultiplicationWrapper, ConversionWrapper, DerivativeWrapper, Evaluation,
2020
Conversion, Multiplication, Derivative, Integral, bandwidths,
2121
ConcreteEvaluation, ConcreteDefiniteLineIntegral, ConcreteDefiniteIntegral, ConcreteIntegral,
2222
DefiniteLineIntegral, DefiniteIntegral, ConcreteDefiniteIntegral, ConcreteDefiniteLineIntegral,
23-
ReverseOrientation, Reverse, Dirichlet,
23+
ReverseOrientation, ReverseOrientationWrapper, ReverseWrapper, Reverse, NegateEven, Dirichlet,
2424
TridiagonalOperator, SubOperator, Space, @containsconstants, spacescompatible,
2525
hasfasttransform, canonicalspace, setdomain, prectype, domainscompatible,
26-
plan_transform, plan_itransform, transform, itransform, hasfasttransform, Integral,
26+
plan_transform, plan_itransform, plan_transform!, plan_itransform!, transform, itransform, hasfasttransform, Integral,
2727
domainspace, rangespace, boundary,
28-
union_rule, conversion_rule, maxspace_rule, conversion_type, hasconversion, points,
28+
union_rule, conversion_rule, maxspace_rule, conversion_type, maxspace, hasconversion, points,
2929
rdirichlet, ldirichlet, lneumann, rneumann, ivp, bvp,
3030
linesum, differentiate, integrate, linebilinearform, bilinearform,
3131
UnsetNumber, coefficienttimes,
32-
Segment, isambiguous, Vec, eps,
32+
Segment, isambiguous, Vec, eps, isperiodic,
3333
arclength, complexlength,
3434
invfromcanonicalD, fromcanonical, tocanonical, fromcanonicalD, tocanonicalD, canonicaldomain, setcanonicaldomain, mappoint,
35-
reverseorientation, checkpoints, evaluate, mul_coefficients, coefficients,
35+
reverseorientation, checkpoints, evaluate, mul_coefficients, coefficients, isconvertible,
3636
clenshaw, ClenshawPlan, sineshaw,
3737
toeplitz_getindex, toeplitz_axpy!, ToeplitzOperator, hankel_getindex,
3838
SpaceOperator, ZeroOperator, InterlaceOperator,
39-
interlace!, reverseeven!, negateeven!, cfstype
39+
interlace!, reverseeven!, negateeven!, cfstype, pad!,
40+
extremal_args, hesseneigvals
4041

4142
import DomainSets: Domain, indomain, UnionDomain, ProductDomain, FullSpace, Point, elements, DifferenceDomain,
4243
Interval, ChebyshevInterval, boundary, ∂, rightendpoint, leftendpoint,
@@ -66,6 +67,7 @@ import FastTransforms: ChebyshevTransformPlan, IChebyshevTransformPlan, plan_che
6667

6768
export Fourier, Taylor, Hardy, CosSpace, SinSpace, Laurent, PeriodicDomain
6869

70+
include("utils.jl")
6971
include("Domains/Domains.jl")
7072

7173
for T in (:CosSpace,:SinSpace)
@@ -602,5 +604,25 @@ include("specialfunctions.jl")
602604
include("FourierOperators.jl")
603605
include("LaurentOperators.jl")
604606
include("LaurentDirichlet.jl")
607+
include("roots.jl")
608+
609+
Fun(::typeof(identity), d::Circle) = Fun(Laurent(d),[d.center,0.,d.radius])
610+
611+
Space(d::PeriodicDomain) = Fourier(d)
612+
Space(d::Circle) = Laurent(d)
613+
614+
615+
## Evaluation
616+
617+
Evaluation(d::PeriodicDomain,x::Number,n...) = Evaluation(Laurent(d),complex(x),n...)
618+
619+
## Definite Integral
620+
621+
DefiniteIntegral(d::PeriodicDomain) = DefiniteIntegral(Laurent(d))
622+
DefiniteLineIntegral(d::PeriodicDomain) = DefiniteLineIntegral(Laurent(d))
623+
624+
## Toeplitz
625+
union_rule(A::Space{<:PeriodicSegment}, B::Space{<:IntervalOrSegment}) =
626+
union(Space(Interval(domain(A))), B)
605627

606628
end #module

src/Domains/Domains.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
abstract type PeriodicDomain{T} <: Domain{T} end
55

6+
isperiodic(::PeriodicDomain) = true
67

78
canonicaldomain(::PeriodicDomain) = PeriodicSegment()
89

src/roots.jl

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
2+
function companion_matrix(c::Vector{T}) where T
3+
n=length(c)-1
4+
5+
if n==0
6+
zeros(T,0,0)
7+
else
8+
A=zeros(T,n,n)
9+
for k=1:n
10+
A[k,end]=-c[k]/c[end]
11+
end
12+
for k=2:n
13+
A[k,k-1]=one(T)
14+
end
15+
A
16+
end
17+
end
18+
19+
20+
# if isdir(Pkg.dir("AMVW"))
21+
# using AMVW
22+
# function complexroots(cfs::Vector)
23+
# c=chop(cfs,10eps())
24+
#
25+
# # Only use special routine for large roots
26+
# if length(c)≥70
27+
# Main.AMVW.rootsAMVW(c)
28+
# else
29+
# hesseneigvals(companion_matrix(c))
30+
# end
31+
# end
32+
# else
33+
complexroots(cfs::Vector{T}) where {T<:Union{Float64,ComplexF64}} =
34+
hesseneigvals(companion_matrix(chop(cfs,10eps())))
35+
# end
36+
37+
function complexroots(cfs::Vector{T}) where T<:Union{BigFloat,Complex{BigFloat}}
38+
a = Fun(Taylor(Circle(BigFloat)),cfs)
39+
ap = a'
40+
rts = Array{Complex{BigFloat}}(complexroots(Vector{ComplexF64}(cfs)))
41+
# Do 3 Newton steps
42+
for _ = 1:3
43+
rts .-= a.(rts)./ap.(rts)
44+
end
45+
rts
46+
end
47+
48+
complexroots(neg::Vector, pos::Vector) =
49+
complexroots([reverse(chop(neg,10eps()), dims=1);pos])
50+
complexroots(f::Fun{Laurent{DD,RR}}) where {DD,RR} =
51+
mappoint.(Ref(Circle()), Ref(domain(f)),
52+
complexroots(f.coefficients[2:2:end],f.coefficients[1:2:end]))
53+
complexroots(f::Fun{Taylor{DD,RR}}) where {DD,RR} =
54+
mappoint.(Ref(Circle()), Ref(domain(f)), complexroots(f.coefficients))
55+
56+
57+
58+
function roots(f::Fun{Laurent{DD,RR}}) where {DD,RR}
59+
irts=filter!(z->in(z,Circle()),complexroots(Fun(Laurent(Circle()),f.coefficients)))
60+
if length(irts)==0
61+
Complex{Float64}[]
62+
else
63+
rts=fromcanonical.(f, tocanonical.(Ref(Circle()), irts))
64+
if isa(domain(f),PeriodicSegment)
65+
sort!(real(rts)) # Make type safe?
66+
else
67+
rts
68+
end
69+
end
70+
end
71+
72+
73+
roots(f::Fun{Fourier{D,R}}) where {D,R} = roots(Fun(f,Laurent))

src/specialfunctions.jl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,21 @@ function Base.imag(f::Fun{Laurent{DD,RR}}) where {DD,RR}
4242

4343
Fun(Fourier(domain(f)),ret)
4444
end
45+
46+
47+
function log(f::Fun{Fourier{D,R},T}) where {T<:Real,D,R}
48+
if isreal(domain(f))
49+
cumsum(differentiate(f)/f)+log(first(f))
50+
else
51+
# this makes sure differentiate doesn't
52+
# make the function complex
53+
g=log(setdomain(f,PeriodicSegment()))
54+
setdomain(g,domain(f))
55+
end
56+
end
57+
58+
extremal_args(f::Fun{<:Space{<:PeriodicSegment}}) = roots(differentiate(f))
59+
function extremal_args(f::Fun{<:Space{<:PeriodicDomain}})
60+
S=typeof(space(f))
61+
fromcanonical.(f,extremal_args(setcanonicaldomain(f)))
62+
end

src/utils.jl

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# diff from CosSpace -> SinSpace
2+
3+
function cosspacediff(v::AbstractVector{T}) where T<:Number
4+
if length(v)==1
5+
w = zeros(T,1)
6+
else
7+
w = Array{T}(undef, length(v)-1)
8+
for k=1:length(v)-1
9+
@inbounds w[k] = -k*v[k+1]
10+
end
11+
end
12+
13+
w
14+
end
15+
16+
# diff from SinSpace -> CosSpace
17+
18+
function sinspacediff(v::AbstractVector{T}) where T<:Number
19+
w = Array{T}(undef, length(v)+1)
20+
w[1] = zero(T)
21+
for k=1:length(v)
22+
@inbounds w[k+1] = k*v[k]
23+
end
24+
25+
w
26+
end
27+
28+
# diff from Fourier -> Fourier
29+
30+
function fourierdiff(v::AbstractVector{T}) where T<:Number
31+
n = 2(length(v)÷2)+1
32+
w = Array{T}(undef, n)
33+
w[1] = zero(T)
34+
n > 1 && (w[n-1] = zero(T))
35+
for k=1:n÷2-1
36+
@inbounds w[2k] = -k*v[2k+1]
37+
@inbounds w[2k+1] = k*v[2k]
38+
end
39+
n > 1 && (w[n] = (n÷2)*v[n-1]; n == length(v) && (w[n-1] = -(n÷2)*v[n]))
40+
41+
w
42+
end
43+
44+
# diff from Taylor -> Taylor
45+
46+
function taylor_diff(v::AbstractVector{T}) where T<:Number
47+
w = Array{T}(undef, length(v))
48+
for k=1:length(v)
49+
@inbounds w[k] = (k-1)*v[k]
50+
end
51+
52+
w
53+
end
54+
55+
# diff from Hardy{false} -> Hardy{false}
56+
57+
function hardyfalse_diff(v::AbstractVector{T}) where T<:Number
58+
w = Array{T}(undef, length(v))
59+
for k=1:length(v)
60+
@inbounds w[k] = -k*v[k]
61+
end
62+
63+
w
64+
end
65+
66+
# diff from Laurent -> Laurent
67+
68+
function laurentdiff(v::AbstractVector{T}) where T<:Number
69+
n = length(v)
70+
w = Array{T}(undef, n)
71+
w[1] = zero(T)
72+
n=length(v)
73+
74+
for k=1:(isodd(n) ? n÷2 : n÷2-1)
75+
@inbounds w[2k] = -k*v[2k]
76+
@inbounds w[2k+1] = k*v[2k+1]
77+
end
78+
79+
if iseven(n)
80+
@inbounds w[n] = -(n÷2)*v[n]
81+
end
82+
83+
w
84+
end

test/runtests.jl

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using ApproxFunFourier, ApproxFunBase, Test, BlockArrays, BlockBandedMatrices, SpecialFunctions, LinearAlgebra
22
import ApproxFunBase: testspace, testtransforms, testmultiplication,
3-
testbandedoperator, testcalculus, Block
3+
testbandedoperator, testcalculus, Block, Vec, testfunctional
44
import SpecialFunctions: factorial
55

66
@testset "Periodic Domains" begin
@@ -114,8 +114,6 @@ end
114114
v = randn(4) .+ im.*randn(4)
115115
@test P*v == P*real(v) + im*(P*imag(v))
116116

117-
@test norm(Fun(x->Fun(cos,Fourier(-π .. π),20)(x),20)-Fun(cos,20)) <100eps()
118-
@test norm(Fun(x->Fun(cos,Fourier(-π .. π))(x))-Fun(cos)) <100eps()
119117
@test norm(Fun(cos,Fourier)'+Fun(sin,Fourier)) < 100eps()
120118

121119
f=Fun(x->exp(-10sin((x-.1)/2)^2),Fourier)
@@ -156,8 +154,8 @@ end
156154
A = Multiplication(mySin,Fourier())
157155
@test A.op[1,1] == 0
158156

159-
@test norm(ApproxFun.Reverse(Fourier())*Fun(t->cos(cos(t-0.2)-0.1),Fourier()) - Fun(t->cos(cos(-t-0.2)-0.1),Fourier())) < 10eps()
160-
@test norm(ApproxFun.ReverseOrientation(Fourier())*Fun(t->cos(cos(t-0.2)-0.1),Fourier()) - Fun(t->cos(cos(t-0.2)-0.1),Fourier(PeriodicSegment(2π,0)))) < 10eps()
157+
@test norm(ApproxFunBase.Reverse(Fourier())*Fun(t->cos(cos(t-0.2)-0.1),Fourier()) - Fun(t->cos(cos(-t-0.2)-0.1),Fourier())) < 10eps()
158+
@test norm(ApproxFunBase.ReverseOrientation(Fourier())*Fun(t->cos(cos(t-0.2)-0.1),Fourier()) - Fun(t->cos(cos(t-0.2)-0.1),Fourier(PeriodicSegment(2π,0)))) < 10eps()
161159
end
162160

163161
@testset "Laurent" begin
@@ -169,7 +167,6 @@ end
169167
@test Fun(Laurent(-1..1),[1,1.,1.])(0.1) 1+2cos*(0.1+1))
170168
@test Fun(Laurent(0..1),[1,1.,1.])(0.1) 1+2cos(2π*0.1)
171169

172-
@test norm(Fun(x->Fun(cos,Laurent)(x))-Fun(cos)) <100eps()
173170
@test norm(Fun(cos,Laurent)'+Fun(sin,Laurent)) < 100eps()
174171

175172
B=Evaluation(Laurent(0..2π),0,1)
@@ -367,20 +364,11 @@ end
367364
end
368365

369366
@testset "Integral equations" begin
370-
@time for S in (Fourier(Circle()),Laurent(Circle()),Taylor(Circle()),
371-
CosSpace(Circle()),JacobiWeight(-0.5,-0.5,Chebyshev()),
372-
JacobiWeight(-0.5,-0.5,Chebyshev(Segment(1.0,2.0+im))),
373-
JacobiWeight(0.5,0.5,Ultraspherical(1,Segment(1.0,2.0+im))))
367+
@time for S in (Fourier(Circle()),Laurent(Circle()),Taylor(Circle()),CosSpace(Circle()))
374368
testfunctional(DefiniteLineIntegral(S))
375369
end
376370

377371
Σ = DefiniteIntegral()
378-
379-
f1 = Fun(t->cos(cos(t)),-π..π)
380-
f = Fun(t->cos(cos(t)),Laurent(-π..π))
381-
382-
@test sum(f1) Σ*f
383-
384372
f1 = Fun(t->cos(cos(t))/t,Laurent(Circle()))
385373
f2 = Fun(t->cos(cos(t))/t,Fourier(Circle()))
386374
@test Σ*f1 Σ*f2

0 commit comments

Comments
 (0)