Skip to content

fiery.diffeo.layers

Diffeomorphic layers: exponentiation, composition and resampling.

Every layer in this module follows the channel-first convention used by the rest of PyTorch: images are (batch, C, *spatial) tensors, and velocity, displacement and momentum fields are (batch, D, *spatial) tensors, where D is the number of spatial dimensions. (The functional API under fiery.diffeo.flows, fiery.diffeo.svf and fiery.diffeo.shoot uses the channel-last convention instead, and these layers transpose on the way in and out.)

Boundary conditions

There is no common convention for naming boundary conditions. The table below lists all the aliases understood by this package; the "Metric" column holds the names that the bound argument of these layers expects. The "Description" column sketches how a 1D signal a b c d is extended past its two ends.

Fourier     SciPy         Metric        Description
---------   -----------   -----------   ----------------------
dft         wrap          circulant      c  d | a b c d |  a  b
dct2        reflect       neumann        b  a | a b c d |  d  c
dct1        mirror                       c  b | a b c d |  c  b
dst2                      dirichlet     -b -a | a b c d | -d -c
dst1                                    -a  0 | a b c d |  0 -d

We further define a flow-specific "sliding" boundary condition, which combines dct2 and dst2: each component of the field uses dst2 along its own axis and dct2 along the other axes. Components are ordered like the spatial axes, so the "X component" below is the one that runs along the first (row) axis, and the "Y component" the one that runs along the second (column) axis.

X component                     Y component
-----------------------------   -----------------------------
 -f -e   -e -f -g -h   -h -g     -f -e    e  f  g  h   -h -g
 -b -a   -a -b -c -d   -d -c     -b -a    a  b  c  d   -d -c
-----------------------------   -----------------------------
  b  a |  a  b  c  d |  d  c     -b -a |  a  b  c  d | -d -c
  f  e |  e  f  g  h |  h  g     -f -e |  e  f  g  h | -h -g
  j  i |  i  j  k  l |  l  k     -j -i |  i  j  k  l | -l -k
  l  m |  m  n  o  p |  p  o     -n -m |  m  n  o  p | -p -o
-----------------------------   -----------------------------
 -n -m   -m -n -o -p   -p -o     -n -m    m  n  o  p   -p -o
 -j -i   -i -j -k -l   -l -k     -j -i    i  j  k  l   -l -k

Classes

Exp

Exp(bound='circulant', steps=8, anagrad=False, backend=None)

Bases: Module

Exponentiate a stationary velocity field by scaling and squaring.

Parameters:

Name Type Description Default
bound [list of] {'circulant', 'neumann', 'dirichlet', 'sliding'}

Boundary conditions.

'circulant'
steps int

Number of scaling and squaring steps.

8
anagrad bool

Use analytical gradients instead of autograd.

False
backend module

Backend to use to implement resampling. Must be one of the modules under fiery.diffeo.backends.

None
Notes

The number of equivalent Euler integration steps is 2**steps.

Analytical gradients use less memory than autograd gradients, as they do not require storing intermediate time steps during scaling and squaring. However, they may be slightly less accurate.

In differential equation terms, autograd corresponds to the strategy "discretize then optimize", whereas analytical gradients correspond to the strategy "optimize then discretize".

Methods:

BCH

BCH(bound='circulant', order=2, backend=None)

Bases: Module

Compose two stationary velocity fields using the BCH formula.

The Baker-Campbell-Hausdorff (BCH) formula gives the velocity field z such that exp(z) = exp(x) o exp(y), as a series of nested Lie brackets of x and y. The series is truncated at order.

See: https://en.wikipedia.org/wiki/BCH_formula

Parameters:

Name Type Description Default
bound [list of] {'circulant', 'neumann', 'dirichlet', 'sliding'}

Boundary conditions.

'circulant'
order (1, 2, 3, 4)

Maximum order used in the BCH series.

1
backend module

Backend to use to implement resampling. Must be one of the modules under fiery.diffeo.backends.

None

Methods:

Shoot

Shoot(metric=default_metric, steps=None, fast=True, backend=None)

Bases: Module

Exponentiate an initial velocity field by geodesic shooting.

Returns the forward transform.

Parameters:

Name Type Description Default
metric Metric

A Riemannian metric.

default_metric
steps int

Number of Euler integration steps. If None, use an educated guess based on the magnitude of the initial velocity.

None
fast bool

Use a faster but slightly less accurate integration scheme.

True
backend module

Backend to use to implement pullback and pushforward. Must be one of the modules under fiery.diffeo.backends.

None

Methods:

ShootInv

ShootInv(metric=default_metric, steps=None, fast=True, backend=None)

Bases: Module

Exponentiate an initial velocity field by geodesic shooting.

Returns the inverse transform.

Parameters:

Name Type Description Default
metric Metric

A Riemannian metric.

default_metric
steps int

Number of Euler integration steps. If None, use an educated guess based on the magnitude of the initial velocity.

None
fast bool

Use a faster but slightly less accurate integration scheme.

True
backend module

Backend to use to implement pullback and pushforward. Must be one of the modules under fiery.diffeo.backends.

None

Methods:

ShootBoth

ShootBoth(metric=default_metric, steps=None, fast=True, backend=None)

Bases: Module

Exponentiate an initial velocity field by geodesic shooting.

Returns both the forward and the inverse transform.

Parameters:

Name Type Description Default
metric Metric

A Riemannian metric.

default_metric
steps int

Number of Euler integration steps. If None, use an educated guess based on the magnitude of the initial velocity.

None
fast bool

Use a faster but slightly less accurate integration scheme.

True
backend module

Backend to use to implement pullback and pushforward. Must be one of the modules under fiery.diffeo.backends.

None

Methods:

Compose

Compose(bound='circulant', backend=None)

Bases: Module

Compose two displacement fields.

Parameters:

Name Type Description Default
bound [list of] {'circulant', 'neumann', 'dirichlet', 'sliding'}

Boundary conditions.

'circulant'
backend module

Backend to use to implement resampling. Must be one of the modules under fiery.diffeo.backends.

None

Methods:

Pull

Pull(bound='wrap', backend=None)

Bases: Module

Warp an image using a displacement field.

Parameters:

Name Type Description Default
bound [list of] {'wrap', 'reflect', 'mirror'}

Boundary conditions. If warping a displacement field, can also be one of the metric bounds: {'circulant', 'neumann', 'dirichlet', 'sliding'}

'wrap'
backend module

Backend to use to implement resampling. Must be one of the modules under fiery.diffeo.backends.

None

Methods:

Push

Push(bound='wrap', normalize=False, backend=None)

Bases: Module

Splat an image using a displacement field.

Parameters:

Name Type Description Default
bound [list of] {'wrap', 'reflect', 'mirror'}

Boundary conditions. If splatting a displacement field, can also be one of the metric bounds: {'circulant', 'neumann', 'dirichlet', 'sliding'}

'wrap'
normalize bool

Whether to divide the pushed values by the number of values pushed onto each voxel (i.e., the result of Count).

False
backend module

Backend to use to implement resampling. Must be one of the modules under fiery.diffeo.backends.

None

Methods:

Count

Count(bound='wrap', backend=None)

Bases: Module

Splat an image of ones using a displacement field.

Parameters:

Name Type Description Default
bound [list of] {'wrap', 'reflect', 'mirror'}

Boundary conditions. If splatting a displacement field, can also be one of the metric bounds: {'circulant', 'neumann', 'dirichlet', 'sliding'}

'wrap'
backend module

Backend to use to implement resampling. Must be one of the modules under fiery.diffeo.backends.

None

Methods: