Commit 084c9f28 authored by Martin Reinecke's avatar Martin Reinecke
Browse files

merge NIFTY_5

parents 4a8838e9 173ccc29
......@@ -199,9 +199,9 @@ an overloaded :attr:`~operators.operator.Operator.apply` method, which can take:
This is the interface that all objects derived from
:class:`~operators.operator.Operator` must implement. In addition,
:class:`~operators.operator.Operator` objects can be added/subtracted,
multiplied, chained (via the :attr:`__call__` method
or the `@` operator) and support point-wise application of functions like
:class:`exp()`, :class:`log()`, :class:`sqrt()`, :class:`conjugate()`.
multiplied, chained (via the :attr:`__call__` method or the `@` operator) and
support point-wise application of functions like :class:`exp()`, :class:`log()`,
:class:`sqrt()`, :class:`conjugate()`.
Advanced operators
......@@ -210,35 +210,40 @@ Advanced operators
NIFTy provides a library of commonly employed operators which can be used for
specific inference problems. Currently these are:
- :class:`AmplitudeOperator`, which returns a smooth power spectrum.
- :class:`InverseGammaOperator`, which models point sources which are
.. currentmodule:: nifty5.library
- :class:`~amplitude_operator.AmplitudeOperator`, which returns a smooth power spectrum.
- :class:`~inverse_gamma_operator.InverseGammaOperator`, which models point sources which are
distributed according to a inverse-gamma distribution.
- :class:`CorrelatedField`, which models a diffuse log-normal field. It takes an
- :class:`~correlated_fields.CorrelatedField`, which models a diffuse log-normal field. It takes an
amplitude operator to specify the correlation structure of the field.
Linear Operators
================
A linear operator (represented by NIFTy5's abstract :class:`operators.linear_operator.LinearOperator`
class) is derived from `Operator` and can be interpreted as an
(implicitly defined) matrix. Since its operation is linear, it can provide some
additional functionality which is not available for the more generic :class:`operators.operator.Operator`
class.
.. currentmodule:: nifty5.operators
A linear operator (represented by NIFTy5's abstract
:class:`~linear_operator.LinearOperator` class) is derived from
:class:`~operator.Operator` and can be interpreted as an (implicitly defined)
matrix. Since its operation is linear, it can provide some additional
functionality which is not available for the more generic
:class:`~operator.Operator` class.
Linear Operator basics
----------------------
There are four basic ways of applying an operator :math:`A` to a field :math:`f`:
There are four basic ways of applying an operator :math:`A` to a field :math:`s`:
- direct application: :math:`A\cdot f`
- adjoint application: :math:`A^\dagger \cdot f`
- inverse application: :math:`A^{-1}\cdot f`
- adjoint inverse application: :math:`(A^\dagger)^{-1}\cdot f`
- direct application: :math:`A(s)`
- adjoint application: :math:`A^\dagger (s)`
- inverse application: :math:`A^{-1} (s)`
- adjoint inverse application: :math:`(A^\dagger)^{-1} (s)`
(Because of the linearity, inverse adjoint and adjoint inverse application
are equivalent.)
Note: The inverse of the adjoint of a linear map and the adjoint of the inverse
of a linear map (if all those exist) are the same.
These different actions of a linear operator ``Op`` on a field ``f`` can be
invoked in various ways:
......@@ -250,33 +255,45 @@ invoked in various ways:
Operator classes defined in NIFTy may implement an arbitrary subset of these
four operations. This subset can be queried using the
:attr:`~LinearOperator.capability` property.
:attr:`~linear_operator.LinearOperator.capability` property.
If needed, the set of supported operations can be enhanced by iterative
inversion methods;
for example, an operator defining direct and adjoint multiplication could be
enhanced by this approach to support the complete set. This functionality is
provided by NIFTy's :class:`InversionEnabler` class, which is itself a linear
inversion methods; for example, an operator defining direct and adjoint
multiplication could be enhanced by this approach to support the complete set.
This functionality is provided by NIFTy's
:class:`~inversion_enabler.InversionEnabler` class, which is itself a linear
operator.
.. currentmodule:: nifty5.operators.linear_operator
Direct multiplication and adjoint inverse multiplication transform a field
living on the operator's :attr:`~LinearOperator.domain` to one living on the operator's :attr:`~LinearOperator.target`, whereas adjoint multiplication
and inverse multiplication transform from :attr:`~LinearOperator.target` to :attr:`~LinearOperator.domain`.
defined on the operator's :attr:`~LinearOperator.domain` to one defined on the
operator's :attr:`~LinearOperator.target`, whereas adjoint multiplication and
inverse multiplication transform from :attr:`~LinearOperator.target` to
:attr:`~LinearOperator.domain`.
.. currentmodule:: nifty5.operators
Operators with identical domain and target can be derived from
:class:`EndomorphicOperator`; typical examples for this category are the :class:`ScalingOperator`, which simply multiplies its input by a scalar
value, and :class:`DiagonalOperator`, which multiplies every value of its input
field with potentially different values.
:class:`~endomorphic_operator.EndomorphicOperator`. Typical examples for this
category are the :class:`~scaling_operator.ScalingOperator`, which simply
multiplies its input by a scalar value, and
:class:`~diagonal_operator.DiagonalOperator`, which multiplies every value of
its input field with potentially different values.
.. currentmodule:: nifty5
Further operator classes provided by NIFTy are
- :class:`HarmonicTransformOperator` for transforms from a harmonic domain to
its counterpart in position space, and their adjoint
- :class:`PowerDistributor` for transforms from a :class:`PowerSpace` to
an associated harmonic domain, and their adjoint
- :class:`GeometryRemover`, which transforms from structured domains to
unstructured ones. This is typically needed when building instrument response
operators.
- :class:`~operators.harmonic_operators.HarmonicTransformOperator` for
transforms from a harmonic domain to its counterpart in position space, and
their adjoint
- :class:`~operators.distributors.PowerDistributor` for transforms from a
:class:`~domains.power_space.PowerSpace` to an associated harmonic domain, and
their adjoint.
- :class:`~operators.simple_linear_operators.GeometryRemover`, which transforms
from structured domains to unstructured ones. This is typically needed when
building instrument response operators.
Syntactic sugar
......@@ -284,12 +301,14 @@ Syntactic sugar
Nifty5 allows simple and intuitive construction of altered and combined
operators.
As an example, if ``A``, ``B`` and ``C`` are of type :class:`operators.linear_operator.LinearOperator`
As an example, if ``A``, ``B`` and ``C`` are of type :class:`~operators.linear_operator.LinearOperator`
and ``f1`` and ``f2`` are of type :class:`~field.Field`, writing::
X = A(B.inverse(A.adjoint)) + C
f2 = X(f1)
.. currentmodule:: nifty5.operators.linear_operator
will perform the operation suggested intuitively by the notation, checking
domain compatibility while building the composed operator.
The combined operator infers its domain and target from its constituents,
......@@ -308,29 +327,32 @@ Minimization
Most problems in IFT are solved by (possibly nested) minimizations of
high-dimensional functions, which are often nonlinear.
.. currentmodule:: nifty5.minimization
Energy functionals
------------------
In NIFTy5 such functions are represented by objects of type :class:`Energy`.
These hold the prescription how to calculate the function's
:attr:`~Energy.value`, :attr:`~Energy.gradient` and
(optionally) :attr:`~Energy.metric` at any given :attr:`~Energy.position`
in parameter space.
Function values are floating-point scalars, gradients have the form of fields
living on the energy's position domain, and metrics are represented by
linear operator objects.
In NIFTy5 such functions are represented by objects of type
:class:`~energy.Energy`. These hold the prescription how to calculate the
function's :attr:`~energy.Energy.value`, :attr:`~energy.Energy.gradient` and
(optionally) :attr:`~energy.Energy.metric` at any given
:attr:`~energy.Energy.position` in parameter space. Function values are
floating-point scalars, gradients have the form of fields living on the energy's
position domain, and metrics are represented by linear operator objects.
.. currentmodule:: nifty5
Energies are classes that typically have to be provided by the user when
tackling new IFT problems.
Some examples of concrete energy classes delivered with NIFTy5 are
:class:`QuadraticEnergy` (with position-independent metric, mainly used with
conjugate gradient minimization) and :class:`~nifty5.library.WienerFilterEnergy`.
tackling new IFT problems. An example of concrete energy classes delivered with
NIFTy5 is :class:`~minimization.quadratic_energy.QuadraticEnergy` (with
position-independent metric, mainly used with conjugate gradient minimization).
Iteration control
-----------------
.. currentmodule:: nifty5.minimization.iteration_controllers
Iterative minimization of an energy reqires some means of
checking the quality of the current solution estimate and stopping once
it is sufficiently accurate. In case of numerical problems, the iteration needs
......@@ -353,50 +375,61 @@ for their specific applications.
Minimization algorithms
-----------------------
.. currentmodule:: nifty5.minimization
All minimization algorithms in NIFTy inherit from the abstract
:class:`Minimizer` class, which presents a minimalistic interface consisting
only of a :meth:`~Minimizer.__call__` method taking an :class:`Energy` object
and optionally a preconditioning operator, and returning the energy at the
discovered minimum and a status code.
:class:`~minimizer.Minimizer` class, which presents a minimalistic interface
consisting only of a :meth:`~minimizer.Minimizer.__call__()` method taking an
:class:`~energy.Energy` object and optionally a preconditioning operator, and
returning the energy at the discovered minimum and a status code.
For energies with a quadratic form (i.e. which
can be expressed by means of a :class:`QuadraticEnergy` object), an obvious
choice of algorithm is the :class:`ConjugateGradient` minimizer.
For energies with a quadratic form (i.e. which can be expressed by means of a
:class:`~quadratic_energy.QuadraticEnergy` object), an obvious choice of
algorithm is the :class:`~conjugate_gradient.ConjugateGradient` minimizer.
A similar algorithm suited for nonlinear problems is provided by
:class:`NonlinearCG`.
:class:`~nonlinear_cg.NonlinearCG`.
Many minimizers for nonlinear problems can be characterized as
- first deciding on a direction for the next step
- then finding a suitable step length along this direction, resulting in the
- First deciding on a direction for the next step.
- Then finding a suitable step length along this direction, resulting in the
next energy estimate.
This family of algorithms is encapsulated in NIFTy's :class:`DescentMinimizer`
class, which currently has three concrete implementations:
:class:`SteepestDescent`, :class:`VL_BFGS`, and :class:`RelaxedNewton`.
Of these algorithms, only :class:`RelaxedNewton` requires the energy object to
provide a :attr:`~Energy.metric` property, the others only need energy
values and gradients.
The flexibility of NIFTy's design allows using externally provided
minimizers. With only small effort, adapters for two SciPy minimizers were
written; they are available under the names :class:`NewtonCG` and
This family of algorithms is encapsulated in NIFTy's
:class:`~descent_minimizers.DescentMinimizer` class, which currently has three
concrete implementations: :class:`~descent_minimizers.SteepestDescent`,
:class:`~descent_minimizers.RelaxedNewton`,
:class:`~descent_minimizers.NewtonCG`, :class:`~descent_minimizers.L_BFGS` and
:class:`~descent_minimizers.VL_BFGS`. Of these algorithms, only
:class:`~descent_minimizers.RelaxedNewton` requires the energy object to provide
a :attr:`~energy.Energy.metric` property, the others only need energy values and
gradients.
The flexibility of NIFTy's design allows using externally provided minimizers.
With only small effort, adapters for two SciPy minimizers were written; they are
available under the names :class:`~scipy_minimizer.ScipyCG` and
:class:`L_BFGS_B`.
Application to operator inversion
---------------------------------
It is important to realize that the machinery presented here cannot only be
used for minimizing IFT Hamiltonians, but also for the numerical inversion of
linear operators, if the desired application mode is not directly available.
A classical example is the information propagator
:math:`D = \left(R^\dagger N^{-1} R + S^{-1}\right)^{-1}`,
.. currentmodule:: nifty5
which must be applied when calculating a Wiener filter. Only its inverse
application is straightforward; to use it in forward direction, we make use
of NIFTy's :class:`InversionEnabler` class, which internally performs a
minimization of a :class:`QuadraticEnergy` by means of the
:class:`ConjugateGradient` algorithm.
The machinery presented here cannot only be used for minimizing functionals
derived from IFT, but also for the numerical inversion of linear operators, if
the desired application mode is not directly available. A classical example is
the information propagator whose inverse is defined as:
:math:`D^{-1} = \left(R^\dagger N^{-1} R + S^{-1}\right)`.
It needs to be applied in forward direction in order to calculate the Wiener
filter solution. Only its inverse application is straightforward; to use it in
forward direction, we make use of NIFTy's
:class:`~operators.inversion_enabler.InversionEnabler` class, which internally
performs a minimization of a
:class:`~minimization.quadratic_energy.QuadraticEnergy` by means of the
:class:`~minimization.conjugate_gradient.ConjugateGradient` algorithm. An
example is provided in
:func:`~ļibrary.wiener_filter_curvature.WienerFilterCurvature`.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment