Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ift
NIFTy
Commits
7abbc7e0
Commit
7abbc7e0
authored
May 18, 2017
by
Martin Reinecke
Browse files
Merge branch 'master' into spherical_plots
parents
22462850
8a0939fe
Pipeline
#12616
passed with stage
in 7 minutes and 15 seconds
Changes
10
Pipelines
1
Hide whitespace changes
Inline
Sidebyside
.gitignore
View file @
7abbc7e0
*.html
# custom
setup.cfg
.idea
.DS_Store
# from https://github.com/github/gitignore/blob/master/Python.gitignore
# Bytecompiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.c
*.o
*.so
*.pyc
*.log
# Distribution / packaging
.Python
env/
build/
developeggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egginfo/
.installed.cfg
*.egg
*.egginfo
*~
.git/
.svn/
.spyderproject
.documen
t
build
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifes
t
*.spec
.idea
# Installer logs
piplog.txt
pipdeletethisdirectory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
.hypothesis/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
# Flask stuff:
instance/
.webassetscache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# IPython Notebook
.ipynb_checkpoints
# pyenv
.pythonversion
# celery beat schedule file
celerybeatschedule
# dotenv
.env
# virtualenv
venv/
ENV/
# Spyder project settings
.spyderproject
# Rope project settings
.ropeproject
\ No newline at end of file
nifty/energies/energy.py
View file @
7abbc7e0
...
...
@@ 22,6 +22,47 @@ from keepers import Loggable
class
Energy
(
Loggable
,
object
):
""" Provides the functional used by minimization schemes.
The Energy object is an implementation of a scalar function including its
gradient and curvature at some position.
Parameters

position : Field
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` in parameter direction.
curvature : LinearOperator, callable
A positive semidefinite operator or function describing the curvature
of the potential at the given `position`.
Notes

An instance of the Energy class is defined at a certain location. If one
is interested in the value, gradient or curvature of the abstract energy
functional one has to 'jump' to the new position using the `at` method.
This method returns a new energy instance residing at the new position. By
this approach, intermediate results from computing e.g. the gradient can
safely be reused for e.g. the value or the curvature.
Memorizing the evaluations of some quantities (using the memo decorator)
minimizes the computational effort for multiple calls.
See also

memo
"""
__metaclass__
=
NiftyMeta
def
__init__
(
self
,
position
):
...
...
@@ 33,20 +74,56 @@ class Energy(Loggable, object):
self
.
_position
=
position
def
at
(
self
,
position
):
""" Initializes and returns a new Energy object at the new position.
Parameters

position : Field
Parameter for the new Energy object.
Returns

out : Energy
Energy object at new position.
"""
return
self
.
__class__
(
position
)
@
property
def
position
(
self
):
"""
The Field location in parameter space where value, gradient and
curvature are evaluated.
"""
return
self
.
_position
@
property
def
value
(
self
):
"""
The value of the energy functional at given `position`.
"""
raise
NotImplementedError
@
property
def
gradient
(
self
):
"""
The gradient at given `position` in parameter direction.
"""
raise
NotImplementedError
@
property
def
curvature
(
self
):
"""
A positive semidefinite operator or function describing the curvature
of the potential at the given `position`.
"""
raise
NotImplementedError
nifty/energies/line_energy.py
View file @
7abbc7e0
...
...
@@ 20,6 +20,58 @@ from .energy import Energy
class
LineEnergy
(
Energy
):
""" Evaluates an underlying Energy along a certain line direction.
Given an Energy class and a line direction, its position is parametrized by
a scalar step size along the descent direction relative to a zero point.
Parameters

position : float
The step length parameter along the given line direction.
energy : Energy
The Energy object which will be evaluated along the given direction.
line_direction : Field
Direction used for line evaluation.
zero_point : Field *optional*
Fixing the zero point of the line restriction. Used to memorize this
position in new initializations. By the default the current position
of the supplied `energy` instance is used (default : None).
Attributes

position : float
The position along the given line direction relative to the zero point.
value : float
The value of the energy functional at given `position`.
gradient : float
The gradient of the underlying energy instance along the line direction
projected on the line direction.
curvature : callable
A positive semidefinite operator or function describing the curvature
of the potential at 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 `position` along the line direction.
Raises

NotImplementedError
Raised if
* value, gradient or curvature of the attribute energy are not
implemented.
Notes

The LineEnergy is used in minimization schemes in order perform line
searches. It describes an underlying Energy which is restricted along one
direction, only requiring the step size parameter to determine a new
position.
"""
def
__init__
(
self
,
position
,
energy
,
line_direction
,
zero_point
=
None
):
super
(
LineEnergy
,
self
).
__init__
(
position
=
position
)
self
.
line_direction
=
line_direction
...
...
@@ 32,6 +84,20 @@ class LineEnergy(Energy):
self
.
energy
=
energy
.
at
(
position
=
position_on_line
)
def
at
(
self
,
position
):
""" Returns LineEnergy at new position, memorizing the zero point.
Parameters

position : float
Parameter for the new position on the line direction.
Returns

out : LineEnergy
LineEnergy object at new position with same zero point as `self`.
"""
return
self
.
__class__
(
position
,
self
.
energy
,
self
.
line_direction
,
...
...
nifty/minimization/conjugate_gradient.py
View file @
7abbc7e0
...
...
@@ 23,32 +23,62 @@ from keepers import Loggable
class
ConjugateGradient
(
Loggable
,
object
):
""" Implementation of the Conjugate Gradient scheme.
It is an iterative method for solving a linear system of equations:
Ax = b
Parameters

convergence_tolerance : float *optional*
Tolerance specifying the case of convergence. (default: 1E4)
convergence_level : integer *optional*
Number of times the tolerance must be undershot before convergence
is reached. (default: 3)
iteration_limit : integer *optional*
Maximum number of iterations performed (default: None).
reset_count : integer *optional*
Number of iterations after which to restart; i.e., forget previous
conjugated directions (default: None).
preconditioner : Operator *optional*
This operator can be provided which transforms the variables of the
system to improve the conditioning (default: None).
callback : callable *optional*
Function f(energy, iteration_number) supplied by the user to perform
insitu analysis at every iteration step. When being called the
current energy and iteration_number are passed. (default: None)
Attributes

convergence_tolerance : float
Tolerance specifying the case of convergence.
convergence_level : integer
Number of times the tolerance must be undershot before convergence
is reached. (default: 3)
iteration_limit : integer
Maximum number of iterations performed.
reset_count : integer
Number of iterations after which to restart; i.e., forget previous
conjugated directions.
preconditioner : function
This operator can be provided which transforms the variables of the
system to improve the conditioning (default: None).
callback : callable
Function f(energy, iteration_number) supplied by the user to perform
insitu analysis at every iteration step. When being called the
current energy and iteration_number are passed. (default: None)
References

Thomas V. Mikosch et al., "Numerical Optimization", Second Edition,
2006, SpringerVerlag New York
"""
def
__init__
(
self
,
convergence_tolerance
=
1E4
,
convergence_level
=
3
,
iteration_limit
=
None
,
reset_count
=
None
,
preconditioner
=
None
,
callback
=
None
):
"""
Initializes the conjugate_gradient and sets the attributes (except
for `x`).
Parameters

A : {operator, function}
Operator `A` applicable to a field.
b : field
Resulting field of the operation `A(x)`.
W : {operator, function}, *optional*
Operator `W` that is a preconditioner on `A` and is applicable to a
field (default: None).
spam : function, *optional*
Callback function which is given the current `x` and iteration
counter each iteration (default: None).
reset : integer, *optional*
Number of iterations after which to restart; i.e., forget previous
conjugated directions (default: sqrt(b.dim)).
note : bool, *optional*
Indicates whether notes are printed or not (default: False).
"""
self
.
convergence_tolerance
=
np
.
float
(
convergence_tolerance
)
self
.
convergence_level
=
np
.
float
(
convergence_level
)
...
...
@@ 67,31 +97,28 @@ class ConjugateGradient(Loggable, object):
self
.
callback
=
callback
def
__call__
(
self
,
A
,
b
,
x0
):
"""
Runs the conjugate gradient minimization.
Parameters

x0 : field, *optional*
Starting guess for the minimization.
tol : scalar, *optional*
Tolerance specifying convergence; measured by current relative
residual (default: 1E4).
clevel : integer, *optional*
Number of times the tolerance should be undershot before
exiting (default: 1).
limii : integer, *optional*
Maximum number of iterations performed (default: 10 * b.dim).
Returns

x : field
Latest `x` of the minimization.
convergence : integer
Latest convergence level indicating whether the minimization
has converged or not.
""" Runs the conjugate gradient minimization.
For `Ax = b` the variable `x` is infered.
Parameters

A : Operator
Operator `A` applicable to a Field.
b : Field
Result of the operation `A(x)`.
x0 : Field
Starting guess for the minimization.
Returns

x : Field
Latest `x` of the minimization.
convergence : integer
Latest convergence level indicating whether the minimization
has converged or not.
"""
r
=
b

A
(
x0
)
d
=
self
.
preconditioner
(
r
)
previous_gamma
=
r
.
dot
(
d
)
...
...
nifty/minimization/descent_minimizer.py
View file @
7abbc7e0
...
...
@@ 27,6 +27,56 @@ from .line_searching import LineSearchStrongWolfe
class
DescentMinimizer
(
Loggable
,
object
):
""" A base class used by gradient methods to find a local minimum.
Descent minimization methods are used to find a local minimum of a scalar
function by following a descent direction. This class implements the
minimization procedure once a descent direction is known. The descent
direction has to be implemented separately.
Parameters

line_searcher : callable *optional*
Function which infers the step size in the descent direction
(default : LineSearchStrongWolfe()).
callback : callable *optional*
Function f(energy, iteration_number) supplied by the user to perform
insitu analysis at every iteration step. When being called the
current energy and iteration_number are passed. (default: None)
convergence_tolerance : float *optional*
Tolerance specifying the case of convergence. (default: 1E4)
convergence_level : integer *optional*
Number of times the tolerance must be undershot before convergence
is reached. (default: 3)
iteration_limit : integer *optional*
Maximum number of iterations performed (default: None).
Attributes

convergence_tolerance : float
Tolerance specifying the case of convergence.
convergence_level : integer
Number of times the tolerance must be undershot before convergence
is reached. (default: 3)
iteration_limit : integer
Maximum number of iterations performed.
line_searcher : LineSearch
Function which infers the optimal step size for functional minization
given a descent direction.
callback : function
Function f(energy, iteration_number) supplied by the user to perform
insitu analysis at every iteration step. When being called the
current energy and iteration_number are passed.
Notes

The callback function can be used to externally stop the minimization by
raising a `StopIteration` exception.
Check `get_descent_direction` of a derived class for information on the
concrete minization scheme.
"""
__metaclass__
=
NiftyMeta
def
__init__
(
self
,
line_searcher
=
LineSearchStrongWolfe
(),
callback
=
None
,
...
...
@@ 34,7 +84,7 @@ class DescentMinimizer(Loggable, object):
iteration_limit
=
None
):
self
.
convergence_tolerance
=
np
.
float
(
convergence_tolerance
)
self
.
convergence_level
=
np
.
floa
t
(
convergence_level
)
self
.
convergence_level
=
np
.
in
t
(
convergence_level
)
if
iteration_limit
is
not
None
:
iteration_limit
=
int
(
iteration_limit
)
...
...
@@ 44,32 +94,30 @@ class DescentMinimizer(Loggable, object):
self
.
callback
=
callback
def
__call__
(
self
,
energy
):
"""
Runs the steepest descent minimization.
Parameters

x0 : field
Starting guess for the minimization.
alpha : scalar, *optional*
Starting step width to be multiplied with normalized gradient
(default: 1).
tol : scalar, *optional*
Tolerance specifying convergence; measured by maximal change in
`x` (default: 1E4).
clevel : integer, *optional*
Number of times the tolerance should be undershot before
exiting (default: 8).
self.iteration_limit : integer, *optional*
Maximum number of iterations performed (default: 100,000).
Returns

x : field
Latest `x` of the minimization.
convergence : integer
Latest convergence level indicating whether the minimization
has converged or not.
""" Performs the minimization of the provided Energy functional.
Parameters

energy : Energy object
Energy object which provides value, gradient and curvature at a
specific position in parameter space.
Returns

energy : Energy object
Latest `energy` of the minimization.
convergence : integer
Latest convergence level indicating whether the minimization
has converged or not.
Note

The minimization is stopped if
* the callback function raises a `StopIteration` exception,
* a perfectly flat point is reached,
* according to the linesearch the minimum is found,
* the target convergence level is reached,
* the iteration limit is reached.
"""
...
...
@@ 98,7 +146,7 @@ class DescentMinimizer(Loggable, object):
break
# current position is encoded in energy object
descend_direction
=
self
.
_
get_descend_direction
(
energy
)
descend_direction
=
self
.
get_descend_direction
(
energy
)
# compute the step length, which minimizes energy.value along the
# search direction
...
...
@@ 140,5 +188,5 @@ class DescentMinimizer(Loggable, object):
return
energy
,
convergence
@
abc
.
abstractmethod
def
_
get_descend_direction
(
self
,
energy
):
def
get_descend_direction
(
self
,
energy
):
raise
NotImplementedError
nifty/minimization/line_searching/line_search.py
View file @
7abbc7e0
...
...
@@ 24,50 +24,47 @@ from nifty import LineEnergy
class
LineSearch
(
Loggable
,
object
):
"""Class for determining the optimal step size along some descent direction.
Initialize the line search procedure which can be used by a specific line
search method. Its finds the step size in a specific direction in the
minimization process.
Attributes

line_energy : LineEnergy Object
LineEnergy object from which we can extract energy at a specific point.
f_k_minus_1 : Field
Value of the field at the k1 iteration of the line search procedure.
prefered_initial_step_size : float
Initial guess for the step length.
"""
Class for finding a step size.
"""
__metaclass__
=
abc
.
ABCMeta
def
__init__
(
self
):
"""
Parameters

f : callable f(x, *args)
Objective function.
fprime : callable f'(x, *args)
Objective functions gradient.
f_args : tuple (optional)
Additional arguments passed to objective function and its
derivation.
"""
self
.
line_energy
=
None
self
.
f_k_minus_1
=
None
self
.
prefered_initial_step_size
=
None
def
_set_line_energy
(
self
,
energy
,
pk
,
f_k_minus_1
=
None
):
"""
Set the coordinates for a new line search.
"""Set the coordinates for a new line search.
Parameters

xk : ndarray, d2o, field
Starting point.
pk : ndarray, d2o, field
Unit vector in search direction.
f_k : float (optional)
Function value f(x_k).
fprime_k : ndarray, d2o, field (optional)
Function value fprime(xk).
energy : Energy object
Energy object from which we can calculate the energy, gradient and
curvature at a specific point.
pk : Field
Unit vector pointing into the search direction.
f_k_minus_1 : float