Skip to content

Commit

Permalink
Added FSFT
Browse files Browse the repository at this point in the history
  • Loading branch information
mnolander committed Aug 23, 2024
1 parent 3f4874c commit 552d69a
Show file tree
Hide file tree
Showing 11 changed files with 550 additions and 33 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Python interface for the [NFFT C library](https://github.com/NFFT/nfft). Based o
- nonequispaced fast cosine transform (NFCT)
- nonequispaced fast sine transform (NFST)
- nonequispaced fast spherical Fourier transforms (NFSFT)
- fast spherical Fourier transforms (FSFT)
- fast summation (fastsum)

## Getting started
Expand Down
1 change: 1 addition & 0 deletions docs/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ API Contents
/api/nfct
/api/nfst
/api/nfsft
/api/fsft
/api/fastsum
81 changes: 81 additions & 0 deletions docs/source/api/fsft.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
``pyNFFT3.FSFT`` - FSFT Class
================================

FSFT Methods
-------------

.. autoclass:: pyNFFT3.FSFT
:members:
:undoc-members:
:member-order: bysource
:exclude-members: f, fhat, __init__

FSFT Attributes
----------------

.. attribute:: plan <fsft_plan>

FSFT plan (C pointer)

.. attribute:: N <int>

The bandwidth :math:`N \epsilon N_0`. Must be a positive integer.

.. attribute:: M <int>

The number of nodes. Must be a positive integer.

.. attribute:: flags <ctypes.c_uint32>

The FSFT flags.

.. attribute:: nfft_flags <ctypes.c_unit32>

The NFFT flags.

.. attribute:: nfft_cutoff <int>

The NFFT cutoff.

.. .. attribute:: x <numpy.ndarray>
.. Float array for sampling nodes.
.. attribute:: f <numpy.ndarray>

Complex array for FSFT values or coefficients for the adjoint FSFT.

.. attribute:: fhat <numpy.ndarray>

Complex array of spherical Fourier coefficients for the FSFT or values for the adjoint FSFT.

.. attribute:: init_done <boolean>

Boolean to indicate if the FSFT plan is initialized.

.. attribute:: finalized <boolean>

Boolean to indicate if the FSFT plan is finalized.

NFSFT Flags
------------
.. autodata:: pyNFFT3.flags.NFSFT_NORMALIZED
.. autodata:: pyNFFT3.flags.NFSFT_USE_NDFT
.. autodata:: pyNFFT3.flags.NFSFT_USE_DPT
.. autodata:: pyNFFT3.flags.NFSFT_MALLOC_X
.. autodata:: pyNFFT3.flags.NFSFT_MALLOC_F_HAT
.. autodata:: pyNFFT3.flags.NFSFT_MALLOC_F
.. autodata:: pyNFFT3.flags.NFSFT_PRESERVE_F_HAT
.. autodata:: pyNFFT3.flags.NFSFT_PRESERVE_X
.. autodata:: pyNFFT3.flags.NFSFT_PRESERVE_F
.. autodata:: pyNFFT3.flags.NFSFT_DESTROY_F_HAT
.. autodata:: pyNFFT3.flags.NFSFT_DESTROY_X
.. autodata:: pyNFFT3.flags.NFSFT_DESTROY_F
.. autodata:: pyNFFT3.flags.NFSFT_NO_DIRECT_ALGORITHM
.. autodata:: pyNFFT3.flags.NFSFT_NO_FAST_ALGORITHM
.. autodata:: pyNFFT3.flags.NFSFT_ZERO_F_HAT
.. autodata:: pyNFFT3.flags.NFSFT_EQUISPACED
.. autodata:: pyNFFT3.flags.nfsft_default
.. autodata:: pyNFFT3.flags.nfsft_nfft_default
.. autodata:: pyNFFT3.flags.nfsft_default_nfft_cut_off
.. autodata:: pyNFFT3.flags.nfsft_default_threshold
1 change: 1 addition & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pyNFFT3 Documentation
- nonequispaced fast cosine transform (NFCT)
- nonequispaced fast sine transform (NFST)
- nonequispaced fast spherical Fourier transforms (NFSFT)
- fast spherical Fourier transforms (FSFT)
- fast summation (fastsum)

Contents
Expand Down
89 changes: 71 additions & 18 deletions docs/source/tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,25 @@ You can then generate a plan with your desired multiband limit values and number
M = 5 # 5 nodes
plan = NFFT(N, M) # generate plan
To compute the NDFT using **trafo()** or **trafo_direct()**, both **x** and **fhat** must be set:
To compute the NDFT using **nfft_trafo()** or **nfft_trafo_direct()**, both **x** and **fhat** must be set:

.. code-block:: python
plan.x = np.array([[0.1, 0.2], [0.3, 0.4], [0.5, 0.6], [0.7, 0.8], [0.9, 1.0]]) # sampling nodes (M entries)
plan.fhat = np.array([0.1+0.1j, 0.2-0.2j, 0.3+0.3j, 0.4-0.4j, 0.5+0.5j, 0.6-0.6j, 0.7+0.7j, 0.8-0.8j]) # Fourier coefficients (numpy.prod(N) entries)
plan.trafo()
plan.nfft_trafo()
# or
plan.trafo_direct()
plan.nfft_trafo_direct()
To compute the adjoint NDFT using **adjoint()** or **adjoint_direct()**, both **x** and **f** must be set:
To compute the adjoint NDFT using **nfft_adjoint()** or **nfft_adjoint_direct()**, both **x** and **f** must be set:

.. code-block:: python
plan.x = np.array([[0.1, 0.2], [0.3, 0.4], [0.5, 0.6], [0.7, 0.8], [0.9, 1.0]]) # sampling nodes (M entries)
plan.f = np.array([1.0+1.0j, 1.1-1.1j, 1.2+1.2j, 1.3-1.3j, 1.4+1.4j]) # values for adjoint NFFT (M entries)
plan.adjoint()
plan.nfft_adjoint()
# or
plan.adjoint_direct()
plan.nfft_adjoint_direct()
Using NFCT
----------
Expand All @@ -69,15 +69,15 @@ You can then generate a plan with your desired multiband limit values and number
M = 5 # 5 nodes
plan = NFCT(N, M) # generate plan
To compute the NDCT using **trafo()** or **trafo_direct()**, both **x** and **fhat** must be set:
To compute the NDCT using **nfct_trafo()** or **nfct_trafo_direct()**, both **x** and **fhat** must be set:

.. code-block:: python
plan.x = np.array([[0.1, 0.2], [0.3, 0.4], [0.5, 0.6], [0.7, 0.8], [0.9, 1.0]]) # sampling nodes (M entries)
plan.fhat = np.array([1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8]) # Fourier coefficients (numpy.prod(N) entries)
plan.trafo()
plan.nfct_trafo()
# or
plan.trafo_direct()
plan.nfct_trafo_direct()
To compute the transposed NDCT using **nfct_transposed()** or **nfct_transposed_direct()**, both **x** and **f** must be set:

Expand Down Expand Up @@ -113,15 +113,15 @@ You can then generate a plan with your desired multiband limit values and number
M = 5 # 5 nodes
plan = NFST(N, M) # generate plan
To compute the NDST using **trafo()** or **trafo_direct()**, both **x** and **fhat** must be set:
To compute the NDST using **nfst_trafo()** or **nfst_trafo_direct()**, both **x** and **fhat** must be set:

.. code-block:: python
plan.x = np.array([[0.1, 0.2], [0.3, 0.4], [0.5, 0.6], [0.7, 0.8], [0.9, 1.0]]) # sampling nodes (M entries)
plan.fhat = np.array([1.1, 2.2, 3.3]) # Fourier coefficients (numpy.prod(N - 1) entries)
plan.trafo()
plan.nfst_trafo()
# or
plan.trafo_direct()
plan.nfst_trafo_direct()
To compute the transposed NDST using **nfst_transposed()** or **nfst_transposed_direct()**, both **x** and **f** must be set:

Expand Down Expand Up @@ -156,7 +156,7 @@ You can then generate a plan with your desired bandwidth and number of nodes (wh
M = 8 # 8 nodes
plan = NFSFT(N, M) # generate plan
To compute the NFSFT using **trafo()** or the NDFST using **trafo_direct()**, both **x** and **fhat** must be set.
To compute the NFSFT using **nfsft_trafo()** or the NDFST using **nfsft_trafo_direct()**, both **x** and **fhat** must be set.
**fhat** must be created in a format using **nfsft_index()** to properly space the entries of **fhat**:

.. code-block:: python
Expand All @@ -172,23 +172,76 @@ To compute the NFSFT using **trafo()** or the NDFST using **trafo_direct()**, bo
index = plan.nfsft_index(k, n)
fhat[index] = (np.random.rand() - 0.5) + 1j * (np.random.rand() - 0.5) # Fourier coefficients, spaced using nfsft_index()
plan.trafo()
plan.nfsft_trafo()
# or
plan.trafo_direct()
plan.nfsft_trafo_direct()
To compute the adjoint NFSFT using **nfst_adjoint()** or **nfst_adjoint_direct()**, both **x** and **f** must be set.
**trafo()** and **trafo_direct()** produce values for **f**, so it is possible to use these outputs:
To compute the adjoint NFSFT using **nfsft_adjoint()** or **nfsft_adjoint_direct()**, both **x** and **f** must be set.
**nfsft_trafo()** and **nfsft_trafo_direct()** produce values for **f**, so it is possible to use these outputs:

.. code-block:: python
plan.x = np.array([
[0.48, 0.45, -0.18, 0.03, -0.08, 0.49, -0.32, 0.13],
[-0.37, 0.12, -0.13, 0.21, -0.15, 0.09, 0.4, 0.43]]) # sampling nodes (2xM entries )
plan.trafo() # assuming fhat is set, this will populate plan.f
plan.nfsft_trafo() # assuming fhat is set, this will populate plan.f
# or
plan.f = np.array([0.1+0.1j, 0.2-0.2j, 0.3+0.3j, 0.4-0.4j, 0.5+0.5j, 0.6-0.6j, 0.7+0.7j, 0.8-0.8j]) # values for adjoint NFSFT (M entries)
plan.nfsft_transposed()
# or
plan.nfsft_transposed_direct()
Using FSFT
------------

View the `test file <https://github.com/NFFT/pyNFFT3/blob/main/tests/FSFT_test.py>`_
for a detailed example of all function uses and error tests.

Or view the `API reference <https://github.com/NFFT/pyNFFT3/blob/main/docs/source/api/FSFT.rst>`_
for the class methods and attributes.

To start using FSFT, first import the class:

.. code-block:: python
from pyNFFT3 import FSFT
You can then generate a plan with your desired bandwidth and number of nodes (which will be checked for proper type/size):

.. code-block:: python
N = 6 # bandwidth
M = 8 # 8 nodes
plan = FSFT(N, M) # generate plan
To compute the FSFT using **fsft_trafo()** or the DFST using **fsft_trafo_direct()**, just **fhat** must be set.
**fhat** must be created in a format using **fsft_index()** to properly space the entries of **fhat**:

.. code-block:: python
import numpy as np
fhat = np.zeros((2*plan.N+2)**2, dtype=np.complex128) # set up structure for fhat ((2*N+2)*(2*N+2) entries)
for k in range(N + 1):
for n in range(-k, k + 1):
index = plan.fsft_index(k, n)
fhat[index] = (np.random.rand() - 0.5) + 1j * (np.random.rand() - 0.5) # Fourier coefficients, spaced using fsft_index()
plan.fsft_trafo()
# or
plan.fsft_trafo_direct()
To compute the adjoint FSFT using **fsft_adjoint()** or **fsft_adjoint_direct()**, just **f** must be set.
**fsft_trafo()** and **fsft_trafo_direct()** produce values for **f**, so it is possible to use these outputs:

.. code-block:: python
plan.fsft_trafo() # assuming fhat is set, this will populate plan.f
# or
plan.f = np.array([0.1+0.1j, 0.2-0.2j, 0.3+0.3j, 0.4-0.4j, 0.5+0.5j, 0.6-0.6j, 0.7+0.7j, 0.8-0.8j]) # values for adjoint FSFT (M entries)
plan.nfst_transposed()
# or
plan.nfst_transposed_direct()
Expand Down
Loading

0 comments on commit 552d69a

Please sign in to comment.