quadratic_energy.py 1.05 KB
Newer Older
Martin Reinecke's avatar
Martin Reinecke committed
1
2
3
4
5
6
from nifty.energies.energy import Energy
from nifty.energies.memoization import memo


class QuadraticEnergy(Energy):
    """The Energy for a quadratic form.
Martin Reinecke's avatar
Martin Reinecke committed
7
8
    The most important aspect of this energy is that its curvature must be
    position-independent.
Martin Reinecke's avatar
Martin Reinecke committed
9
10
    """

Martin Reinecke's avatar
tweaks    
Martin Reinecke committed
11
    def __init__(self, position, A, b, grad=None):
Martin Reinecke's avatar
Martin Reinecke committed
12
13
14
        super(QuadraticEnergy, self).__init__(position=position)
        self._A = A
        self._b = b
Martin Reinecke's avatar
tweaks    
Martin Reinecke committed
15
16
17
18
        if grad is not None:
            self._Ax = grad + self._b
        else:
            self._Ax = self._A(self.position)
Martin Reinecke's avatar
Martin Reinecke committed
19
20
21
22

    def at(self, position):
        return self.__class__(position=position, A=self._A, b=self._b)

Martin Reinecke's avatar
tweaks    
Martin Reinecke committed
23
24
25
26
    def at_with_grad(self, position, grad):
        return self.__class__(position=position, A=self._A, b=self._b,
                              grad=grad)

Martin Reinecke's avatar
Martin Reinecke committed
27
28
29
30
31
32
33
34
35
36
37
38
39
    @property
    @memo
    def value(self):
        return 0.5*self.position.vdot(self._Ax) - self._b.vdot(self.position)

    @property
    @memo
    def gradient(self):
        return self._Ax - self._b

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