smoothness_operator.py 2.7 KB
Newer Older
1 2 3
from ...spaces.power_space import PowerSpace
from ..endomorphic_operator import EndomorphicOperator
from ..laplace_operator import LaplaceOperator
4 5 6


class SmoothnessOperator(EndomorphicOperator):
7 8
    """An operator measuring the smoothness on an irregular grid with respect
    to some scale.
Jakob Knollmueller's avatar
Jakob Knollmueller committed
9

10 11 12 13 14 15 16 17
    This operator applies the irregular LaplaceOperator and its adjoint to some
    Field over a PowerSpace which corresponds to its smoothness and weights the
    result with a scale parameter sigma. It is used in the smoothness prior
    terms of the CriticalPowerEnergy. For this purpose we use free boundary
    conditions in the LaplaceOperator, having no curvature at both ends. In
    addition the first entry is ignored as well, corresponding to the overall
    mean of the map. The mean is therefore not considered in the smoothness
    prior.
Jakob Knollmueller's avatar
Jakob Knollmueller committed
18 19 20 21


    Parameters
    ----------
22
    strength: float,
Jakob Knollmueller's avatar
Jakob Knollmueller committed
23 24 25 26 27
        Specifies the strength of the SmoothnessOperator
    logarithmic : boolean,
        Whether smoothness is calculated on a logarithmic scale or linear scale
        default : True
    """
28

29
    # ---Overwritten properties and methods---
30

31 32
    def __init__(self, domain, strength=1., logarithmic=True,
                 default_spaces=None):
33

34
        super(SmoothnessOperator, self).__init__(default_spaces=default_spaces)
35 36

        self._domain = self._parse_domain(domain)
Martin Reinecke's avatar
Martin Reinecke committed
37
        if len(self.domain) != 1:
38
            raise ValueError("The domain must contain exactly one PowerSpace.")
39

40 41 42
        if not isinstance(self.domain[0], PowerSpace):
            raise TypeError("The domain must contain exactly one PowerSpace.")

43
        if strength <= 0:
44 45
            raise ValueError("ERROR: invalid sigma.")

46
        self._strength = strength
47

48 49
        self._laplace = LaplaceOperator(domain=self.domain,
                                        logarithmic=logarithmic)
50

51
    # ---Mandatory properties and methods---
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72

    @property
    def target(self):
        return self._domain

    @property
    def domain(self):
        return self._domain

    @property
    def unitary(self):
        return False

    @property
    def symmetric(self):
        return False

    @property
    def self_adjoint(self):
        return False

73
    def _times(self, x, spaces):
74 75 76 77 78 79 80 81
        if self._strength != 0:
            result = self._laplace.adjoint_times(self._laplace(x, spaces),
                                                 spaces)
            result *= self._strength**2
        else:
            result = x.copy_empty()
            result.val[:] = 0
        return result
82 83 84

    # ---Added properties and methods---

85 86 87 88
    @property
    def logarithmic(self):
        return self._laplace.logarithmic

89
    @property
90 91
    def strength(self):
        return self._strength