endomorphic_operator.py 5.92 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 23 24 25

import abc

from nifty.operators.linear_operator import LinearOperator


class EndomorphicOperator(LinearOperator):

26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
    """NIFTY class for endomorphic operators.
    The  NIFTY EndomorphicOperator class is a class derived from the
    LinearOperator. Domain and target are the same in any EndomorphicOperator.
    Prominent other specific operator subclasses, in NIFTy are
    (e.g. DiagonalOperator, SmoothingOperator,
    PropagatorOperator).

    Parameters
    ----------

    Attributes
    ----------
    domain : NIFTy.space
        The NIFTy.space in which the operator is defined.
    target : NIFTy.space
        The NIFTy.space in which the outcome of the operator lives.
        As the Operator is endomorphic this is the same as its domain.
    self_adjoint : boolean
        Indicates whether the operator is self_adjoint or not

    Raises
    ------
    NotImplementedError
        Raised if
            * self_adjoint is not defined

    Notes
    -----

    Examples
    --------


    See Also
    --------
    DiagonalOperator, SmoothingOperator,
    PropagatorOperator

    """


67 68
    # ---Overwritten properties and methods---

69
    def inverse_times(self, x, spaces=None):
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
        """ Applies the inverse-Operator to a given Field.

        Operator and Field have to live over the same domain.

        Parameters
        ----------
        x : NIFTY.Field
            applies the Operator to the given Field
        spaces : integer (default: None)
            defines on which space of the given Field the Operator acts
        **kwargs
           Additional keyword arguments get passed to the used copy_empty
           routine.

        Returns
        -------
        out : NIFTy.Field
            the processed Field living on the domain space

        See Also
       --------

        """
Martin Reinecke's avatar
Martin Reinecke committed
93
        if self.self_adjoint and self.unitary:
94
            return self.times(x, spaces)
95 96 97
        else:
            return super(EndomorphicOperator, self).inverse_times(
                                                              x=x,
98
                                                              spaces=spaces)
99

100
    def adjoint_times(self, x, spaces=None):
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
        """ Applies the adjoint-Operator to a given Field.

        Operator and Field have to live over the same domain.

        Parameters
        ----------
        x : NIFTY.Field
            applies the Operator to the given Field
        spaces : integer (default: None)
            defines on which space of the given Field the Operator acts
        **kwargs
           Additional keyword arguments get passed to the used copy_empty
           routine.

        Returns
        -------
        out : NIFTy.Field
            the processed Field living on the domain space

        See Also
       --------

        """
Martin Reinecke's avatar
Martin Reinecke committed
124
        if self.self_adjoint:
125
            return self.times(x, spaces)
126 127 128
        else:
            return super(EndomorphicOperator, self).adjoint_times(
                                                                x=x,
129
                                                                spaces=spaces)
130

131
    def adjoint_inverse_times(self, x, spaces=None):
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
        """ Applies the adjoint-inverse-Operator to a given Field.

        Operator and Field have to live over the same domain.

        Parameters
        ----------
        x : NIFTY.Field
            applies the Operator to the given Field
        spaces : integer (default: None)
            defines on which space of the given Field the Operator acts
        **kwargs
           Additional keyword arguments get passed to the used copy_empty
           routine.

        Returns
        -------
        out : NIFTy.Field
            the processed Field living on the domain space

        See Also
       --------

        """
Martin Reinecke's avatar
Martin Reinecke committed
155
        if self.self_adjoint:
156
            return self.inverse_times(x, spaces)
157 158 159
        else:
            return super(EndomorphicOperator, self).adjoint_inverse_times(
                                                                x=x,
160
                                                                spaces=spaces)
161

162
    def inverse_adjoint_times(self, x, spaces=None):
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
        """ Applies the inverse-adjoint-Operator to a given Field.

        Operator and Field have to live over the same domain.

        Parameters
        ----------
        x : NIFTY.Field
            applies the Operator to the given Field
        spaces : integer (default: None)
            defines on which space of the given Field the Operator acts
        **kwargs
           Additional keyword arguments get passed to the used copy_empty
           routine.

        Returns
        -------
        out : NIFTy.Field
            the processed Field living on the domain space

        See Also
       --------

        """
Martin Reinecke's avatar
Martin Reinecke committed
186
        if self.self_adjoint:
187
            return self.inverse_times(x, spaces)
188 189 190
        else:
            return super(EndomorphicOperator, self).inverse_adjoint_times(
                                                                x=x,
191
                                                                spaces=spaces)
192 193 194 195 196 197 198 199 200 201

    # ---Mandatory properties and methods---

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

    # ---Added properties and methods---

    @abc.abstractproperty
Martin Reinecke's avatar
Martin Reinecke committed
202
    def self_adjoint(self):
203
        raise NotImplementedError