コード例 #1
0
ファイル: vectorization_test.py プロジェクト: iceseismic/odl
def test_is_valid_input_array():

    # 1d
    valid_shapes = [(1, 1), (1, 2), (1, 20), (1,), (20,)]
    invalid_shapes = [(2, 1), (1, 1, 1), ()]

    for shp in valid_shapes:
        arr = np.zeros(shp)
        assert is_valid_input_array(arr, ndim=1)

    for shp in invalid_shapes:
        arr = np.zeros(shp)
        assert not is_valid_input_array(arr, ndim=1)

    # 3d
    valid_shapes = [(3, 1), (3, 2), (3, 20)]
    invalid_shapes = [(3,), (20,), (4, 1), (3, 1, 1), ()]

    for shp in valid_shapes:
        arr = np.zeros(shp)
        assert is_valid_input_array(arr, ndim=3)

    for shp in invalid_shapes:
        arr = np.zeros(shp)
        assert not is_valid_input_array(arr, ndim=3)

    # Other input
    invalid_input = [1, [[1, 2], [3, 4]], (5,)]
    for inp in invalid_input:
        assert not is_valid_input_array(inp, ndim=2)
コード例 #2
0
ファイル: vectorization_test.py プロジェクト: sushmita13/odl
def test_is_valid_input_array():

    # 1d
    valid_shapes = [(1, 1), (1, 2), (1, 20), (20, )]
    invalid_shapes = [(2, 1), (1, 1, 1), (1, ), ()]

    for shp in valid_shapes:
        arr = np.zeros(shp)
        assert is_valid_input_array(arr, ndim=1)

    for shp in invalid_shapes:
        arr = np.zeros(shp)
        assert not is_valid_input_array(arr, ndim=1)

    # 3d
    valid_shapes = [(3, 1), (3, 2), (3, 20)]
    invalid_shapes = [(3, ), (20, ), (4, 1), (3, 1, 1), ()]

    for shp in valid_shapes:
        arr = np.zeros(shp)
        assert is_valid_input_array(arr, ndim=3)

    for shp in invalid_shapes:
        arr = np.zeros(shp)
        assert not is_valid_input_array(arr, ndim=3)

    # Other input
    assert is_valid_input_array([[1, 2], [3, 4]], ndim=2)
    invalid_input = [1, [[[1, 2], [3, 4]]], (5, )]
    for inp in invalid_input:
        assert not is_valid_input_array(inp, ndim=2)
コード例 #3
0
ファイル: fspace.py プロジェクト: rajmund/odl
        def one_vec(x, out=None):
            """The one function, vectorized."""
            if is_valid_input_meshgrid(x, self.domain.ndim):
                out_shape = out_shape_from_meshgrid(x)
            elif is_valid_input_array(x, self.domain.ndim):
                out_shape = out_shape_from_array(x)
            else:
                raise TypeError('invalid input type')

            if out is None:
                return np.ones(out_shape, dtype=self.out_dtype)
            else:
                out.fill(1)
コード例 #4
0
ファイル: domain.py プロジェクト: iceseismic/odl
    def contains_all(self, other):
        """Test if all points defined by ``other`` are contained.

        Parameters
        ----------
        other : object
            Can be a single point, a ``(d, N)`` array where ``d`` is the
            number of dimensions or a length-``d`` meshgrid sequence

        Returns
        -------
        contains : `bool`
            `True` if all points are contained, `False` otherwise

        Examples
        --------
        >>> b, e = [-1, 0, 2], [-0.5, 0, 3]
        >>> rbox = IntervalProd(b, e)
        ...
        ... # Arrays are expected in (ndim, npoints) shape
        >>> arr = np.array([[-1, 0, 2],   # defining one point at a time
        ...                 [-0.5, 0, 2]])
        >>> rbox.contains_all(arr.T)
        True
        >>> # Implicit meshgrids defined by coordinate vectors
        >>> from odl.discr.grid import sparse_meshgrid
        >>> vec1 = (-1, -0.9, -0.7)
        >>> vec2 = (0, 0, 0)
        >>> vec3 = (2.5, 2.75, 3)
        >>> mg = sparse_meshgrid(vec1, vec2, vec3)
        >>> rbox.contains_all(mg)
        True
        """
        if other in self:
            return True
        elif is_valid_input_meshgrid(other, self.ndim):
            order = meshgrid_input_order(other)
            vecs = vecs_from_meshgrid(other, order)
            mins = np.fromiter((np.min(vec) for vec in vecs), dtype=float)
            maxs = np.fromiter((np.max(vec) for vec in vecs), dtype=float)
            return np.all(mins >= self.begin) and np.all(maxs <= self.end)
        elif is_valid_input_array(other, self.ndim):
            if self.ndim == 1:
                mins = np.min(other)
                maxs = np.max(other)
            else:
                mins = np.min(other, axis=1)
                maxs = np.max(other, axis=1)
            return np.all(mins >= self.begin) and np.all(maxs <= self.end)
        else:
            return False
コード例 #5
0
ファイル: fspace.py プロジェクト: iceseismic/odl
def _default_out_of_place(func, dtype, x, **kwargs):
    """Default in-place evaluation method."""
    if is_valid_input_array(x, func.domain.ndim):
        out_shape = out_shape_from_array(x)
    elif is_valid_input_meshgrid(x, func.domain.ndim):
        out_shape = out_shape_from_meshgrid(x)
    else:
        raise TypeError('cannot use in-place method to implement '
                        'out-of-place non-vectorized evaluation.')

    if dtype is None:
        dtype = np.result_type(*x)

    out = np.empty(out_shape, dtype=dtype)
    func(x, out=out, **kwargs)
    return out
コード例 #6
0
ファイル: fspace.py プロジェクト: rajmund/odl
def _default_out_of_place(func, x, **kwargs):
    """Default in-place evaluation method."""
    if is_valid_input_array(x, func.domain.ndim):
        out_shape = out_shape_from_array(x)
    elif is_valid_input_meshgrid(x, func.domain.ndim):
        out_shape = out_shape_from_meshgrid(x)
    else:
        raise TypeError('cannot use in-place method to implement '
                        'out-of-place non-vectorized evaluation')

    dtype = func.space.out_dtype
    if dtype is None:
        dtype = np.result_type(*x)

    out = np.empty(out_shape, dtype=dtype)
    func(x, out=out, **kwargs)
    return out
コード例 #7
0
ファイル: domain.py プロジェクト: NikEfth/odl
    def contains_all(self, other):
        """Test if all points defined by ``other`` are contained.

        Parameters
        ----------
        other :
            Can be a single point, a ``(d, N)`` array where ``d`` is the
            number of dimensions or a length-``d`` meshgrid tuple

        Returns
        -------
        contains : `bool`
            `True` if all points are contained, `False` otherwise

        Examples
        --------
        >>> import odl
        >>> b, e = [-1, 0, 2], [-0.5, 0, 3]
        >>> rbox = IntervalProd(b, e)

        rrays are expected in (ndim, npoints) shape

        >>> arr = np.array([[-1, 0, 2],   # defining one point at a time
        ...                 [-0.5, 0, 2]])
        >>> rbox.contains_all(arr.T)
        True

        Implicit meshgrids defined by coordinate vectors

        >>> from odl.discr.grid import sparse_meshgrid
        >>> vec1 = (-1, -0.9, -0.7)
        >>> vec2 = (0, 0, 0)
        >>> vec3 = (2.5, 2.75, 3)
        >>> mg = sparse_meshgrid(vec1, vec2, vec3)
        >>> rbox.contains_all(mg)
        True

        Also works with any iterable

        >>> rbox.contains_all([[-1, -0.5], # define points by axis
        ...                    [0, 0],
        ...                    [2, 2]])
        True

        And with grids

        >>> agrid = odl.uniform_sampling(rbox.begin, rbox.end, [3, 1, 3])
        >>> rbox.contains_all(agrid)
        True
        """
        # First try optimized methods
        if other in self:
            return True
        if hasattr(other, 'meshgrid'):
            return self.contains_all(other.meshgrid)
        elif is_valid_input_meshgrid(other, self.ndim):
            vecs = tuple(vec.squeeze() for vec in other)
            mins = np.fromiter((np.min(vec) for vec in vecs), dtype=float)
            maxs = np.fromiter((np.max(vec) for vec in vecs), dtype=float)
            return np.all(mins >= self.begin) and np.all(maxs <= self.end)

        # Convert to array and check each element
        other = np.asarray(other)
        if is_valid_input_array(other, self.ndim):
            if self.ndim == 1:

                mins = np.min(other)
                maxs = np.max(other)
            else:
                mins = np.min(other, axis=1)
                maxs = np.max(other, axis=1)
            return np.all(mins >= self.begin) and np.all(maxs <= self.end)
        else:
            return False
コード例 #8
0
ファイル: domain.py プロジェクト: odlgroup/odl
    def contains_all(self, other, atol=0.0):
        """Return ``True`` if all points defined by ``other`` are contained.

        Parameters
        ----------
        other :
            Collection of points to be tested. Can be given as a single
            point, a ``(d, N)`` array-like where ``d`` is the
            number of dimensions, or a length-``d`` `meshgrid` tuple.
        atol : float, optional
            The maximum allowed distance in 'inf'-norm between the
            other set and this interval product.

        Returns
        -------
        contains : bool
            ``True`` if all points are contained, ``False`` otherwise.

        Examples
        --------
        >>> min_pt, max_pt = [-1, 0, 2], [-0.5, 0, 3]
        >>> rbox = IntervalProd(min_pt, max_pt)

        Arrays are expected in ``(ndim, npoints)`` shape:

        >>> arr = np.array([[-1, 0, 2],   # defining one point at a time
        ...                 [-0.5, 0, 2]])
        >>> rbox.contains_all(arr.T)
        True

        Implicit meshgrids defined by coordinate vectors:

        >>> from odl.discr.grid import sparse_meshgrid
        >>> vec1 = (-1, -0.9, -0.7)
        >>> vec2 = (0, 0, 0)
        >>> vec3 = (2.5, 2.75, 3)
        >>> mg = sparse_meshgrid(vec1, vec2, vec3)
        >>> rbox.contains_all(mg)
        True

        Works also with an arbitrary iterable:

        >>> rbox.contains_all([[-1, -0.5], # define points by axis
        ...                    [0, 0],
        ...                    [2, 2]])
        True

        Grids are also accepted as input:

        >>> agrid = odl.uniform_sampling(rbox.min_pt, rbox.max_pt, [3, 1, 3])
        >>> rbox.contains_all(agrid)
        True
        """
        atol = float(atol)

        # First try optimized methods
        if other in self:
            return True
        if hasattr(other, 'meshgrid'):
            return self.contains_all(other.meshgrid, atol=atol)
        elif is_valid_input_meshgrid(other, self.ndim):
            vecs = tuple(vec.squeeze() for vec in other)
            mins = np.fromiter((np.min(vec) for vec in vecs), dtype=float)
            maxs = np.fromiter((np.max(vec) for vec in vecs), dtype=float)
            return (np.all(mins >= self.min_pt - atol) and
                    np.all(maxs <= self.max_pt + atol))

        # Convert to array and check each element
        other = np.asarray(other)
        if is_valid_input_array(other, self.ndim):
            if self.ndim == 1:
                mins = np.min(other)
                maxs = np.max(other)
            else:
                mins = np.min(other, axis=1)
                maxs = np.max(other, axis=1)
            return np.all(mins >= self.min_pt) and np.all(maxs <= self.max_pt)
        else:
            return False
コード例 #9
0
ファイル: fspace.py プロジェクト: iceseismic/odl
    def __call__(self, x, out=None, **kwargs):
        """Evaluate the function at one or multiple values ``x``.

        Parameters
        ----------
        x : object
            Input argument for the function evaluation. Conditions
            on ``x`` depend on vectorization:

            `False` : ``x`` must be a domain element

            `True` : ``x`` must be a `numpy.ndarray` with shape
            ``(d, N)``, where ``d`` is the number of dimensions of
            the function domain
            OR
            ``x`` is a sequence of `numpy.ndarray` with length
            ``space.ndim``, and the arrays can be broadcast
            against each other.

        out : `numpy.ndarray`, optional
            Output argument holding the result of the function
            evaluation, can only be used for vectorized
            functions. Its shape must be equal to
            ``np.broadcast(*x).shape``.

        bounds_check : bool
            Whether or not to check if all input points lie in
            the function domain. For vectorized evaluation,
            this requires the domain to implement
            `Set.contains_all`.

            Default: `True`

        Returns
        -------
        out : range element or array of elements
            Result of the function evaluation. If ``out`` was provided,
            the returned object is a reference to it.

        Raises
        ------
        TypeError
            If ``x`` is not a valid vectorized evaluation argument

            If ``out`` is not a range element or a `numpy.ndarray`
            of range elements

        ValueError
            If evaluation points fall outside the valid domain
        """
        bounds_check = kwargs.pop('bounds_check', True)
        if bounds_check and not hasattr(self.domain, 'contains_all'):
            raise AttributeError('bounds check not possible for '
                                 'domain {}, missing `contains_all()` '
                                 'method.'.format(self.domain))

        # Check for input type and determine output shape
        if is_valid_input_array(x, self.domain.ndim):
            out_shape = out_shape_from_array(x)
            scalar_out = False
            # For 1d, squeeze the array
            if self.domain.ndim == 1 and x.ndim == 2:
                x = x.squeeze()
        elif is_valid_input_meshgrid(x, self.domain.ndim):
            out_shape = out_shape_from_meshgrid(x)
            scalar_out = False
            # For 1d, fish out the vector from the tuple
            if self.domain.ndim == 1:
                x = x[0]
        elif x in self.domain:
            x = np.atleast_2d(x).T  # make a (d, 1) array
            out_shape = (1,)
            scalar_out = (out is None)
        else:
            # Unknown input
            raise TypeError('argument {!r} not a valid vectorized '
                            'input. Expected an element of the domain '
                            '{dom}, a ({dom.ndim}, n) array '
                            'or a length-{dom.ndim} meshgrid sequence.'
                            ''.format(x, dom=self.domain))

        # Check bounds if specified
        if bounds_check:
            if not self.domain.contains_all(x):
                raise ValueError('input contains points outside '
                                 'the domain {}.'.format(self.domain))

        # Call the function and check out shape, before or after
        if out is None:
            out = self._call(x, **kwargs)
            if out_shape != (1,) and out.shape != out_shape:
                raise ValueError('output shape {} not equal to shape '
                                 '{} expected from input.'
                                 ''.format(out.shape, out_shape))
        else:
            if not isinstance(out, np.ndarray):
                raise TypeError('output {!r} not a `numpy.ndarray` '
                                'instance.')
            if out_shape != (1,) and out.shape != out_shape:
                raise ValueError('output shape {} not equal to shape '
                                 '{} expected from input.'
                                 ''.format(out.shape, out_shape))
            self._call(x, out=out, **kwargs)

        # Check output values
        if bounds_check:
            if not self.range.contains_all(out):
                raise ValueError('output contains points outside '
                                 'the range {}.'
                                 ''.format(self.domain))

        # Numpy does not implement __complex__ for arrays (in contrast to
        # __float__), so we have to fish out the scalar ourselves.
        return self.range.element(out.ravel()[0]) if scalar_out else out
コード例 #10
0
ファイル: fspace.py プロジェクト: rajmund/odl
    def __call__(self, x, out=None, **kwargs):
        """Return ``self(x[, out, **kwargs])``.

        Parameters
        ----------
        x : domain `element-like`, `meshgrid` or `numpy.ndarray`
            Input argument for the function evaluation. Conditions
            on ``x`` depend on its type:

            element-like: must be a castable to a domain element

            meshgrid: length must be ``space.ndim``, and the arrays must
            be broadcastable against each other.

            array:  shape must be ``(d, N)``, where ``d`` is the number
            of dimensions of the function domain

        out : `numpy.ndarray`, optional
            Output argument holding the result of the function
            evaluation, can only be used for vectorized
            functions. Its shape must be equal to
            ``np.broadcast(*x).shape``.

        Other Parameters
        ----------------
        bounds_check : `bool`
            If `True`, check if all input points lie in the function
            domain in the case of vectorized evaluation. This requires
            the domain to implement `Set.contains_all`.
            Default: `True`

        Returns
        -------
        out : range element or array of elements
            Result of the function evaluation. If ``out`` was provided,
            the returned object is a reference to it.

        Raises
        ------
        TypeError
            If ``x`` is not a valid vectorized evaluation argument

            If ``out`` is not a range element or a `numpy.ndarray`
            of range elements

        ValueError
            If evaluation points fall outside the valid domain
        """
        bounds_check = kwargs.pop('bounds_check', True)
        if bounds_check and not hasattr(self.domain, 'contains_all'):
            raise AttributeError('bounds check not possible for '
                                 'domain {}, missing `contains_all()` '
                                 'method'.format(self.domain))

        if bounds_check and not hasattr(self.range, 'contains_all'):
            raise AttributeError('bounds check not possible for '
                                 'range {}, missing `contains_all()` '
                                 'method'.format(self.range))

        ndim = getattr(self.domain, 'ndim', None)
        # Check for input type and determine output shape
        if is_valid_input_meshgrid(x, ndim):
            out_shape = out_shape_from_meshgrid(x)
            scalar_out = False
            # Avoid operations on tuples like x * 2 by casting to array
            if ndim == 1:
                x = x[0][None, ...]
        elif is_valid_input_array(x, ndim):
            x = np.asarray(x)
            out_shape = out_shape_from_array(x)
            scalar_out = False
            # For 1d, squeeze the array
            if ndim == 1 and x.ndim == 2:
                x = x.squeeze()
        elif x in self.domain:
            x = np.atleast_2d(x).T  # make a (d, 1) array
            out_shape = (1,)
            scalar_out = (out is None)
        else:
            # Unknown input
            txt_1d = ' or (n,)' if ndim == 1 else ''
            raise TypeError('Argument {!r} not a valid vectorized '
                            'input. Expected an element of the domain '
                            '{domain}, an array-like with shape '
                            '({domain.ndim}, n){} or a length-{domain.ndim} '
                            'meshgrid tuple.'
                            ''.format(x, txt_1d, domain=self.domain))

        # Check bounds if specified
        if bounds_check:
            if not self.domain.contains_all(x):
                raise ValueError('input contains points outside '
                                 'the domain {}'.format(self.domain))

        # Call the function and check out shape, before or after
        if out is None:
            if ndim == 1:
                try:
                    out = self._call(x, **kwargs)
                    if np.ndim(out) == 0 and not scalar_out:
                        # Don't accept scalar result. A typical situation where
                        # this occurs is with comparison operators, e.g.
                        # "return x > 0" which simply gives 'True' for a
                        # non-empty tuple (in Python 2). We raise TypeError
                        # to trigger the call with x[0].
                        raise TypeError
                    out = np.atleast_1d(np.squeeze(out))
                except (TypeError, IndexError):
                    # TypeError is raised if a meshgrid was used but the
                    # function expected an array (1d only). In this case we try
                    # again with the first meshgrid vector.
                    # IndexError is raised in expressions like x[x > 0] since
                    # "x > 0" evaluates to 'True', i.e. 1, and that index is
                    # out of range for a meshgrid tuple of length 1 :-). To get
                    # the real errors with indexing, we check again for the
                    # same scenario (scalar output when not valid) as in the
                    # first case.
                    out = self._call(x[0], **kwargs)
                    if np.ndim(out) == 0 and not scalar_out:
                        raise ValueError('invalid scalar output')
                    out = np.atleast_1d(np.squeeze(out))
            else:
                out = self._call(x, **kwargs)

            if self.out_dtype is not None:
                # Cast to proper dtype if needed
                out = out.astype(self.out_dtype)

            if out_shape != (1,) and out.shape != out_shape:
                # Try to broadcast the returned element if possible
                try:
                    out = np.broadcast_to(out, out_shape)
                except AttributeError:
                    # The above requires numpy 1.10, fallback impl else
                    shape = [m if n == 1 and m != 1 else 1
                             for n, m in zip(out.shape, out_shape)]
                    out = out + np.zeros(shape, dtype=out.dtype)
        else:
            if not isinstance(out, np.ndarray):
                raise TypeError('output {!r} not a `numpy.ndarray` '
                                'instance')
            if out_shape != (1,) and out.shape != out_shape:
                raise ValueError('output shape {} not equal to shape '
                                 '{} expected from input'
                                 ''.format(out.shape, out_shape))
            if self.out_dtype is not None and out.dtype != self.out_dtype:
                raise ValueError('`out.dtype` ({}) does not match out_dtype '
                                 '({})'.format(out.dtype, self.out_dtype))

            if ndim == 1:
                # TypeError for meshgrid in 1d, but expected array (see above)
                try:
                    self._call(x, out=out, **kwargs)
                except TypeError:
                    self._call(x[0], out=out, **kwargs)
            else:
                self._call(x, out=out, **kwargs)

        # Check output values
        if bounds_check:
            if not self.range.contains_all(out):
                raise ValueError('output contains points outside '
                                 'the range {}'
                                 ''.format(self.range))

        # Numpy does not implement __complex__ for arrays (in contrast to
        # __float__), so we have to fish out the scalar ourselves.
        return self.range.element(out.ravel()[0]) if scalar_out else out
コード例 #11
0
ファイル: domain.py プロジェクト: rajmund/odl
    def contains_all(self, other, atol=0.0):
        """Test if all points defined by ``other`` are contained.

        Parameters
        ----------
        other :
            Can be a single point, a ``(d, N)`` array where ``d`` is the
            number of dimensions or a length-``d`` meshgrid tuple
        atol : `float`, optional
            The maximum allowed distance in 'inf'-norm between the
            other set and this interval product.

        Returns
        -------
        contains : `bool`
            `True` if all points are contained, `False` otherwise

        Examples
        --------
        >>> import odl
        >>> b, e = [-1, 0, 2], [-0.5, 0, 3]
        >>> rbox = IntervalProd(b, e)

        rrays are expected in (ndim, npoints) shape

        >>> arr = np.array([[-1, 0, 2],   # defining one point at a time
        ...                 [-0.5, 0, 2]])
        >>> rbox.contains_all(arr.T)
        True

        Implicit meshgrids defined by coordinate vectors

        >>> from odl.discr.grid import sparse_meshgrid
        >>> vec1 = (-1, -0.9, -0.7)
        >>> vec2 = (0, 0, 0)
        >>> vec3 = (2.5, 2.75, 3)
        >>> mg = sparse_meshgrid(vec1, vec2, vec3)
        >>> rbox.contains_all(mg)
        True

        Also works with any iterable

        >>> rbox.contains_all([[-1, -0.5], # define points by axis
        ...                    [0, 0],
        ...                    [2, 2]])
        True

        And with grids

        >>> agrid = odl.uniform_sampling(rbox.begin, rbox.end, [3, 1, 3])
        >>> rbox.contains_all(agrid)
        True
        """
        atol = float(atol)

        # First try optimized methods
        if other in self:
            return True
        if hasattr(other, 'meshgrid'):
            return self.contains_all(other.meshgrid, atol=atol)
        elif is_valid_input_meshgrid(other, self.ndim):
            vecs = tuple(vec.squeeze() for vec in other)
            mins = np.fromiter((np.min(vec) for vec in vecs), dtype=float)
            maxs = np.fromiter((np.max(vec) for vec in vecs), dtype=float)
            return (np.all(mins >= self.begin - atol) and
                    np.all(maxs <= self.end + atol))

        # Convert to array and check each element
        other = np.asarray(other)
        if is_valid_input_array(other, self.ndim):
            if self.ndim == 1:
                mins = np.min(other)
                maxs = np.max(other)
            else:
                mins = np.min(other, axis=1)
                maxs = np.max(other, axis=1)
            return np.all(mins >= self.begin) and np.all(maxs <= self.end)
        else:
            return False