Skip to content

Commit 25fb1d8

Browse files
authored
Add supportsinplacetransform trait (#379)
1 parent 69fe27c commit 25fb1d8

File tree

4 files changed

+31
-18
lines changed

4 files changed

+31
-18
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.7.70"
3+
version = "0.7.71"
44

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

src/LinearAlgebra/helper.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ promote_rule(::Type{Bool}, ::Type{UnsetNumber}) = Bool
3232

3333
# Test the number of arguments a function takes
3434
hasnumargs(f,k) = k == 1 ? applicable(f, 0.0) : applicable(f, (1.0:k)...)
35+
hasonearg(f) = hasnumargs(f, 1)
3536

3637
# fast implementation of isapprox with atol a non-keyword argument in most cases
3738
isapprox_atol(a,b,atol;kwds...) = isapprox(a,b;atol=atol,kwds...)

src/Space.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,21 @@ itransform(S::Space, cfs) = plan_itransform(S,cfs)*cfs
553553
itransform!(S::Space,cfs) = plan_itransform!(S,cfs)*cfs
554554
transform!(S::Space,cfs) = plan_transform!(S,cfs)*cfs
555555

556+
_transform!!(::Val{false}) = transform
557+
_transform!!(::Val{true}) = transform!
558+
_itransform!!(::Val{false}) = itransform
559+
_itransform!!(::Val{true}) = itransform!
560+
561+
"""
562+
supportsinplacetransform(s::Space)
563+
564+
Trait that states if an inplace transform is possible for the space `s`.
565+
In general, this is possible if `transform(s, v)` has the same `eltype` and `size` as `v`.
566+
By default this is assumed to be `false`.
567+
568+
New spaces may choose to extend this if the result is known statically.
569+
"""
570+
supportsinplacetransform(_) = false
556571

557572
_coefficients!!(::Val{true}) = coefficients!
558573
_coefficients!!(::Val{false}) = coefficients

src/constructors.jl

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,19 @@ end
3838

3939
# default_Fun is the default constructor, based on evaluation and transforms
4040
# last argument is whether to splat or not
41-
default_Fun(T::Type,f,d::Space,pts::AbstractArray, shouldsplat::Val{true}) =
42-
Fun(d,transform(d,T[f(x...) for x in pts]))
41+
function default_Fun(T::Type, f, d::Space, pts::AbstractArray, shouldsplat::Val{true})
42+
default_Fun(T, Base.splat(f), d, pts, Val(false))
43+
end
4344

44-
default_Fun(T::Type,f,d::Space,pts::AbstractArray, shouldsplat::Val{false}) =
45-
Fun(d,transform(d,broadcast!(f, similar(pts, T), pts)))
45+
function default_Fun(T::Type, f, d::Space, pts::AbstractArray, shouldsplat::Val{false})
46+
fv = broadcast!(f, similar(pts, T), pts)
47+
tfn = _transform!!(Val(supportsinplacetransform(d)))
48+
coeffs = tfn(d, fv)
49+
Fun(d, coeffs)
50+
end
4651

4752

48-
function default_Fun(f,d::Space,n::Integer, shouldsplat::Val{false})
53+
function default_Fun(f, d::Space, n::Integer, shouldsplat::Val{false})
4954
pts=points(d, n)
5055
f1=f(pts[1])
5156
if isa(f1,AbstractArray) && size(d) size(f1)
@@ -57,19 +62,11 @@ function default_Fun(f,d::Space,n::Integer, shouldsplat::Val{false})
5762
default_Fun(Tprom,f,d,pts,Val(false))
5863
end
5964

60-
function default_Fun(f,d::Space,n::Integer, shouldsplat::Val{true})
61-
pts=points(d, n)
62-
f1=f(pts[1]...)
63-
if isa(f1,AbstractArray) && size(d) size(f1)
64-
return Fun(f,Space(fill(d,size(f1))),n)
65-
end
66-
67-
# we need 3 eltype calls for the case Interval(Point([1.,1.]))
68-
Tprom=choosefuncfstype(typeof(f1),prectype(domain(d)))
69-
default_Fun(Tprom,f,d,pts,Val(true))
65+
function default_Fun(f, d::Space, n::Integer, shouldsplat::Val{true})
66+
default_Fun(Base.splat(f), d, n, Val(false))
7067
end
7168

72-
default_Fun(f,d::Space,n::Integer) = default_Fun(f,d,n,Val(!hasnumargs(f,1)))
69+
default_Fun(f,d::Space,n::Integer) = default_Fun(f,d,n,Val(!hasonearg(f)))
7370

7471
Fun(f,d::Space,n::Integer) = default_Fun(dynamic(f),d,n)
7572

@@ -96,7 +93,7 @@ Fun(c::Number,d::Space) = c==0 ? c*zeros(prectype(d),d) : c*ones(prectype(d),d)
9693

9794
## Adaptive constructors
9895
function default_Fun(f, d::Space)
99-
_default_Fun(hasnumargs(f, 1) ? f : Base.splat(f), d)
96+
_default_Fun(hasonearg(f) ? f : Base.splat(f), d)
10097
end
10198
# In _default_Fun, we know that the function takes a single argument
10299
function _default_Fun(f, d::Space)

0 commit comments

Comments
 (0)