@@ -331,26 +331,74 @@ Base.transpose(d::TensorSpace) = TensorSpace(d.spaces[2],d.spaces[1])
331
331
332
332
333
333
# # 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
335
342
for (plan, plan!, Typ) in ((:plan_transform , :plan_transform! , :TransformPlan ),
336
343
(: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 })
341
344
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
344
358
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
347
369
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
350
374
end
351
375
M
352
376
end
353
377
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
+
354
402
function * (T:: $Typ{TT,SS,false} ,v:: AbstractVector ) where {SS<: TensorSpace ,TT}
355
403
P = $ Typ (T. space,T. plan,Val{true })
356
404
P* AbstractVector {rangetype(SS)} (v)
@@ -489,7 +537,7 @@ function points(sp::TensorSpace,n)
489
537
end
490
538
491
539
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))))
493
541
494
542
evaluate (f:: AbstractVector ,S:: AbstractProductSpace ,x) = ProductFun (totensor (S,f),S)(x... )
495
543
evaluate (f:: AbstractVector ,S:: AbstractProductSpace ,x,y) = ProductFun (totensor (S,f),S)(x,y)
0 commit comments