<commit_before># Copyright 2014-2017 The ODL contributors
#
# This file is part of ODL.
#
# This Source Code Form is subject to the terms of the Mozilla Public License,
# v. 2.0. If a copy of the MPL was not distributed with this file, You can
# obtain one at https://mozilla.org/MPL/2.0/.

"""Convenience functions for operators."""

from __future__ import print_function, division, absolute_import
from future.utils import native
import numpy as np

from odl.space.base_tensors import TensorSpace
from odl.space import ProductSpace
from odl.util import nd_iterator

__all__ = ('matrix_representation', 'power_method_opnorm', 'as_scipy_operator',
           'as_scipy_functional', 'as_proximal_lang_operator')


def matrix_representation(op):
    """Return a matrix representation of a linear operator.

    Parameters
    ----------
    op : `Operator`
        The linear operator of which one wants a matrix representation.
        If the domain or range is a `ProductSpace`, it must be a power-space.

    Returns
    -------
    matrix : `numpy.ndarray`
        The matrix representation of the operator.

        The shape will be ``op.domain.shape + op.range.shape`` and the dtype
        is the promoted (greatest) dtype of the domain and range.

    Examples
    --------
    Approximate a matrix on its own:

    >>> mat = np.array([[1, 2, 3],
    ...                 [4, 5, 6],
    ...                 [7, 8, 9]])
    >>> op = odl.MatrixOperator(mat)
    >>> matrix_representation(op)
    array([[1, 2, 3],
           [4, 5, 6],
           [7, 8, 9]])

    It also works with `ProductSpace`s and higher dimensional `TensorSpace`s.
    In this case, the returned "matrix" will also be higher dimensional:

    >>> space = odl.uniform_discr([0, 0], [2, 2], (2, 2))
    >>> grad = odl.Gradient(space)
    >>> tensor = odl.matrix_representation(grad)
    >>> tensor.shape
    (2L, 2L, 2L, 2L, 2L)

    Since the "matrix" is now higher dimensional, we need to use e.g.
    `numpy.tensordot` if we want to compute with the matrix representation:

    >>> x = space.element(lambda x: x[0] ** 2 + 2 * x[1] ** 2)
    >>> grad(x)
    ProductSpace(uniform_discr([ 0.,  0.], [ 2.,  2.], (2, 2)), 2).element([
    <BLANKLINE>
            [[ 2.  ,  2.  ],
             [-2.75, -6.75]],
    <BLANKLINE>
            [[ 4.  , -4.75],
             [ 4.  , -6.75]]
    ])
    >>> np.tensordot(tensor, x, axes=grad.domain.ndim)
    array([[[ 2.  ,  2.  ],
            [-2.75, -6.75]],
    <BLANKLINE>
            [[ 4.  , -4.75],
             [ 4.  , -6.75]]])

    Notes
    ----------
    The algorithm works by letting the operator act on all unit vectors, and
    stacking the output as a matrix.
    """

    if not op.is_linear:
        raise ValueError('the operator is not linear')

    if not (isinstance(op.domain, TensorSpace) or
            (isinstance(op.domain, ProductSpace) and
             op.domain.is_power_space and
             all(isinstance(spc, TensorSpace) for spc in op.domain))):
        raise TypeError('operator domain {!r} is neither `TensorSpace` '<commit_msg>ENH: Windows/python2 fix in matrix_operator test<commit_after># Copyright 2014-2017 The ODL contributors
#
# This file is part of ODL.
#
# This Source Code Form is subject to the terms of the Mozilla Public License,
# v. 2.0. If a copy of the MPL was not distributed with this file, You can
# obtain one at https://mozilla.org/MPL/2.0/.

"""Convenience functions for operators."""

from __future__ import print_function, division, absolute_import
from future.utils import native
import numpy as np

from odl.space.base_tensors import TensorSpace
from odl.space import ProductSpace
from odl.util import nd_iterator

__all__ = ('matrix_representation', 'power_method_opnorm', 'as_scipy_operator',
           'as_scipy_functional', 'as_proximal_lang_operator')


def matrix_representation(op):
    """Return a matrix representation of a linear operator.

    Parameters
    ----------
    op : `Operator`
        The linear operator of which one wants a matrix representation.
        If the domain or range is a `ProductSpace`, it must be a power-space.

    Returns
    -------
    matrix : `numpy.ndarray`
        The matrix representation of the operator.

        The shape will be ``op.domain.shape + op.range.shape`` and the dtype
        is the promoted (greatest) dtype of the domain and range.

    Examples
    --------
    Approximate a matrix on its own:

    >>> mat = np.array([[1, 2, 3],
    ...                 [4, 5, 6],
    ...                 [7, 8, 9]])
    >>> op = odl.MatrixOperator(mat)
    >>> matrix_representation(op)
    array([[1, 2, 3],
           [4, 5, 6],
           [7, 8, 9]])

    It also works with `ProductSpace`s and higher dimensional `TensorSpace`s.
    In this case, the returned "matrix" will also be higher dimensional:

    >>> space = odl.uniform_discr([0, 0], [2, 2], (2, 2))
    >>> grad = odl.Gradient(space)
    >>> tensor = odl.matrix_representation(grad)
    >>> tensor.shape == (2, 2, 2, 2, 2)
    True

    Since the "matrix" is now higher dimensional, we need to use e.g.
    `numpy.tensordot` if we want to compute with the matrix representation:

    >>> x = space.element(lambda x: x[0] ** 2 + 2 * x[1] ** 2)
    >>> grad(x)
    ProductSpace(uniform_discr([ 0.,  0.], [ 2.,  2.], (2, 2)), 2).element([
    <BLANKLINE>
            [[ 2.  ,  2.  ],
             [-2.75, -6.75]],
    <BLANKLINE>
            [[ 4.  , -4.75],
             [ 4.  , -6.75]]
    ])
    >>> np.tensordot(tensor, x, axes=grad.domain.ndim)
    array([[[ 2.  ,  2.  ],
            [-2.75, -6.75]],
    <BLANKLINE>
           [[ 4.  , -4.75],
            [ 4.  , -6.75]]])

    Notes
    ----------
    The algorithm works by letting the operator act on all unit vectors, and
    stacking the output as a matrix.
    """

    if not op.is_linear:
        raise ValueError('the operator is not linear')

    if not (isinstance(op.domain, TensorSpace) or
            (isinstance(op.domain, ProductSpace) and
             op.domain.is_power_space and
             all(isinstance(spc, TensorSpace) for spc in op.domain))):
        raise TypeError('operator domain {!r} is neither `TensorSpace` '
{'fraction_non_alphanumeric': 0.13483870967741934, 'fraction_numerical': 0.027580645161290322, 'mean_word_length': 2.2896551724137932, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 69, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3479454', 'n_tokens_mistral': 2065, 'n_tokens_neox': 1924, 'n_words': 658}