domain.py 3.34 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
# 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/>.
Theo Steininger's avatar
Theo Steininger committed
13
#
14
# Copyright(C) 2013-2019 Max-Planck-Society
Theo Steininger's avatar
Theo Steininger committed
15
#
16
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik.
Philipp Arras's avatar
Philipp Arras committed
17

Martin Reinecke's avatar
Martin Reinecke committed
18
from functools import reduce
Martin Reinecke's avatar
Martin Reinecke committed
19
from ..utilities import NiftyMeta
20
21


Martin Reinecke's avatar
Martin Reinecke committed
22
class Domain(metaclass=NiftyMeta):
Martin Reinecke's avatar
Martin Reinecke committed
23
    """The abstract class repesenting a (structured or unstructured) domain.
24
    """
25
26
27
    def __repr__(self):
        raise NotImplementedError

28
    def __hash__(self):
Martin Reinecke's avatar
Martin Reinecke committed
29
30
31
32
        """Returns a hash value for the object.

        Notes
        -----
Martin Reinecke's avatar
Martin Reinecke committed
33
34
        Only members that are explicitly added to
        :attr:`._needed_for_hash` will be used for hashing.
Martin Reinecke's avatar
Martin Reinecke committed
35
        """
Martin Reinecke's avatar
Martin Reinecke committed
36
37
38
        try:
            return self._hash
        except AttributeError:
Martin Reinecke's avatar
Martin Reinecke committed
39
40
41
            v = vars(self)
            self._hash = reduce(lambda x, y: x ^ y, (hash(v[key])
                                for key in self._needed_for_hash), 0)
Martin Reinecke's avatar
step 1    
Martin Reinecke committed
42
        return self._hash
43
44

    def __eq__(self, x):
Martin Reinecke's avatar
Martin Reinecke committed
45
        """Checks whether two domains are equal.
Theo Steininger's avatar
Theo Steininger committed
46

47
48
        Parameters
        ----------
Martin Reinecke's avatar
Martin Reinecke committed
49
        x : Domain
Martin Reinecke's avatar
Martin Reinecke committed
50
            The domain `self` is compared to.
Theo Steininger's avatar
Theo Steininger committed
51

52
53
        Returns
        -------
Martin Reinecke's avatar
Martin Reinecke committed
54
        bool : True iff `self` and x describe the same domain.
Martin Reinecke's avatar
Martin Reinecke committed
55
56
57
58

        Notes
        -----
        Only members that are explicitly added to
Martin Reinecke's avatar
Martin Reinecke committed
59
        :attr:`._needed_for_hash` will be used for comparison.
Martin Reinecke's avatar
Martin Reinecke committed
60
61
62
63

        Subclasses of Domain should not re-define :meth:`__eq__`,
        :meth:`__ne__`, or :meth:`__hash__`; they should instead add their
        relevant attributes' names to :attr:`._needed_for_hash`.
64
        """
Martin Reinecke's avatar
Martin Reinecke committed
65
66
        if self is x:  # shortcut for simple case
            return True
Martin Reinecke's avatar
Martin Reinecke committed
67
        if not isinstance(x, type(self)):
68
            return False
69
70
71
        for key in self._needed_for_hash:
            if vars(self)[key] != vars(x)[key]:
                return False
Martin Reinecke's avatar
Martin Reinecke committed
72
        return True
73
74

    def __ne__(self, x):
Martin Reinecke's avatar
Martin Reinecke committed
75
        """Returns the opposite of :meth:`.__eq__()`"""
76
77
        return not self.__eq__(x)

Martin Reinecke's avatar
Martin Reinecke committed
78
    @property
79
    def shape(self):
Martin Reinecke's avatar
Martin Reinecke committed
80
        """tuple of int: number of pixels along each axis
Theo Steininger's avatar
Theo Steininger committed
81

Martin Reinecke's avatar
Martin Reinecke committed
82
        The shape of the array-like object required to store information
Philipp Arras's avatar
Philipp Arras committed
83
        defined on the domain.
84
        """
Martin Reinecke's avatar
Martin Reinecke committed
85
        raise NotImplementedError
86

87
88
    @property
    def local_shape(self):
89
90
91
92
        """tuple of int: number of pixels along each axis on the local task,
        mainly relevant for MPI.

        See :meth:`.shape()` for general explanation of property.
93
94

        The shape of the array-like object required to store information
Philipp Arras's avatar
Philipp Arras committed
95
        defined on part of the domain which is stored on the local MPI task.
96
97
98
99
        """
        from ..dobj import local_shape
        return local_shape(self.shape)

Martin Reinecke's avatar
Martin Reinecke committed
100
    @property
Martin Reinecke's avatar
Martin Reinecke committed
101
    def size(self):
Martin Reinecke's avatar
Martin Reinecke committed
102
        """int: total number of pixels.
103

Martin Reinecke's avatar
Martin Reinecke committed
104
        Equivalent to the products over all entries in the domain's shape.
105
        """
Martin Reinecke's avatar
Martin Reinecke committed
106
        raise NotImplementedError