@@ -303,18 +303,22 @@ coefficients(f::AbstractVector,sp1::Space,::Type{T2}) where {T2<:Space} = coeffi
303303
304304# # coefficients defaults to calling Conversion, otherwise it tries to pipe through Chebyshev
305305
306+ _mul_coefficients!! (inplace:: Val{true} ) = mul_coefficients!
307+ _mul_coefficients!! (inplace:: Val{false} ) = mul_coefficients
308+ _ldiv_coefficients!! (inplace:: Val{true} ) = ldiv_coefficients!
309+ _ldiv_coefficients!! (inplace:: Val{false} ) = ldiv_coefficients
306310
307311_Fun (v:: AbstractVector , sp) = Fun (sp, v)
308312_Fun (v, sp) = Fun (v, sp)
309- function defaultcoefficients (f,a,b)
313+ function defaultcoefficients (f,a,b,inplace = Val ( false ) )
310314 ct= conversion_type (a,b) # gives a space that has a banded conversion to both a and b
311315
312316 if spacescompatible (a,b)
313317 f
314318 elseif hasconversion (a,b)
315- mul_coefficients (Conversion (a,b),f)
319+ _mul_coefficients!! (inplace) (Conversion (a,b),f)
316320 elseif hasconversion (b,a)
317- ldiv_coefficients (Conversion (b,a),f)
321+ _ldiv_coefficients!! (inplace) (Conversion (b,a),f)
318322 else
319323 csp= canonicalspace (a)
320324
@@ -323,14 +327,15 @@ function defaultcoefficients(f,a,b)
323327 end
324328 if spacescompatible (a,csp) || spacescompatible (b,csp)
325329 # b is csp too, so we are stuck, try Fun constructor
326- coefficients (default_Fun (_Fun (f,a),b))
330+ _coefficients!! (inplace) (default_Fun (_Fun (f,a),b))
327331 else
328- coefficients (f,a,csp,b)
332+ _coefficients!! (inplace) (f,a,csp,b)
329333 end
330334 end
331335end
332336
333337coefficients (f,a,b) = defaultcoefficients (f,a,b)
338+ coefficients! (f,a,b) = defaultcoefficients (f,a,b,Val (true ))
334339
335340
336341
@@ -368,50 +373,43 @@ end
368373
369374for Typ in (:CanonicalTransformPlan ,:ICanonicalTransformPlan )
370375 @eval begin
371- struct $ Typ{T,SP,PL,CSP} <: AbstractTransformPlan{T}
376+ struct $ Typ{T,SP,PL,CSP,inplace } <: AbstractTransformPlan{T}
372377 space:: SP
373378 plan:: PL
374379 canonicalspace:: CSP
375380 end
376- $ Typ (space,plan,csp) =
377- $ Typ {eltype(plan),typeof(space),typeof(plan),typeof(csp)} (space,plan,csp)
378- $ Typ (:: Type{T} ,space,plan,csp) where {T} =
379- $ Typ {T,typeof(space),typeof(plan),typeof(csp)} (space,plan,csp)
381+ $ Typ (space,plan,csp) = $ Typ (space,plan,csp,Val (false ))
382+ $ Typ (space,plan,csp,ip:: Val{inplace} ) where {inplace} =
383+ $ Typ {eltype(plan),typeof(space),typeof(plan),typeof(csp),inplace} (space,plan,csp)
380384 end
381385end
382-
386+ inplace (:: CanonicalTransformPlan{<:Any,<:Any,<:Any,<:Any,IP} ) where {IP} = IP
387+ inplace (:: ICanonicalTransformPlan{<:Any,<:Any,<:Any,<:Any,IP} ) where {IP} = IP
383388
384389# Canonical plan uses coefficients
385- function CanonicalTransformPlan (space,v)
386- csp = canonicalspace (space)
387- CanonicalTransformPlan (eltype (v),space,plan_transform (csp,v),csp)
388- end
389390function checkcanonicalspace (sp)
390391 csp = canonicalspace (sp)
391392 sp == csp && error (" Override for $sp " )
392393 csp
393394end
394- function plan_transform (sp:: Space ,vals)
395- csp = checkcanonicalspace (sp)
396- CanonicalTransformPlan (sp,plan_transform (csp,vals),csp)
395+ _plan_transform!! (:: Val{true} ) = plan_transform!
396+ _plan_transform!! (:: Val{false} ) = plan_transform
397+ function CanonicalTransformPlan (space, v, inplace:: Val = Val (false ))
398+ csp = checkcanonicalspace (space)
399+ CanonicalTransformPlan (space, _plan_transform!! (inplace)(csp,v), csp, inplace)
397400end
398-
399- function ICanonicalTransformPlan (space,v)
400- csp = canonicalspace (space)
401- cfs = coefficients (v,space,csp)
402- ICanonicalTransformPlan (eltype (v),space,plan_itransform (csp,cfs),csp)
401+ plan_transform (sp:: Space ,vals) = CanonicalTransformPlan (sp, vals, Val (false ))
402+ plan_transform! (sp:: Space ,vals) = CanonicalTransformPlan (sp, vals, Val (true ))
403+
404+ _plan_itransform!! (:: Val{true} ) = plan_itransform!
405+ _plan_itransform!! (:: Val{false} ) = plan_itransform
406+ function ICanonicalTransformPlan (space, v, ip:: Val{inplace} = Val (false )) where {inplace}
407+ csp = checkcanonicalspace (space)
408+ cfs = inplace ? coefficients (v,space,csp) : v
409+ ICanonicalTransformPlan (space, _plan_itransform!! (ip)(csp,cfs), csp, ip)
403410end
404- function plan_itransform (sp:: Space ,v)
405- csp = checkcanonicalspace (sp)
406- cfs = coefficients (v,sp,csp)
407- ICanonicalTransformPlan (sp,plan_itransform (csp,cfs),csp)
408- end
409-
410-
411- plan_transform! (sp:: Space ,vals) = error (" Override for $sp " )
412- plan_itransform! (sp:: Space ,cfs) = error (" Override for $sp " )
413-
414-
411+ plan_itransform (sp:: Space ,v) = ICanonicalTransformPlan (sp, v, Val (false ))
412+ plan_itransform! (sp:: Space ,v) = ICanonicalTransformPlan (sp, v, Val (true ))
415413
416414# transform converts from values at points(S,n) to coefficients
417415# itransform converts from coefficients to values at points(S,n)
@@ -423,9 +421,11 @@ itransform!(S::Space,cfs) = plan_itransform!(S,cfs)*cfs
423421transform! (S:: Space ,cfs) = plan_transform! (S,cfs)* cfs
424422
425423
426- * (P:: CanonicalTransformPlan ,vals:: AbstractVector ) = coefficients (P. plan* vals,P. canonicalspace,P. space)
427- * (P:: ICanonicalTransformPlan ,cfs:: AbstractVector ) = P. plan* coefficients (cfs,P. space,P. canonicalspace)
428-
424+ _coefficients!! (:: Val{true} ) = coefficients!
425+ _coefficients!! (:: Val{false} ) = coefficients
426+ _mul (P:: CanonicalTransformPlan , ip, vals) = _coefficients!! (ip)(P. plan * vals, P. canonicalspace, P. space)
427+ _mul (P:: ICanonicalTransformPlan , ip, cfs) = P. plan * _coefficients!! (ip)(cfs, P. space, P. canonicalspace)
428+ * (P:: Union{CanonicalTransformPlan, ICanonicalTransformPlan} , vals:: AbstractVector ) = _mul (P, Val (inplace (P)), vals)
429429
430430
431431for OP in (:plan_transform ,:plan_itransform ,:plan_transform! ,:plan_itransform! )
0 commit comments