relaxed_sum_operator.py 2.11 KB
Newer Older
Martin Reinecke's avatar
more    
Martin Reinecke committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 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/>.
#
# Copyright(C) 2013-2018 Max-Planck-Society
#
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik
# and financially supported by the Studienstiftung des deutschen Volkes.

from __future__ import absolute_import, division, print_function

import numpy as np

from ..compat import *
from ..utilities import my_sum
from .linear_operator import LinearOperator
Martin Reinecke's avatar
more    
Martin Reinecke committed
26
from ..sugar import domain_union
Martin Reinecke's avatar
more    
Martin Reinecke committed
27
from ..multi.multi_domain import MultiDomain
Martin Reinecke's avatar
more    
Martin Reinecke committed
28
from ..multi.multi_field import MultiField
Martin Reinecke's avatar
more    
Martin Reinecke committed
29
30
31


class RelaxedSumOperator(LinearOperator):
Martin Reinecke's avatar
more    
Martin Reinecke committed
32
    """Class representing sums of operators with compatible domains."""
Martin Reinecke's avatar
more    
Martin Reinecke committed
33
34
35
36

    def __init__(self, ops):
        super(RelaxedSumOperator, self).__init__()
        self._ops = ops
Martin Reinecke's avatar
more    
Martin Reinecke committed
37
38
        self._domain = domain_union([op.domain for op in ops])
        self._target = domain_union([op.target for op in ops])
Martin Reinecke's avatar
more    
Martin Reinecke committed
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
        self._capability = self.TIMES | self.ADJOINT_TIMES
        for op in ops:
            self._capability &= op.capability

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

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

    @property
    def adjoint(self):
        return RelaxedSumOperator([op.adjoint for op in self._ops])

    @property
    def capability(self):
        return self._capability

    def apply(self, x, mode):
        self._check_mode(mode)
        res = None
        for op in self._ops:
Martin Reinecke's avatar
Martin Reinecke committed
63
64
            tmp = op.apply(x.extract(op._dom(mode)), mode)
            res = tmp if res is None else res.unite(tmp)
Martin Reinecke's avatar
more    
Martin Reinecke committed
65
        return res