Skip to content

Commit 366d2ba

Browse files
authored
avoid eval in specialfn (#195)
* avoid eval in specialfn * add tests * fix coverage
1 parent 7151a98 commit 366d2ba

File tree

3 files changed

+38
-21
lines changed

3 files changed

+38
-21
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "ApproxFunBase"
22
uuid = "fbd15aa5-315a-5a7d-a8a4-24992e37be05"
3-
version = "0.6.20"
3+
version = "0.6.21"
44

55
[deps]
66
AbstractFFTs = "621f4979-c628-5d54-868e-fcf4e3e8185c"

src/specialfunctions.jl

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -140,17 +140,21 @@ cos(f::Fun{S,T}) where {S<:RealSpace,T<:Real} = real(exp(im*f))
140140

141141
atan(f::Fun)=cumsum(f'/(1+f^2))+atan(first(f))
142142

143-
144-
# this is used to find a point in which to impose a boundary
145-
# condition in calculating secial functions
146-
function specialfunctionnormalizationpoint(op,growth,f)
143+
function _specialfunctionnormalizationpoint(op,growth,f)
147144
g=chop(growth(f),eps(cfstype(f)))
148145
d = domain(g)
149146
T = eltype(d)
150147
xmin = isempty(g.coefficients) ? leftendpoint(d) : T(argmin(g))::T
151148
xmax = isempty(g.coefficients) ? rightendpoint(d) : T(argmax(g))::T
152149
opfxmin,opfxmax = op(f(xmin)),op(f(xmax))
153150
opmax = maximum(abs,(opfxmin,opfxmax))
151+
xmin, xmax, opfxmin, opfxmax, opmax
152+
end
153+
154+
# this is used to find a point in which to impose a boundary
155+
# condition in calculating secial functions
156+
function specialfunctionnormalizationpoint(op,growth,f)
157+
xmin, xmax, opfxmin, opfxmax, opmax = _specialfunctionnormalizationpoint(op,growth,f)
154158
if abs(opfxmin) == opmax
155159
xmax,opfxmax = xmin,opfxmin
156160
end
@@ -192,7 +196,15 @@ for (op, ODE, RHS, growth) in ((:(exp), "D-f'", "0", :(real)
192196
end
193197
end
194198

195-
199+
function specialfunctionnormalizationpoint2(op, growth, f, T = cfstype(f))
200+
xmin, xmax, opfxmin, opfxmax, opmax = _specialfunctionnormalizationpoint(op,growth,f)
201+
while opmax10eps(T) || abs(f(xmin)-f(xmax))10eps(T)
202+
xmin,xmax = rand(domain(f)),rand(domain(f))
203+
opfxmin,opfxmax = op(f(xmin)),op(f(xmax))
204+
opmax = maximum(abs,(opfxmin,opfxmax))
205+
end
206+
xmin, xmax, opfxmin, opfxmax, opmax
207+
end
196208

197209
for (op,ODE,RHS,growth) in ((:(erf),"f'*D^2+(2f*f'^2-f'')*D","0",:(imag)),
198210
(:(erfi),"f'*D^2-(2f*f'^2+f'')*D","0",:(real)),
@@ -207,22 +219,13 @@ for (op,ODE,RHS,growth) in ((:(erf),"f'*D^2+(2f*f'^2-f'')*D","0",:(imag)),
207219
L,R = Meta.parse(ODE),Meta.parse(RHS)
208220
@eval begin
209221
function $op(fin::Fun)
210-
f=setcanonicaldomain(fin)
211-
212222
T = cfstype(fin)
213-
g=chop($growth(f),eps(T))
214-
xmin = isempty(g.coefficients) ? leftendpoint(domain(g)) : argmin(g)
215-
xmax = isempty(g.coefficients) ? rightendpoint(domain(g)) : argmax(g)
216-
opfxmin,opfxmax = $op(f(xmin)),$op(f(xmax))
217-
opmax = maximum(abs,(opfxmin,opfxmax))
218-
while opmax10eps(T) || abs(f(xmin)-f(xmax))10eps(T)
219-
xmin,xmax = rand(domain(f)),rand(domain(f))
220-
opfxmin,opfxmax = $op(f(xmin)),$op(f(xmax))
221-
opmax = maximum(abs,(opfxmin,opfxmax))
222-
end
223-
D=Derivative(space(f))
224-
B=[Evaluation(space(f),xmin),Evaluation(space(f),xmax)]
225-
u=\([B;eval($L)],[opfxmin;opfxmax;eval($R)];tolerance=10eps(T)*opmax)
223+
f=setcanonicaldomain(fin)
224+
xmin, xmax, opfxmin, opfxmax, opmax = specialfunctionnormalizationpoint2($op, $growth, f, T)
225+
S = space(f)
226+
B=[Evaluation(S,xmin), Evaluation(S,xmax)]
227+
D=Derivative(S)
228+
u=\([B;$L], [opfxmin;opfxmax;$R]; tolerance=10eps(T)*opmax)
226229

227230
setdomain(u,domain(fin))
228231
end

test/SpacesTest.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ using LinearAlgebra
2222
f2 = @inferred Fun(space(f), view(Float64[1:3;], :))
2323
@test coefficients(f2) == coefficients(f)
2424

25+
f = Fun(PointSpace(1:4), [1:4;])
26+
for spfn in Any[sin, cos, exp]
27+
@test values(spfn(f)) spfn.(points(f))
28+
end
29+
2530
@testset "conversions" begin
2631
@testset for S in Any[typeof(space(f)), Any]
2732
T = Fun{S, Any, Any}
@@ -370,6 +375,15 @@ using LinearAlgebra
370375
@test coefficients(f^2) == coefficients(g^2)
371376
end
372377

378+
@testset "special functions" begin
379+
for f in Any[Fun(), Fun(-0.5..1), Fun(Segment(1.0+im,2.0+2im))]
380+
for spfn in Any[sin, cos, exp]
381+
p = leftendpoint(domain(f))
382+
@test spfn(f)(p) spfn(p) atol=1e-14
383+
end
384+
end
385+
end
386+
373387
@testset "Derivative" begin
374388
@test Derivative() == Derivative()
375389
for d in Any[(), (0..1,)]

0 commit comments

Comments
 (0)