domain.py 3.4 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
#
Martin Reinecke's avatar
Martin Reinecke committed
14
# Copyright(C) 2013-2018 Max-Planck-Society
Theo Steininger's avatar
Theo Steininger committed
15
16
17
#
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik
# and financially supported by the Studienstiftung des deutschen Volkes.
18

19
20
from __future__ import absolute_import, division, print_function
from ..compat import *
21
import abc
Martin Reinecke's avatar
Martin Reinecke committed
22
from ..utilities import NiftyMetaBase
23
24


Martin Reinecke's avatar
Martin Reinecke committed
25
class Domain(NiftyMetaBase()):
Martin Reinecke's avatar
Martin Reinecke committed
26
    """The abstract class repesenting a (structured or unstructured) domain.
27
    """
Martin Reinecke's avatar
step 1    
Martin Reinecke committed
28
29
    def __init__(self):
        self._hash = None
30

31
32
33
34
    @abc.abstractmethod
    def __repr__(self):
        raise NotImplementedError

35
    def __hash__(self):
Martin Reinecke's avatar
Martin Reinecke committed
36
37
38
39
        """Returns a hash value for the object.

        Notes
        -----
Martin Reinecke's avatar
Martin Reinecke committed
40
41
        Only members that are explicitly added to
        :attr:`._needed_for_hash` will be used for hashing.
Martin Reinecke's avatar
Martin Reinecke committed
42
        """
Martin Reinecke's avatar
step 1    
Martin Reinecke committed
43
44
45
46
47
48
        if self._hash is None:
            h = 0
            for key in self._needed_for_hash:
                h ^= hash(vars(self)[key])
            self._hash = h
        return self._hash
49
50

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

53
54
        Parameters
        ----------
Martin Reinecke's avatar
Martin Reinecke committed
55
        x : Domain
Martin Reinecke's avatar
Martin Reinecke committed
56
            The domain `self` is compared to.
Theo Steininger's avatar
Theo Steininger committed
57

58
59
        Returns
        -------
Martin Reinecke's avatar
Martin Reinecke committed
60
        bool : True iff `self` and x describe the same domain.
Martin Reinecke's avatar
Martin Reinecke committed
61
62
63
64

        Notes
        -----
        Only members that are explicitly added to
Martin Reinecke's avatar
Martin Reinecke committed
65
        :attr:`._needed_for_hash` will be used for comparison.
Martin Reinecke's avatar
Martin Reinecke committed
66
67
68
69

        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`.
70
        """
Martin Reinecke's avatar
Martin Reinecke committed
71
72
        if self is x:  # shortcut for simple case
            return True
Martin Reinecke's avatar
Martin Reinecke committed
73
        if not isinstance(x, type(self)):
74
            return False
75
76
77
        for key in self._needed_for_hash:
            if vars(self)[key] != vars(x)[key]:
                return False
Martin Reinecke's avatar
Martin Reinecke committed
78
        return True
79
80

    def __ne__(self, x):
Martin Reinecke's avatar
Martin Reinecke committed
81
        """Returns the opposite of :meth:`.__eq__()`"""
82
83
84
85
        return not self.__eq__(x)

    @abc.abstractproperty
    def shape(self):
Martin Reinecke's avatar
Martin Reinecke committed
86
        """tuple of int: number of pixels along each axis
Theo Steininger's avatar
Theo Steininger committed
87

Martin Reinecke's avatar
Martin Reinecke committed
88
89
        The shape of the array-like object required to store information
        living on the domain.
90
        """
Martin Reinecke's avatar
Martin Reinecke committed
91
        raise NotImplementedError
92

93
94
95
96
97
98
99
100
101
102
    @property
    def local_shape(self):
        """tuple of int: number of pixels along each axis on the local task

        The shape of the array-like object required to store information
        living on part of the domain which is stored on the local MPI task.
        """
        from ..dobj import local_shape
        return local_shape(self.shape)

103
    @abc.abstractproperty
Martin Reinecke's avatar
Martin Reinecke committed
104
    def size(self):
Martin Reinecke's avatar
Martin Reinecke committed
105
        """int: total number of pixels.
106

Martin Reinecke's avatar
Martin Reinecke committed
107
        Equivalent to the products over all entries in the domain's shape.
108
        """
Martin Reinecke's avatar
Martin Reinecke committed
109
        raise NotImplementedError