コード例 #1
0
def test_to_matrix():
    np.random.seed(0)
    A = np.random.randn(2, 2)
    B = np.random.randn(3, 3)
    C = np.random.randn(3, 3)

    X = np.bmat([[np.eye(2) + A, np.zeros((2, 3))],
                 [np.zeros((3, 2)), B.dot(C.T)]])

    C = sps.csc_matrix(C)

    Aop = NumpyMatrixOperator(A)
    Bop = NumpyMatrixOperator(B)
    Cop = NumpyMatrixOperator(C)

    Xop = BlockDiagonalOperator([
        LincombOperator([IdentityOperator(NumpyVectorSpace(2)), Aop], [1, 1]),
        Concatenation(Bop, AdjointOperator(Cop))
    ])

    assert np.allclose(X, to_matrix(Xop))
    assert np.allclose(X, to_matrix(Xop, format='csr').toarray())

    np.random.seed(0)
    V = np.random.randn(10, 2)
    Vva = NumpyVectorArray(V.T)
    Vop = VectorArrayOperator(Vva)
    assert np.allclose(V, to_matrix(Vop))
    Vop = VectorArrayOperator(Vva, transposed=True)
    assert np.allclose(V, to_matrix(Vop).T)
コード例 #2
0
 def action_apply_basis(self, op):
     range_basis, source_basis = self.range_basis, self.source_basis
     if source_basis is None:
         try:
             V = op.apply_adjoint(range_basis)
         except NotImplementedError:
             raise RuleNotMatchingError('apply_adjoint not implemented')
         if isinstance(op.source, NumpyVectorSpace):
             from pymor.operators.numpy import NumpyMatrixOperator
             return NumpyMatrixOperator(V.to_numpy(),
                                        source_id=op.source.id,
                                        name=op.name)
         else:
             from pymor.operators.constructions import VectorArrayOperator
             return VectorArrayOperator(V, adjoint=True, name=op.name)
     else:
         if range_basis is None:
             V = op.apply(source_basis)
             if isinstance(op.range, NumpyVectorSpace):
                 from pymor.operators.numpy import NumpyMatrixOperator
                 return NumpyMatrixOperator(V.to_numpy().T,
                                            range_id=op.range.id,
                                            name=op.name)
             else:
                 from pymor.operators.constructions import VectorArrayOperator
                 return VectorArrayOperator(V, adjoint=False, name=op.name)
         else:
             from pymor.operators.numpy import NumpyMatrixOperator
             return NumpyMatrixOperator(op.apply2(range_basis,
                                                  source_basis),
                                        name=op.name)
コード例 #3
0
ファイル: operators.py プロジェクト: TreeerT/pymor
def test_vectorarray_op_apply_inverse():
    np.random.seed(1234)
    O = np.random.random((5, 5))
    op = VectorArrayOperator(NumpyVectorSpace.make_array(O))
    V = op.range.random()
    U = op.apply_inverse(V)
    v = V.to_numpy()
    u = np.linalg.solve(O.T, v.ravel())
    assert np.all(almost_equal(U, U.space.from_numpy(u)))
コード例 #4
0
ファイル: operators.py プロジェクト: TreeerT/pymor
def test_adjoint_vectorarray_op_apply_inverse_lstsq():
    np.random.seed(1234)
    O = np.random.random((3, 5))
    op = VectorArrayOperator(NumpyVectorSpace.make_array(O), adjoint=True)
    V = op.range.random()
    U = op.apply_inverse(V, least_squares=True)
    v = V.to_numpy()
    u = np.linalg.lstsq(O, v.ravel())[0]
    assert np.all(almost_equal(U, U.space.from_numpy(u)))
コード例 #5
0
def test_to_matrix_VectorArrayOperator():
    np.random.seed(0)
    V = np.random.randn(10, 2)

    Vva = NumpyVectorSpace.make_array(V.T)
    Vop = VectorArrayOperator(Vva)
    assert_type_and_allclose(V, Vop, 'dense')

    Vop = VectorArrayOperator(Vva, transposed=True)
    assert_type_and_allclose(V.T, Vop, 'dense')
コード例 #6
0
 def projected(self, range_basis, source_basis, product=None, name=None):
     name = name or '{}_projected'.format(self.name)
     if self.linear and not self.parametric:
         assert source_basis is None or source_basis in self.source
         assert range_basis is None or range_basis in self.range
         assert product is None or product.source == product.range == self.range
         if source_basis is None:
             if range_basis is None:
                 return self
             else:
                 try:
                     V = self.apply_adjoint(range_basis,
                                            range_product=product)
                 except NotImplementedError:
                     return ProjectedOperator(self,
                                              range_basis,
                                              None,
                                              product,
                                              name=name)
                 if self.source.type == NumpyVectorArray:
                     from pymor.operators.numpy import NumpyMatrixOperator
                     return NumpyMatrixOperator(V.data, name=name)
                 else:
                     from pymor.operators.constructions import VectorArrayOperator
                     return VectorArrayOperator(V,
                                                transposed=True,
                                                name=name)
         else:
             if range_basis is None:
                 V = self.apply(source_basis)
                 if self.range.type == NumpyVectorArray:
                     from pymor.operators.numpy import NumpyMatrixOperator
                     return NumpyMatrixOperator(V.data.T, name=name)
                 else:
                     from pymor.operators.constructions import VectorArrayOperator
                     return VectorArrayOperator(V,
                                                transposed=False,
                                                name=name)
             elif product is None:
                 from pymor.operators.numpy import NumpyMatrixOperator
                 return NumpyMatrixOperator(self.apply2(
                     range_basis, source_basis),
                                            name=name)
             else:
                 from pymor.operators.numpy import NumpyMatrixOperator
                 V = self.apply(source_basis)
                 return NumpyMatrixOperator(product.apply2(range_basis, V),
                                            name=name)
     else:
         self.logger.warn('Using inefficient generic projection operator')
         return ProjectedOperator(self,
                                  range_basis,
                                  source_basis,
                                  product,
                                  name=name)
コード例 #7
0
 def projected(self, source_basis, range_basis, product=None, name=None):
     name = name or '{}_projected'.format(self.name)
     if self.linear and not self.parametric:
         assert source_basis is None or source_basis in self.source
         assert range_basis is None or range_basis in self.range
         assert product is None or product.source == product.range == self.range
         if source_basis is None:
             if range_basis is None:
                 return self
             else:
                 V = self.apply_adjoint(range_basis, range_product=product)
                 if self.source.type == NumpyVectorArray:
                     from pymor.operators.numpy import NumpyMatrixOperator
                     return NumpyMatrixOperator(V.data, name=name)
                 else:
                     from pymor.operators.constructions import VectorArrayOperator
                     return VectorArrayOperator(V,
                                                transposed=True,
                                                copy=False,
                                                name=name)
         else:
             if range_basis is None:
                 V = self.apply(source_basis)
                 if self.range.type == NumpyVectorArray:
                     from pymor.operators.numpy import NumpyMatrixOperator
                     return NumpyMatrixOperator(V.data.T, name=name)
                 else:
                     from pymor.operators.constructions import VectorArrayOperator
                     return VectorArrayOperator(V,
                                                transposed=False,
                                                copy=False,
                                                name=name)
             elif product is None:
                 from pymor.operators.numpy import NumpyMatrixOperator
                 return NumpyMatrixOperator(self.apply2(range_basis,
                                                        source_basis,
                                                        pairwise=False),
                                            name=name)
             else:
                 from pymor.operators.numpy import NumpyMatrixOperator
                 V = self.apply(source_basis)
                 return NumpyMatrixOperator(product.apply2(range_basis,
                                                           V,
                                                           pairwise=False),
                                            name=name)
     else:
         self.logger.warn('Using inefficient generic projection operator')
         # Since the bases are not immutable and we do not own them,
         # the ProjectedOperator will have to create copies of them.
         return ProjectedOperator(self,
                                  source_basis,
                                  range_basis,
                                  product,
                                  copy=True,
                                  name=name)
コード例 #8
0
ファイル: projection.py プロジェクト: emamy/pymor
 def action_apply_basis(self, op):
     range_basis, source_basis, product = self.range_basis, self.source_basis, self.product
     if source_basis is None:
         if range_basis is None:
             return op
         else:
             try:
                 V = op.apply_transpose(
                     product.apply(range_basis) if product else range_basis)
             except NotImplementedError:
                 raise RuleNotMatchingError(
                     'apply_transpose not implemented')
             if isinstance(op.source, NumpyVectorSpace):
                 from pymor.operators.numpy import NumpyMatrixOperator
                 return NumpyMatrixOperator(V.data,
                                            source_id=op.source.id,
                                            range_id=op.range.id,
                                            name=op.name)
             else:
                 from pymor.operators.constructions import VectorArrayOperator
                 return VectorArrayOperator(V,
                                            transposed=True,
                                            space_id=op.range.id,
                                            name=op.name)
     else:
         if range_basis is None:
             V = op.apply(source_basis)
             if isinstance(op.range, NumpyVectorSpace):
                 from pymor.operators.numpy import NumpyMatrixOperator
                 return NumpyMatrixOperator(V.data.T,
                                            source_id=op.source.id,
                                            range_id=op.range.id,
                                            name=op.name)
             else:
                 from pymor.operators.constructions import VectorArrayOperator
                 return VectorArrayOperator(V,
                                            transposed=False,
                                            space_id=op.source.id,
                                            name=op.name)
         elif product is None:
             from pymor.operators.numpy import NumpyMatrixOperator
             return NumpyMatrixOperator(op.apply2(range_basis,
                                                  source_basis),
                                        source_id=op.source.id,
                                        range_id=op.range.id,
                                        name=op.name)
         else:
             from pymor.operators.numpy import NumpyMatrixOperator
             V = op.apply(source_basis)
             return NumpyMatrixOperator(product.apply2(range_basis, V),
                                        source_id=op.source.id,
                                        range_id=op.range.id,
                                        name=op.name)
コード例 #9
0
ファイル: ei.py プロジェクト: michaellaier/pymor
    def jacobian(self, U, mu=None):
        mu = self.parse_parameter(mu)

        if len(self.interpolation_dofs) == 0:
            if self.source.type == self.range.type == NumpyVectorArray:
                return NumpyMatrixOperator(np.zeros((0, self.source.dim)), name=self.name + '_jacobian')
            else:
                return ZeroOperator(self.source, self.range, name=self.name + '_jacobian')
        elif hasattr(self, 'operator'):
            return EmpiricalInterpolatedOperator(self.operator.jacobian(U, mu=mu), self.interpolation_dofs,
                                                 self.collateral_basis, self.triangular, self.name + '_jacobian')
        else:
            U_components = NumpyVectorArray(U.components(self.source_dofs), copy=False)
            JU = self.restricted_operator.jacobian(U_components, mu=mu) \
                                         .apply(NumpyVectorArray(np.eye(len(self.source_dofs)), copy=False))
            try:
                if self.triangular:
                    interpolation_coefficients = solve_triangular(self.interpolation_matrix, JU.data.T,
                                                                  lower=True, unit_diagonal=True).T
                else:
                    interpolation_coefficients = np.linalg.solve(self.interpolation_matrix, JU._array.T).T
            except ValueError:  # this exception occurs when AU contains NaNs ...
                interpolation_coefficients = np.empty((len(JU), len(self.collateral_basis))) + np.nan
            J = self.collateral_basis.lincomb(interpolation_coefficients)
            if isinstance(J, NumpyVectorArray):
                J = NumpyMatrixOperator(J.data.T)
            else:
                J = VectorArrayOperator(J, copy=False)
            return Concatenation(J, ComponentProjection(self.source_dofs, self.source), name=self.name + '_jacobian')
コード例 #10
0
ファイル: ei.py プロジェクト: ftschindler-work/pymor
    def jacobian(self, U, mu=None):
        mu = self.parse_parameter(mu)
        options = self.solver_options.get('jacobian') if self.solver_options else None

        if len(self.interpolation_dofs) == 0:
            if isinstance(self.source, NumpyVectorSpace) and isinstance(self.range, NumpyVectorSpace):
                return NumpyMatrixOperator(np.zeros((self.range.dim, self.source.dim)), solver_options=options,
                                           source_id=self.source.id, range_id=self.range.id,
                                           name=self.name + '_jacobian')
            else:
                return ZeroOperator(self.range, self.source, name=self.name + '_jacobian')
        elif hasattr(self, 'operator'):
            return EmpiricalInterpolatedOperator(self.operator.jacobian(U, mu=mu), self.interpolation_dofs,
                                                 self.collateral_basis, self.triangular,
                                                 solver_options=options, name=self.name + '_jacobian')
        else:
            restricted_source = self.restricted_operator.source
            U_dofs = restricted_source.make_array(U.dofs(self.source_dofs))
            JU = self.restricted_operator.jacobian(U_dofs, mu=mu) \
                                         .apply(restricted_source.make_array(np.eye(len(self.source_dofs))))
            try:
                if self.triangular:
                    interpolation_coefficients = solve_triangular(self.interpolation_matrix, JU.to_numpy().T,
                                                                  lower=True, unit_diagonal=True).T
                else:
                    interpolation_coefficients = solve(self.interpolation_matrix, JU.to_numpy().T).T
            except ValueError:  # this exception occurs when AU contains NaNs ...
                interpolation_coefficients = np.empty((len(JU), len(self.collateral_basis))) + np.nan
            J = self.collateral_basis.lincomb(interpolation_coefficients)
            if isinstance(J.space, NumpyVectorSpace):
                J = NumpyMatrixOperator(J.to_numpy().T, range_id=self.range.id)
            else:
                J = VectorArrayOperator(J)
            return Concatenation([J, ComponentProjection(self.source_dofs, self.source)],
                                 solver_options=options, name=self.name + '_jacobian')
コード例 #11
0
def mpi_wrap_operator(obj_id, mpi_range, mpi_source, with_apply2=False, pickle_local_spaces=True,
                      space_type=MPIVectorSpace):
    """Wrap MPI distributed local |Operators| to a global |Operator| on rank 0.

    Given MPI distributed local |Operators| referred to by the
    :class:`~pymor.tools.mpi.ObjectId` `obj_id`, return a new |Operator|
    which manages these distributed operators from rank 0. This
    is done by instantiating :class:`MPIOperator`. Additionally, the
    structure of the wrapped operators is preserved. E.g. |LincombOperators|
    will be wrapped as a |LincombOperator| of :class:`MPIOperators <MPIOperator>`.

    Parameters
    ----------
    See :class:`MPIOperator`.

    Returns
    -------
    The wrapped |Operator|.
    """
    op = mpi.get_object(obj_id)
    if isinstance(op, LincombOperator):
        obj_ids = mpi.call(_mpi_wrap_operator_LincombOperator_manage_operators, obj_id)
        return LincombOperator([mpi_wrap_operator(o, mpi_range, mpi_source, with_apply2, pickle_local_spaces,
                                                  space_type)
                                for o in obj_ids], op.coefficients, name=op.name)
    elif isinstance(op, VectorArrayOperator):
        array_obj_id, local_spaces = mpi.call(_mpi_wrap_operator_VectorArrayOperator_manage_array,
                                              obj_id, pickle_local_spaces)
        if all(ls == local_spaces[0] for ls in local_spaces):
            local_spaces = (local_spaces[0],)
        return VectorArrayOperator(space_type(local_spaces).make_array(array_obj_id),
                                   adjoint=op.adjoint, name=op.name)
    else:
        return MPIOperator(obj_id, mpi_range, mpi_source, with_apply2, pickle_local_spaces, space_type)
コード例 #12
0
ファイル: ei.py プロジェクト: tobiasleibner/pymor
    def jacobian(self, U, mu=None):
        assert len(U) == 1
        assert self.parameters.assert_compatible(mu)
        options = self.solver_options.get(
            'jacobian') if self.solver_options else None

        if self.interpolation_matrix.shape[0] == 0:
            return NumpyMatrixOperator(np.zeros(
                (self.range.dim, self.source.dim)),
                                       solver_options=options,
                                       name=self.name + '_jacobian')

        U_dofs = self.source_basis_dofs.lincomb(U.to_numpy()[0])
        J = self.restricted_operator.jacobian(U_dofs, mu=mu).apply(
            self.source_basis_dofs)
        try:
            if self.triangular:
                interpolation_coefficients = solve_triangular(
                    self.interpolation_matrix,
                    J.to_numpy().T,
                    lower=True,
                    unit_diagonal=True).T
            else:
                interpolation_coefficients = solve(self.interpolation_matrix,
                                                   J.to_numpy().T).T
        except ValueError:  # this exception occurs when J contains NaNs ...
            interpolation_coefficients = (np.empty(
                (len(self.source_basis_dofs),
                 len(self.projected_collateral_basis))) + np.nan)
        M = self.projected_collateral_basis.lincomb(interpolation_coefficients)
        if isinstance(M.space, NumpyVectorSpace):
            return NumpyMatrixOperator(M.to_numpy().T, solver_options=options)
        else:
            assert not options
            return VectorArrayOperator(M)
コード例 #13
0
ファイル: operator.py プロジェクト: ftschindler-work/pymor
def thermalblock_vectorarray_factory(adjoint, xblocks, yblocks, diameter, seed):
    from pymor.operators.constructions import VectorArrayOperator
    _, _, U, V, sp, rp = thermalblock_factory(xblocks, yblocks, diameter, seed)
    op = VectorArrayOperator(U, adjoint)
    if adjoint:
        U = V
        V = op.range.make_array(np.random.random((7, op.range.dim)))
        sp = rp
        rp = NumpyMatrixOperator(np.eye(op.range.dim) * 2)
    else:
        U = op.source.make_array(np.random.random((7, op.source.dim)))
        sp = NumpyMatrixOperator(np.eye(op.source.dim) * 2)
    return op, None, U, V, sp, rp
コード例 #14
0
ファイル: operator.py プロジェクト: simon-ca/pymor
def thermalblock_vectorarray_factory(transposed, xblocks, yblocks, diameter, seed):
    from pymor.operators.constructions import VectorArrayOperator
    _, _, U, V, sp, rp = thermalblock_factory(xblocks, yblocks, diameter, seed)
    op = VectorArrayOperator(U, transposed)
    if transposed:
        U = V
        V = NumpyVectorArray(np.random.random((7, op.range.dim)), copy=False)
        sp = rp
        rp = NumpyMatrixOperator(np.eye(op.range.dim) * 2)
    else:
        U = NumpyVectorArray(np.random.random((7, op.source.dim)), copy=False)
        sp = NumpyMatrixOperator(np.eye(op.source.dim) * 2)
    return op, None, U, V, sp, rp
コード例 #15
0
ファイル: mpi.py プロジェクト: simon-ca/pymor
def mpi_wrap_operator(obj_id,
                      functional=False,
                      vector=False,
                      with_apply2=False,
                      pickle_subtypes=True,
                      array_type=MPIVectorArray):
    """Wrap MPI distributed local |Operators| to a global |Operator| on rank 0.

    Given MPI distributed local |Operators| referred to by the
    `~pymor.tools.mpi.ObjectId` `obj_id`, return a new |Operator|
    which manages these distributed operators from rank 0. This
    is done by instantiating :class:`MPIOperator`. Additionally, the
    structure of the wrapped operators is preserved. E.g. |LincombOperators|
    will be wrapped as a |LincombOperator| of :class:`MPIOperators`.

    Parameters
    ----------
    See :class:`MPIOperator`.

    Returns
    -------
    The wrapped |Operator|.
    """
    op = mpi.get_object(obj_id)
    if isinstance(op, LincombOperator):
        obj_ids = mpi.call(_mpi_wrap_operator_LincombOperator_manage_operators,
                           obj_id)
        return LincombOperator([
            mpi_wrap_operator(o, functional, vector, with_apply2,
                              pickle_subtypes, array_type) for o in obj_ids
        ],
                               op.coefficients,
                               name=op.name)
    elif isinstance(op, VectorArrayOperator):
        array_obj_id, subtypes = mpi.call(
            _mpi_wrap_operator_VectorArrayOperator_manage_array, obj_id,
            pickle_subtypes)
        if all(subtype == subtypes[0] for subtype in subtypes):
            subtypes = (subtypes[0], )
        return VectorArrayOperator(array_type(type(op._array), subtypes,
                                              array_obj_id),
                                   transposed=op.transposed,
                                   name=op.name)
    else:
        return MPIOperator(obj_id, functional, vector, with_apply2,
                           pickle_subtypes, array_type)
コード例 #16
0
ファイル: lincomb.py プロジェクト: deneick/pymor
    def action_VectorArrayOperator(self, ops):
        if not all(op.adjoint == ops[0].adjoint for op in ops):
            raise RuleNotMatchingError

        adjoint = ops[0].adjoint
        assert not self.solver_options

        coeffs = np.conj(self.coefficients) if adjoint else self.coefficients

        if coeffs[0] == 1:
            array = ops[0]._array.copy()
        else:
            array = ops[0]._array * coeffs[0]
        for op, c in zip(ops[1:], coeffs[1:]):
            array.axpy(c, op._array)

        return VectorArrayOperator(array, adjoint=adjoint, space_id=ops[0].space_id, name=self.name)
コード例 #17
0
ファイル: ei.py プロジェクト: michaellaier/pymor
 def jacobian(self, U, mu=None):
     assert len(U) == 1
     mu = self.parse_parameter(mu)
     U_components = self.source_basis_dofs.lincomb(U.data[0])
     J = self.restricted_operator.jacobian(U_components, mu=mu).apply(self.source_basis_dofs)
     try:
         if self.triangular:
             interpolation_coefficients = solve_triangular(self.interpolation_matrix, J.data.T,
                                                           lower=True, unit_diagonal=True).T
         else:
             interpolation_coefficients = np.linalg.solve(self.interpolation_matrix, J.data.T).T
     except ValueError:  # this exception occurs when J contains NaNs ...
         interpolation_coefficients = (np.empty((len(self.projected_collateral_basis), len(self.source_basis_dofs)))
                                       + np.nan)
     M = self.projected_collateral_basis.lincomb(interpolation_coefficients)
     if isinstance(M, NumpyVectorArray):
         return NumpyMatrixOperator(M.data.T)
     else:
         return VectorArrayOperator(M)
コード例 #18
0
    def localize_operator(self, op, range_ind, source_ind):
        if isinstance(op, VectorArrayOperator):
            assert range_ind is None
            source_ind = tuple(source_ind)
            source_subspace = self.join_spaces(source_ind)
            a = NumpyVectorSpace.make_array(op._array.data[:, source_subspace])
            result = VectorArrayOperator(a,
                                         transposed=op.transposed,
                                         name='{}-{}-{}'.format(
                                             op.name, source_ind, range_ind))
            return result

        if isinstance(op, NumpyMatrixOperator):
            # special case for functionals
            if range_ind is None:
                source_ind = tuple(source_ind)
                source_subspace = self.join_spaces(source_ind)
                m = op.matrix[source_subspace]
                result = NumpyMatrixOperator(m,
                                             name='{}-{}-{}'.format(
                                                 op.name, source_ind,
                                                 range_ind))
                return result

            source_ind = tuple(source_ind)
            range_ind = tuple(range_ind)
            op_id = getattr(op, 'sid', op.uid)
            identification_key = (op_id, source_ind, range_ind)
            if identification_key in self._resultcache:
                return self._resultcache[identification_key]

            if op_id not in self._non_zeros:
                # FIXME also handle dense case
                M = op.matrix.tocoo()
                incidences = np.empty(len(M.col),
                                      dtype=[('row', np.int32),
                                             ('col', np.int32)])
                incidences['row'] = self.subspace_map[M.row]
                incidences['col'] = self.subspace_map[M.col]
                incidences = np.unique(incidences)
                self._non_zeros[op_id] = set(incidences.tolist())

            non_zeros = self._non_zeros[op_id]
            if all((ri, si) not in non_zeros
                   for si, ri in product(source_ind, range_ind)):
                return None

            source_subspace = self.join_spaces(source_ind)
            range_subspace = self.join_spaces(range_ind)
            if issparse(op.matrix):
                m = op.matrix.tocsc()[:, source_subspace][range_subspace, :]
            else:
                m = op.matrix[:, source_subspace][range_subspace, :]

            result = NumpyMatrixOperator(m,
                                         name='{}-{}-{}'.format(
                                             op.name, source_ind, range_ind))
            self._resultcache[identification_key] = result
            return result

        elif isinstance(op, LincombOperator):
            ops = [
                self.localize_operator(o, range_ind, source_ind)
                for o in op.operators
            ]
            return LincombOperator(ops, op.coefficients)
        else:
            print("op is ", op)
            raise NotImplementedError
コード例 #19
0
ファイル: randrangefinder.py プロジェクト: deneick/pymor
from pymor.algorithms.randrangefinder import rrf, adaptive_rrf
from pymor.operators.numpy import NumpyMatrixOperator
from pymor.operators.constructions import VectorArrayOperator

np.random.seed(0)
A = uniform(low=-1.0, high=1.0, size=(100, 100))
A = A.dot(A.T)
range_product = NumpyMatrixOperator(A)

np.random.seed(1)
A = uniform(low=-1.0, high=1.0, size=(10, 10))
A = A.dot(A.T)
source_product = NumpyMatrixOperator(A)

B = range_product.range.random(10, seed=10)
op = VectorArrayOperator(B)

C = range_product.range.random(
    10, seed=11) + 1j * range_product.range.random(10, seed=12)
op_complex = VectorArrayOperator(C)


def test_rrf():
    Q = rrf(op, source_product, range_product)
    assert Q in op.range
    assert len(Q) == 8

    Q = rrf(op_complex, iscomplex=True)
    assert np.iscomplexobj(Q.data)
    assert Q in op.range
    assert len(Q) == 8