line_energy.py 3.86 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# NIFTy
# Copyright (C) 2017  Theo Steininger
#
# Author: Theo Steininger
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
19
20
21
22

from .energy import Energy


class LineEnergy(Energy):
23
24
25
26
    """ 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.
27
28
29
30
31

    Parameters
    ----------
    position : float
        The step length parameter along the given line direction.
Jakob Knollmueller's avatar
Jakob Knollmueller committed
32
    energy : Energy
33
34
35
36
37
38
39
        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).
40
41
42

    Attributes
    ----------
43
44
    position : float
        The position along the given line direction relative to the zero point.
45
    value : float
46
        The value of the energy functional at given `position`.
47
    gradient : float
48
49
        The gradient of the underlying energy instance along the line direction
        projected on the line direction.
50
    curvature : callable
51
52
        A positive semi-definite operator or function describing the curvature
        of the potential at given `position`.
Jakob Knollmueller's avatar
Jakob Knollmueller committed
53
    line_direction : Field
54
55
        Direction along which the movement is restricted. Does not have to be
        normalized.
56
    energy : Energy
57
        The underlying Energy at the `position` along the line direction.
58

Jakob Knollmueller's avatar
Jakob Knollmueller committed
59
60
61
62
    Raises
    ------
    NotImplementedError
        Raised if
63
64
            * value, gradient or curvature of the attribute energy are not
              implemented.
Jakob Knollmueller's avatar
Jakob Knollmueller committed
65
66
67

    Notes
    -----
68
69
70
71
    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.
72
73

    """
74

75
    def __init__(self, position, energy, line_direction, zero_point=None):
76
        super(LineEnergy, self).__init__(position=position)
77
78
79
80
81
82
83
84
        self.line_direction = line_direction

        if zero_point is None:
            zero_point = energy.position
        self._zero_point = zero_point

        position_on_line = self._zero_point + self.position*line_direction
        self.energy = energy.at(position=position_on_line)
85
86

    def at(self, position):
87
        """ Returns LineEnergy at new position, memorizing the zero point.
Jakob Knollmueller's avatar
Jakob Knollmueller committed
88
89
90
91

        Parameters
        ----------
        position : float
92
            Parameter for the new position on the line direction.
Jakob Knollmueller's avatar
Jakob Knollmueller committed
93
94
95
96

        Returns
        -------
        out : LineEnergy
97
            LineEnergy object at new position with same zero point as `self`.
Jakob Knollmueller's avatar
Jakob Knollmueller committed
98
99

        """
100

101
102
103
104
        return self.__class__(position,
                              self.energy,
                              self.line_direction,
                              zero_point=self._zero_point)
105
106
107
108
109
110
111
112
113
114
115
116

    @property
    def value(self):
        return self.energy.value

    @property
    def gradient(self):
        return self.energy.gradient.dot(self.line_direction)

    @property
    def curvature(self):
        return self.energy.curvature