Skip to content

Commit abed5ff

Browse files
authored
n-d transforms (#215)
* n-d transforms * fix itransform for matrices * fix values for ArrayFun
1 parent c54d5a0 commit abed5ff

File tree

3 files changed

+63
-14
lines changed

3 files changed

+63
-14
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.9"
3+
version = "0.7.10"
44

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

src/Fun.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,8 @@ extrapolate(f::Fun,x,y,z...) = extrapolate(f.coefficients,f.space,Vec(x,y,z...))
245245

246246
values(f::Fun,dat...) = _values(f.space, f.coefficients, dat...)
247247
_values(sp, v, dat...) = itransform(sp, v, dat...)
248-
_values(sp, v::Vector{T}, dat...) where {T} = itransform(sp, v, dat...)::Vector{float(T)}
248+
_values(sp::UnivariateSpace, v::Vector{T}, dat...) where {T<:Number} =
249+
itransform(sp, v, dat...)::Vector{float(T)}
249250
points(f::Fun) = points(f.space,ncoefficients(f))
250251
ncoefficients(f::Fun)::Int = length(f.coefficients)
251252
blocksize(f::Fun) = (block(space(f),ncoefficients(f)).n[1],)

src/Multivariate/TensorSpace.jl

Lines changed: 60 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -331,26 +331,74 @@ Base.transpose(d::TensorSpace) = TensorSpace(d.spaces[2],d.spaces[1])
331331

332332

333333
## Transforms
334-
334+
function nDtransform_inner!(A, tempv, Rpre, Rpost, dim, plan!)
335+
for indpost in Rpost, indpre in Rpre
336+
v = view(A, indpre, :, indpost)
337+
tempv .= v
338+
v .= plan! * tempv
339+
end
340+
A
341+
end
335342
for (plan, plan!, Typ) in ((:plan_transform, :plan_transform!, :TransformPlan),
336343
(:plan_itransform, :plan_itransform!, :ITransformPlan))
337-
@eval begin
338-
$plan!(S::TensorSpace, M::AbstractMatrix) = $Typ(S,(($plan(S.spaces[1],size(M,1)),size(M,1)),
339-
($plan(S.spaces[2],size(M,2)),size(M,2))),
340-
Val{true})
341344

342-
function *(T::$Typ{<:Any,<:TensorSpace,true}, M::AbstractMatrix)
343-
n=size(M,1)
345+
for (f, ip) in [(plan, false), (plan!, true)]
346+
@eval function $f(S::TensorSpace{<:NTuple{N,Space}}, A::AbstractArray{<:Any,N}) where {N}
347+
spaces = S.spaces
348+
tempv = similar(A, size(A,1))
349+
sizehint!(tempv, maximum(size(A), init=0))
350+
plans = ntuple(N) do dim
351+
szdim = size(A,dim)
352+
resize!(tempv, szdim)
353+
($f(spaces[dim], tempv), szdim)
354+
end
355+
$Typ(S, plans, Val{$ip})
356+
end
357+
end
344358

345-
for k=1:size(M,2)
346-
M[:,k]=T.plan[1][1]*M[:,k]
359+
@eval begin
360+
function *(T::$Typ{<:Any,<:TensorSpace{<:NTuple{2,Space}},true}, M::AbstractMatrix)
361+
Base.require_one_based_indexing(M)
362+
all(dim -> T.plan[dim][2] == size(M,dim), 1:2) ||
363+
throw(ArgumentError("size of matrix is incompatible with transform plan"))
364+
365+
tempv = similar(M, size(M,1))
366+
for k in axes(M,2)
367+
tempv .= @view M[:, k]
368+
M[:,k]=T.plan[1][1]*tempv
347369
end
348-
for k=1:n
349-
M[k,:]=T.plan[2][1]*M[k,:]
370+
resize!(tempv, size(M,2))
371+
for k in axes(M,1)
372+
tempv .= @view M[k,:]
373+
M[k,:]=T.plan[2][1]*tempv
350374
end
351375
M
352376
end
353377

378+
function *(T::$Typ{<:Any,<:TensorSpace{<:NTuple{N,Space}},true}, A::AbstractArray{<:Any,N}) where {N}
379+
Base.require_one_based_indexing(A)
380+
all(dim -> T.plan[dim][2] == size(A,dim), 1:N) ||
381+
throw(ArgumentError("size of array is incompatible with transform plan"))
382+
383+
tempv = similar(A, size(A,1))
384+
sizehint!(tempv, maximum(size(A), init=0))
385+
for dim in 1:N
386+
Rpre = CartesianIndices(axes(A)[1:dim-1])
387+
Rpost = CartesianIndices(axes(A)[dim+1:end])
388+
resize!(tempv, size(A, dim))
389+
nDtransform_inner!(A, tempv, Rpre, Rpost, dim, T.plan[dim][1])
390+
end
391+
A
392+
end
393+
394+
function *(T::$Typ{<:Any,<:TensorSpace{<:NTuple{N,Space}},false},
395+
A::AbstractArray{<:Any,N}) where {N}
396+
# TODO: we assume that the transform has the same number of coefficients
397+
# as the number of points in A
398+
# This may not always be the case, so we may need to fix this
399+
$Typ(T.space, T.plan, Val{true}) * copy(A)
400+
end
401+
354402
function *(T::$Typ{TT,SS,false},v::AbstractVector) where {SS<:TensorSpace,TT}
355403
P = $Typ(T.space,T.plan,Val{true})
356404
P*AbstractVector{rangetype(SS)}(v)
@@ -489,7 +537,7 @@ function points(sp::TensorSpace,n)
489537
end
490538

491539

492-
itransform(sp::TensorSpace,cfs) = vec(itransform!(sp,coefficientmatrix(Fun(sp,cfs))))
540+
itransform(sp::TensorSpace,cfs::AbstractVector) = vec(itransform!(sp,coefficientmatrix(Fun(sp,cfs))))
493541

494542
evaluate(f::AbstractVector,S::AbstractProductSpace,x) = ProductFun(totensor(S,f),S)(x...)
495543
evaluate(f::AbstractVector,S::AbstractProductSpace,x,y) = ProductFun(totensor(S,f),S)(x,y)

0 commit comments

Comments
 (0)