### more doc work

parent ff879f9c
Pipeline #25106 passed with stages
in 6 minutes and 36 seconds
 ... @@ -128,6 +128,10 @@ class) can be interpreted as an (implicitly defined) matrix. ... @@ -128,6 +128,10 @@ class) can be interpreted as an (implicitly defined) matrix. It can be applied to :class:Field instances, resulting in other :class:Field It can be applied to :class:Field instances, resulting in other :class:Field instances that potentially live on other domains. instances that potentially live on other domains. 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:f: - direct multiplication: :math:A\cdot f - direct multiplication: :math:A\cdot f ... @@ -179,6 +183,10 @@ Further operator classes provided by NIFTy are ... @@ -179,6 +183,10 @@ Further operator classes provided by NIFTy are unstructured ones. This is typically needed when building instrument response unstructured ones. This is typically needed when building instrument response operators. operators. Syntatic sugar -------------- Nifty4 allows simple and intuitive construction of altered and combined Nifty4 allows simple and intuitive construction of altered and combined operators. operators. As an example, if A, B and C are of type :class:LinearOperator As an example, if A, B and C are of type :class:LinearOperator ... @@ -201,16 +209,68 @@ were the original operator's adjoint or inverse, respectively. ... @@ -201,16 +209,68 @@ were the original operator's adjoint or inverse, respectively. Minimization Minimization ============ ============ Most problems in IFT are solved by (possibly nested) minimizations of high-dimensional functions, which are often nonlinear. Most problems in IFT are solved by (possibly nested) minimizations of high-dimensional functions, which are often nonlinear. Energy functionals ------------------ In NIFTy4 such functions are represented by objects of type :class:Energy. In NIFTy4 such functions are represented by objects of type :class:Energy. These hold the prescription how to calculate the function's value, gradient and (optionally) curvature at any given position. These hold the prescription how to calculate the function's Function values are floating-point scalars, gradients have the form of fields living on the energy's position domain, and curvatures are represented by linear operator objects. :attr:~Energy.value, :attr:~Energy.gradient and (optionally) :attr:~Energy.curvature at any given position. Function values are floating-point scalars, gradients have the form of fields living on the energy's position domain, and curvatures are represented by linear operator objects. Some examples of concrete energy classes delivered with NIFTy4 are :class:QuadraticEnergy (with position-independent curvature, mainly used with conjugate gradient minimization) and :class:WienerFilterEnergy. Energies are classes that typically have to be provided by the user when tackling new IFT problems. The minimization procedure can be carried out by one of several algorithms; NIFTy4 currently ships solvers based on Convergence control ------------------- Iterative minimization of an energy reqires some means of controlling the quality of the current solution estimate and stopping once it is sufficiently accurate. In case of numerical problems, the iteration needs to be terminated as well, returning a suitable error description. In NIFTy4, this functionality is encapsulated in the abstract :class:IterationController class, which is provided with the initial energy object before starting the minimization, and is updated with the improved energy after every iteration. Based on this information, it can either continue the minimization or return the current estimate indicating convergence or failure. Sensible stopping criteria can vary significantly with the problem being solved; NIFTy provides one concrete sub-class of :class:IterationController called :class:GradientNormController, which should be appropriate in many circumstances, but users have complete freedom to implement custom sub-classes for their specific applications. Minimization algorithms ----------------------- 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}, 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 a :class:ConjugateGradient algorithm. Some examples of concrete energy classes delivered with NIFTy4 are :class:QuadraticEnergy (with position-independent curvature, mainly used with conjugate gradient minimization) and :class:WienerFilterEnergy. Energies are classes that typically have to be provided by the user when tackling new IFT problems. The minimization procedure can be carried out by one of several algorithms; NIFTy4 currently ships solvers based on - the conjugate gradient method (for quadratic energies) - the conjugate gradient method (for quadratic energies) - the steepest descent method - the steepest descent method ... ...
 ... @@ -53,12 +53,12 @@ class Energy(NiftyMetaBase()): ... @@ -53,12 +53,12 @@ class Energy(NiftyMetaBase()): self._position = position.lock() self._position = position.lock() def at(self, position): def at(self, position): """ Initializes and returns a new Energy object at the new position. """ Returns a new Energy object, initialized at position. Parameters Parameters ---------- ---------- position : Field position : Field Parameter for the new Energy object. Location in parameter space for the new Energy object. Returns Returns ------- ------- ... @@ -70,15 +70,16 @@ class Energy(NiftyMetaBase()): ... @@ -70,15 +70,16 @@ class Energy(NiftyMetaBase()): @property @property def position(self): def position(self): """ """ The Field location in parameter space where value, gradient and Field : selected location in parameter space curvature are evaluated. The Field location in parameter space where value, gradient and curvature are evaluated. """ """ return self._position return self._position @property @property def value(self): def value(self): """ """ float float : value of the functional The value of the energy functional at given position. The value of the energy functional at given position. """ """ raise NotImplementedError raise NotImplementedError ... @@ -86,8 +87,7 @@ class Energy(NiftyMetaBase()): ... @@ -86,8 +87,7 @@ class Energy(NiftyMetaBase()): @property @property def gradient(self): def gradient(self): """ """ Field Field : The gradient at given position. The gradient at given position. """ """ raise NotImplementedError raise NotImplementedError ... @@ -95,15 +95,14 @@ class Energy(NiftyMetaBase()): ... @@ -95,15 +95,14 @@ class Energy(NiftyMetaBase()): @memo @memo def gradient_norm(self): def gradient_norm(self): """ """ float float : L2-norm of the gradient at given position. The length of the gradient at given position. """ """ return self.gradient.norm() return self.gradient.norm() @property @property def curvature(self): def curvature(self): """ """ LinearOperator LinearOperator : implicitly defined curvature A positive semi-definite operator or function describing the A positive semi-definite operator or function describing the curvature of the potential at the given position. curvature of the potential at the given position. """ """ ... ...
 ... @@ -77,24 +77,21 @@ class LineEnergy(object): ... @@ -77,24 +77,21 @@ class LineEnergy(object): @property @property def energy(self): def energy(self): """ """ Energy Energy : The underlying Energy object The underlying Energy object """ """ return self._energy return self._energy @property @property def value(self): def value(self): """ """ float float : The value of the energy functional at given position. The value of the energy functional at given position. """ """ return self._energy.value return self._energy.value @property @property def directional_derivative(self): def directional_derivative(self): """ """ float float : The directional derivative at the given position. The directional derivative at the given position. """ """ res = self._energy.gradient.vdot(self._line_direction) res = self._energy.gradient.vdot(self._line_direction) if abs(res.imag) / max(abs(res.real), 1.) > 1e-12: if abs(res.imag) / max(abs(res.real), 1.) > 1e-12: ... ...
 ... @@ -42,6 +42,24 @@ class QuadraticEnergy(Energy): ... @@ -42,6 +42,24 @@ class QuadraticEnergy(Energy): return QuadraticEnergy(position=position, A=self._A, b=self._b) return QuadraticEnergy(position=position, A=self._A, b=self._b) def at_with_grad(self, position, grad): def at_with_grad(self, position, grad): """ Specialized version of at, taking also a gradient. This custom method is meant for use within :class:ConjugateGradient` minimizers, which already have the gradient available. It saves time by not recomputing it. Parameters ---------- position : Field Location in parameter space for the new Energy object. grad : Field Energy gradient at the new position. Returns ------- Energy Energy object at new position. """ return QuadraticEnergy(position=position, A=self._A, b=self._b, return QuadraticEnergy(position=position, A=self._A, b=self._b, _grad=grad) _grad=grad) ... ...