You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Implement AdjointPlans
* Implement chain rules for FFT plans
* Test plan adjoints and AD rules
* Apply suggestions from adjoint plan code review
Co-authored-by: David Widmann <[email protected]>
* Include irrft_dim in RealInverseProjectionStyle
Co-authored-by: David Widmann <[email protected]>
* update to new fftdims interface
* fix broken tests
* Explicitly don't support mul! for adjoint plans
* Document adjoint plans
* remove incorrectly thrown error
* Update adjoint plan docs
* Update adjoint docs
* Fix typos
* tweak adjoint doc string
* Tweaks to adjoint description
* Immutable AdjointPlan
* Add rules and tests for ScaledPlan
* Apply suggestions from code review
Co-authored-by: David Widmann <[email protected]>
* More tweaks to address code review
* Restrict to T<:Real for rfft adjoint
* Get type T correct for test irfft
* Test complex input when appropriate for adjoint tests
* Add plan_inv implementation for adjoint plan and test it
* Apply suggestions from code review
Co-authored-by: Seth Axen <[email protected]>
* Apply suggestions from code review
* Test in-place plans
---------
Co-authored-by: David Widmann <[email protected]>
Co-authored-by: David Widmann <[email protected]>
Co-authored-by: Seth Axen <[email protected]>
Copy file name to clipboardExpand all lines: README.md
+1-22Lines changed: 1 addition & 22 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,26 +16,5 @@ This allows multiple FFT packages to co-exist with the same underlying `fft(x)`
16
16
17
17
## Developer information
18
18
19
-
To define a new FFT implementation in your own module, you should
19
+
To define a new FFT implementation in your own module, see [defining a new implementation](https://juliamath.github.io/AbstractFFTs.jl/stable/implementations/#Defining-a-new-implementation).
20
20
21
-
* Define a new subtype (e.g. `MyPlan`) of `AbstractFFTs.Plan{T}` for FFTs and related transforms on arrays of `T`.
22
-
This must have a `pinv::Plan` field, initially undefined when a `MyPlan` is created, that is used for caching the
23
-
inverse plan.
24
-
25
-
* Define a new method `AbstractFFTs.plan_fft(x, region; kws...)` that returns a `MyPlan` for at least some types of
26
-
`x` and some set of dimensions `region`. The `region` (or a copy thereof) should be accessible via `fftdims(p::MyPlan)` (which defaults to `p.region`).
27
-
28
-
* Define a method of `LinearAlgebra.mul!(y, p::MyPlan, x)` (or `A_mul_B!(y, p::MyPlan, x)` on Julia prior to
29
-
0.7.0-DEV.3204) that computes the transform `p` of `x` and stores the result in `y`.
30
-
31
-
* Define a method of `*(p::MyPlan, x)`, which can simply call your `mul!` (or `A_mul_B!`) method.
32
-
This is not defined generically in this package due to subtleties that arise for in-place and real-input FFTs.
33
-
34
-
* If the inverse transform is implemented, you should also define `plan_inv(p::MyPlan)`, which should construct the
35
-
inverse plan to `p`, and `plan_bfft(x, region; kws...)` for an unnormalized inverse ("backwards") transform of `x`.
36
-
37
-
* You can also define similar methods of `plan_rfft` and `plan_brfft` for real-input FFTs.
38
-
39
-
The normalization convention for your FFT should be that it computes $y_k = \sum_j \exp\(-2 \pi i \cdot \frac{j k}{n}\) x_j$
40
-
for a transform of length $n$, and the "backwards" (unnormalized inverse) transform computes the same thing but with
Copy file name to clipboardExpand all lines: docs/src/implementations.md
+28-13Lines changed: 28 additions & 13 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,16 +11,31 @@ The following packages extend the functionality provided by AbstractFFTs:
11
11
12
12
## Defining a new implementation
13
13
14
-
Implementations should implement `LinearAlgebra.mul!(Y, plan, X)` (or
15
-
`A_mul_B!(y, p::MyPlan, x)` on Julia prior to 0.7.0-DEV.3204) so as to support
16
-
pre-allocated output arrays.
17
-
We don't define `*` in terms of `mul!` generically here, however, because
18
-
of subtleties for in-place and real FFT plans.
19
-
20
-
To support `inv`, `\`, and `ldiv!(y, plan, x)`, we require `Plan` subtypes
21
-
to have a `pinv::Plan` field, which caches the inverse plan, and which should be
22
-
initially undefined.
23
-
They should also implement `plan_inv(p)` to construct the inverse of a plan `p`.
24
-
25
-
Implementations only need to provide the unnormalized backwards FFT,
26
-
similar to FFTW, and we do the scaling generically to get the inverse FFT.
14
+
To define a new FFT implementation in your own module, you should
15
+
16
+
* Define a new subtype (e.g. `MyPlan`) of `AbstractFFTs.Plan{T}` for FFTs and related transforms on arrays of `T`.
17
+
This must have a `pinv::Plan` field, initially undefined when a `MyPlan` is created, that is used for caching the
18
+
inverse plan.
19
+
20
+
* Define a new method `AbstractFFTs.plan_fft(x, region; kws...)` that returns a `MyPlan` for at least some types of
21
+
`x` and some set of dimensions `region`. The `region` (or a copy thereof) should be accessible via `fftdims(p::MyPlan)` (which defaults to `p.region`).
22
+
23
+
* Define a method of `LinearAlgebra.mul!(y, p::MyPlan, x)` that computes the transform `p` of `x` and stores the result in `y`.
24
+
25
+
* Define a method of `*(p::MyPlan, x)`, which can simply call your `mul!` method.
26
+
This is not defined generically in this package due to subtleties that arise for in-place and real-input FFTs.
27
+
28
+
* If the inverse transform is implemented, you should also define `plan_inv(p::MyPlan)`, which should construct the
29
+
inverse plan to `p`, and `plan_bfft(x, region; kws...)` for an unnormalized inverse ("backwards") transform of `x`.
30
+
Implementations only need to provide the unnormalized backwards FFT, similar to FFTW, and we do the scaling generically
31
+
to get the inverse FFT.
32
+
33
+
* You can also define similar methods of `plan_rfft` and `plan_brfft` for real-input FFTs.
34
+
35
+
* To enable automatic computation of adjoint plans via [`Base.adjoint`](@ref) (used in rules for reverse-mode differentiation), define the trait `AbstractFFTs.ProjectionStyle(::MyPlan)`, which can return:
36
+
*`AbstractFFTs.NoProjectionStyle()`,
37
+
*`AbstractFFTs.RealProjectionStyle()`, for plans that halve one of the output's dimensions analogously to [`rfft`](@ref),
38
+
*`AbstractFFTs.RealInverseProjectionStyle(d::Int)`, for plans that expect an input with a halved dimension analogously to [`irfft`](@ref), where `d` is the original length of the dimension.
39
+
40
+
The normalization convention for your FFT should be that it computes ``y_k = \sum_j x_j \exp(-2\pi i j k/n)`` for a transform of
41
+
length ``n``, and the "backwards" (unnormalized inverse) transform computes the same thing but with ``\exp(+2\pi i jk/n)``.
0 commit comments