Commit eb3a20e3 authored by Martin Reinecke's avatar Martin Reinecke
Browse files

more docs

parent 59a5251e
Pipeline #25039 passed with stages
in 6 minutes and 42 seconds
...@@ -7,18 +7,25 @@ Description of Minimization ...@@ -7,18 +7,25 @@ Description of Minimization
:maxdepth: 1 :maxdepth: 1
:caption: Minimization Concepts :caption: Minimization Concepts
Conjugate Gradient <../mod/nifty4.minimization.conjugate_gradient>
Descent Minimizer <../mod/nifty4.minimization.descent_minimizer>
Energy <../mod/nifty4.minimization.energy> Energy <../mod/nifty4.minimization.energy>
Iteration Controller <../mod/nifty4.minimization.iteration_controller> QuadraticEnergy <../mod/nifty4.minimization.quadratic_energy>
Line Energy <../mod/nifty4.minimization.line_energy>
Line Search <../mod/nifty4.minimization.line_search> IterationController <../mod/nifty4.minimization.iteration_controller>
Line Search Strong Wolfe <../mod/nifty4.minimization.line_search_strong_wolfe> GradientNormController <../mod/nifty4.minimization.gradient_norm_controller>
Minimizer <../mod/nifty4.minimization.minimizer> Minimizer <../mod/nifty4.minimization.minimizer>
Nonlinear Cg <../mod/nifty4.minimization.nonlinear_cg>
Quadratic Energy <../mod/nifty4.minimization.quadratic_energy> ConjugateGradient <../mod/nifty4.minimization.conjugate_gradient>
Relaxed Newton <../mod/nifty4.minimization.relaxed_newton> NonlinearCG <../mod/nifty4.minimization.nonlinear_cg>
Scipy Minimizer <../mod/nifty4.minimization.scipy_minimizer>
Steepest Descent <../mod/nifty4.minimization.steepest_descent> ScipyMinimizer <../mod/nifty4.minimization.scipy_minimizer>
VL BFGS <../mod/nifty4.minimization.vl_bfgs>
Gradient Norm Controller <../mod/nifty4.minimization.gradient_norm_controller> LineEnergy <../mod/nifty4.minimization.line_energy>
LineSearch <../mod/nifty4.minimization.line_search>
LineSearchStrongWolfe <../mod/nifty4.minimization.line_search_strong_wolfe>
DescentMinimizer <../mod/nifty4.minimization.descent_minimizer>
SteepestDescent <../mod/nifty4.minimization.steepest_descent>
RelaxedNewton <../mod/nifty4.minimization.relaxed_newton>
VL_BFGS <../mod/nifty4.minimization.vl_bfgs>
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
# Copyright(C) 2013-2017 Max-Planck-Society # Copyright(C) 2013-2018 Max-Planck-Society
# #
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik # NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik
# and financially supported by the Studienstiftung des deutschen Volkes. # and financially supported by the Studienstiftung des deutschen Volkes.
...@@ -50,7 +50,7 @@ class DescentMinimizer(Minimizer): ...@@ -50,7 +50,7 @@ class DescentMinimizer(Minimizer):
Parameters Parameters
---------- ----------
nergy : Energy energy : Energy
Energy object which provides value, gradient and curvature at a Energy object which provides value, gradient and curvature at a
specific position in parameter space. specific position in parameter space.
...@@ -105,4 +105,17 @@ class DescentMinimizer(Minimizer): ...@@ -105,4 +105,17 @@ class DescentMinimizer(Minimizer):
@abc.abstractmethod @abc.abstractmethod
def get_descent_direction(self, energy): def get_descent_direction(self, energy):
""" Calculates the next descent direction.
Parameters
----------
energy : Energy
An instance of the Energy class which shall be minimized. The
position of `energy` is used as the starting point of minimization.
Returns
-------
Field
The descent direction.
"""
raise NotImplementedError raise NotImplementedError
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
# Copyright(C) 2013-2017 Max-Planck-Society # Copyright(C) 2013-2018 Max-Planck-Society
# #
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik # NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik
# and financially supported by the Studienstiftung des deutschen Volkes. # and financially supported by the Studienstiftung des deutschen Volkes.
...@@ -31,19 +31,6 @@ class Energy(with_metaclass(NiftyMeta, type('NewBase', (object,), {}))): ...@@ -31,19 +31,6 @@ class Energy(with_metaclass(NiftyMeta, type('NewBase', (object,), {}))):
position : Field position : Field
The input parameter of the scalar function. The input parameter of the scalar function.
Attributes
----------
position : Field
The Field location in parameter space where value, gradient and
curvature are evaluated.
value : np.float
The value of the energy functional at given `position`.
gradient : Field
The gradient at given `position`.
curvature : LinearOperator, callable
A positive semi-definite operator or function describing the curvature
of the potential at the given `position`.
Notes Notes
----- -----
An instance of the Energy class is defined at a certain location. If one An instance of the Energy class is defined at a certain location. If one
...@@ -76,7 +63,7 @@ class Energy(with_metaclass(NiftyMeta, type('NewBase', (object,), {}))): ...@@ -76,7 +63,7 @@ class Energy(with_metaclass(NiftyMeta, type('NewBase', (object,), {}))):
Returns Returns
------- -------
out : Energy Energy
Energy object at new position. Energy object at new position.
""" """
return self.__class__(position) return self.__class__(position)
...@@ -92,6 +79,7 @@ class Energy(with_metaclass(NiftyMeta, type('NewBase', (object,), {}))): ...@@ -92,6 +79,7 @@ class Energy(with_metaclass(NiftyMeta, type('NewBase', (object,), {}))):
@property @property
def value(self): def value(self):
""" """
float
The value of the energy functional at given `position`. The value of the energy functional at given `position`.
""" """
raise NotImplementedError raise NotImplementedError
...@@ -99,6 +87,7 @@ class Energy(with_metaclass(NiftyMeta, type('NewBase', (object,), {}))): ...@@ -99,6 +87,7 @@ class Energy(with_metaclass(NiftyMeta, type('NewBase', (object,), {}))):
@property @property
def gradient(self): def gradient(self):
""" """
Field
The gradient at given `position`. The gradient at given `position`.
""" """
raise NotImplementedError raise NotImplementedError
...@@ -107,6 +96,7 @@ class Energy(with_metaclass(NiftyMeta, type('NewBase', (object,), {}))): ...@@ -107,6 +96,7 @@ class Energy(with_metaclass(NiftyMeta, type('NewBase', (object,), {}))):
@memo @memo
def gradient_norm(self): def gradient_norm(self):
""" """
float
The length of the gradient at given `position`. The length of the gradient at given `position`.
""" """
return self.gradient.norm() return self.gradient.norm()
...@@ -114,7 +104,8 @@ class Energy(with_metaclass(NiftyMeta, type('NewBase', (object,), {}))): ...@@ -114,7 +104,8 @@ class Energy(with_metaclass(NiftyMeta, type('NewBase', (object,), {}))):
@property @property
def curvature(self): def curvature(self):
""" """
A positive semi-definite operator or function describing the curvature LinearOperator
of the potential at the given `position`. A positive semi-definite operator or function describing the
curvature of the potential at the given `position`.
""" """
raise NotImplementedError raise NotImplementedError
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
# Copyright(C) 2013-2017 Max-Planck-Society # Copyright(C) 2013-2018 Max-Planck-Society
# #
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik # NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik
# and financially supported by the Studienstiftung des deutschen Volkes. # and financially supported by the Studienstiftung des deutschen Volkes.
...@@ -37,34 +37,12 @@ class LineEnergy(object): ...@@ -37,34 +37,12 @@ class LineEnergy(object):
energy.position = zero_point + offset*line_direction energy.position = zero_point + offset*line_direction
(default : 0.). (default : 0.).
Attributes
----------
line_position : float
The position along the given line direction relative to the zero point.
value : float
The value of the energy functional at the given position
directional_derivative : float
The directional derivative at the given position
line_direction : Field
Direction along which the movement is restricted. Does not have to be
normalized.
energy : Energy
The underlying Energy at the given position
Raises
------
NotImplementedError
Raised if
* value, gradient or curvature of the attribute energy are not
implemented.
Notes Notes
----- -----
The LineEnergy is used in minimization schemes in order perform line The LineEnergy is used in minimization schemes in order perform line
searches. It describes an underlying Energy which is restricted along one searches. It describes an underlying Energy which is restricted along one
direction, only requiring the step size parameter to determine a new direction, only requiring the step size parameter to determine a new
position. position.
""" """
def __init__(self, line_position, energy, line_direction, offset=0.): def __init__(self, line_position, energy, line_direction, offset=0.):
...@@ -73,11 +51,11 @@ class LineEnergy(object): ...@@ -73,11 +51,11 @@ class LineEnergy(object):
self._line_direction = line_direction self._line_direction = line_direction
if self._line_position == float(offset): if self._line_position == float(offset):
self.energy = energy self._energy = energy
else: else:
pos = energy.position \ pos = energy.position \
+ (self._line_position-float(offset))*self._line_direction + (self._line_position-float(offset))*self._line_direction
self.energy = energy.at(position=pos) self._energy = energy.at(position=pos)
def at(self, line_position): def at(self, line_position):
""" Returns LineEnergy at new position, memorizing the zero point. """ Returns LineEnergy at new position, memorizing the zero point.
...@@ -93,24 +71,32 @@ class LineEnergy(object): ...@@ -93,24 +71,32 @@ class LineEnergy(object):
""" """
return LineEnergy(line_position, self.energy, self.line_direction, return LineEnergy(line_position, self._energy, self._line_direction,
offset=self.line_position) offset=self._line_position)
@property @property
def value(self): def energy(self):
return self.energy.value """
Energy
@property The underlying Energy object
def line_position(self): """
return self._line_position return self._energy
@property @property
def line_direction(self): def value(self):
return self._line_direction """
float
The value of the energy functional at given `position`.
"""
return self._energy.value
@property @property
def directional_derivative(self): def directional_derivative(self):
res = self.energy.gradient.vdot(self.line_direction) """
float
The directional derivative at the given `position`.
"""
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:
from ..dobj import mprint from ..dobj import mprint
mprint("directional derivative has non-negligible " mprint("directional derivative has non-negligible "
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
# Copyright(C) 2013-2017 Max-Planck-Society # Copyright(C) 2013-2018 Max-Planck-Society
# #
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik # NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik
# and financially supported by the Studienstiftung des deutschen Volkes. # and financially supported by the Studienstiftung des deutschen Volkes.
...@@ -30,7 +30,7 @@ class Minimizer(with_metaclass(NiftyMeta, type('NewBase', (object,), {}))): ...@@ -30,7 +30,7 @@ class Minimizer(with_metaclass(NiftyMeta, type('NewBase', (object,), {}))):
Parameters Parameters
---------- ----------
energy : Energy object energy : Energy
Energy object which provides value, gradient and curvature at a Energy object which provides value, gradient and curvature at a
specific position in parameter space. specific position in parameter space.
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
# Copyright(C) 2013-2017 Max-Planck-Society # Copyright(C) 2013-2018 Max-Planck-Society
# #
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik # NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik
# and financially supported by the Studienstiftung des deutschen Volkes. # and financially supported by the Studienstiftung des deutschen Volkes.
...@@ -21,6 +21,11 @@ from .line_search_strong_wolfe import LineSearchStrongWolfe ...@@ -21,6 +21,11 @@ from .line_search_strong_wolfe import LineSearchStrongWolfe
class RelaxedNewton(DescentMinimizer): class RelaxedNewton(DescentMinimizer):
""" Calculates the descent direction according to a Newton scheme.
The descent direction is determined by weighting the gradient at the
current parameter position with the inverse local curvature.
"""
def __init__(self, controller, line_searcher=LineSearchStrongWolfe()): def __init__(self, controller, line_searcher=LineSearchStrongWolfe()):
super(RelaxedNewton, self).__init__(controller=controller, super(RelaxedNewton, self).__init__(controller=controller,
line_searcher=line_searcher) line_searcher=line_searcher)
...@@ -28,23 +33,4 @@ class RelaxedNewton(DescentMinimizer): ...@@ -28,23 +33,4 @@ class RelaxedNewton(DescentMinimizer):
self.line_searcher.preferred_initial_step_size = 1. self.line_searcher.preferred_initial_step_size = 1.
def get_descent_direction(self, energy): def get_descent_direction(self, energy):
""" Calculates the descent direction according to a Newton scheme.
The descent direction is determined by weighting the gradient at the
current parameter position with the inverse local curvature, provided
by the Energy object.
Parameters
----------
energy : Energy
An instance of the Energy class which shall be minized. The
position of `energy` is used as the starting point of minization.
Returns
-------
descent_direction : Field
Returns the descent direction with proposed step length. In a
quadratic potential this corresponds to the optimal step.
"""
return -energy.curvature.inverse_times(energy.gradient) return -energy.curvature.inverse_times(energy.gradient)
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
# Copyright(C) 2013-2017 Max-Planck-Society # Copyright(C) 2013-2018 Max-Planck-Society
# #
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik # NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik
# and financially supported by the Studienstiftung des deutschen Volkes. # and financially supported by the Studienstiftung des deutschen Volkes.
......
...@@ -12,7 +12,7 @@ from __future__ import division ...@@ -12,7 +12,7 @@ from __future__ import division
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
# Copyright(C) 2013-2017 Max-Planck-Society # Copyright(C) 2013-2018 Max-Planck-Society
# #
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik # NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik
# and financially supported by the Studienstiftung des deutschen Volkes. # and financially supported by the Studienstiftung des deutschen Volkes.
...@@ -22,21 +22,10 @@ from .descent_minimizer import DescentMinimizer ...@@ -22,21 +22,10 @@ from .descent_minimizer import DescentMinimizer
class SteepestDescent(DescentMinimizer): class SteepestDescent(DescentMinimizer):
def get_descent_direction(self, energy):
""" Implementation of the steepest descent minimization scheme. """ Implementation of the steepest descent minimization scheme.
Also known as 'gradient descent'. This algorithm simply follows the Also known as 'gradient descent'. This algorithm simply follows the
functional's gradient for minization. functional's gradient for minimization.
Parameters
----------
energy : Energy
An instance of the Energy class which shall be minized. The
position of `energy` is used as the starting point of minization.
Returns
-------
descent_direction : Field
the descent direction.
""" """
def get_descent_direction(self, energy):
return -energy.gradient return -energy.gradient
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
# Copyright(C) 2013-2017 Max-Planck-Society # Copyright(C) 2013-2018 Max-Planck-Society
# #
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik # NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik
# and financially supported by the Studienstiftung des deutschen Volkes. # and financially supported by the Studienstiftung des deutschen Volkes.
...@@ -25,17 +25,6 @@ from .line_search_strong_wolfe import LineSearchStrongWolfe ...@@ -25,17 +25,6 @@ from .line_search_strong_wolfe import LineSearchStrongWolfe
class VL_BFGS(DescentMinimizer): class VL_BFGS(DescentMinimizer):
def __init__(self, controller, line_searcher=LineSearchStrongWolfe(),
max_history_length=5):
super(VL_BFGS, self).__init__(controller=controller,
line_searcher=line_searcher)
self.max_history_length = max_history_length
def __call__(self, energy):
self._information_store = None
return super(VL_BFGS, self).__call__(energy)
def get_descent_direction(self, energy):
"""Implementation of the Vector-free L-BFGS minimization scheme. """Implementation of the Vector-free L-BFGS minimization scheme.
Find the descent direction by using the inverse Hessian. Find the descent direction by using the inverse Hessian.
...@@ -44,33 +33,31 @@ class VL_BFGS(DescentMinimizer): ...@@ -44,33 +33,31 @@ class VL_BFGS(DescentMinimizer):
Hessian product. The updates are represented in a new basis to optimize Hessian product. The updates are represented in a new basis to optimize
the algorithm. the algorithm.
Parameters
----------
energy : Energy
An instance of the Energy class which shall be minized. The
position of `energy` is used as the starting point of minization.
Returns
-------
descent_direction : Field
Returns the descent direction.
References References
---------- ----------
W. Chen, Z. Wang, J. Zhou, "Large-scale L-BFGS using MapReduce", 2014, W. Chen, Z. Wang, J. Zhou, "Large-scale L-BFGS using MapReduce", 2014,
Microsoft Microsoft
""" """
def __init__(self, controller, line_searcher=LineSearchStrongWolfe(),
max_history_length=5):
super(VL_BFGS, self).__init__(controller=controller,
line_searcher=line_searcher)
self.max_history_length = max_history_length
def __call__(self, energy):
self._information_store = None
return super(VL_BFGS, self).__call__(energy)
def get_descent_direction(self, energy):
x = energy.position x = energy.position
gradient = energy.gradient gradient = energy.gradient
# initialize the information store if it doesn't already exist # initialize the information store if it doesn't already exist
try: try:
self._information_store.add_new_point(x, gradient) self._information_store.add_new_point(x, gradient)
except AttributeError: except AttributeError:
self._information_store = InformationStore(self.max_history_length, self._information_store = _InformationStore(
x0=x, self.max_history_length, x0=x, gradient=gradient)
gradient=gradient)
b = self._information_store.b b = self._information_store.b
delta = self._information_store.delta delta = self._information_store.delta
...@@ -82,7 +69,7 @@ class VL_BFGS(DescentMinimizer): ...@@ -82,7 +69,7 @@ class VL_BFGS(DescentMinimizer):
return descent_direction return descent_direction
class InformationStore(object): class _InformationStore(object):
"""Class for storing a list of past updates. """Class for storing a list of past updates.
Parameters Parameters
......
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