Ejemplo n.º 1
0
 def apply_inverse_adjoint(self, U, ind=None, mu=None, source_product=None, range_product=None,
                           least_squares=False):
     from pymor.operators.constructions import FixedParameterOperator
     assembled_op = self.assemble(mu)
     if assembled_op != self and not isinstance(assembled_op, FixedParameterOperator):
         return assembled_op.apply_inverse_adjoint(U, ind=ind, source_product=source_product,
                                                   range_product=range_product, least_squares=least_squares)
     elif source_product or range_product:
         if source_product:
             U = source_product.apply(U, ind=ind)
             ind = None
         # maybe there is a better implementation for source_product == None and range_product == None
         V = self.apply_inverse_adjoint(U, mu=mu, least_squares=least_squares)
         if range_product:
             return range_product.apply_inverse(V)
         else:
             return V
     else:
         if not self.linear:
             raise NotImplementedError
         # use generic solver for the adjoint operator
         from pymor.operators.constructions import AdjointOperator
         options = {'inverse': self.solver_options.get('inverse_adjoint') if self.solver_options else None}
         adjoint_op = AdjointOperator(self, with_apply_inverse=False, solver_options=options)
         return adjoint_op.apply_inverse(U, ind=ind, mu=mu, least_squares=least_squares)
Ejemplo n.º 2
0
    def apply_inverse_adjoint(self, U, mu=None, least_squares=False):
        """Apply the inverse adjoint operator.

        Parameters
        ----------
        U
            |VectorArray| of vectors to which the inverse adjoint operator is applied.
        mu
            The |Parameter| for which to evaluate the inverse adjoint operator.
        least_squares
            If `True`, solve the least squares problem::

                v = argmin ||op^*(v) - u||_2.

            Since for an invertible operator the least squares solution agrees
            with the result of the application of the inverse operator,
            setting this option should, in general, have no effect on the result
            for those operators. However, note that when no appropriate
            |solver_options| are set for the operator, most operator
            implementations will choose a least squares solver by default which
            may be undesirable.

        Returns
        -------
        |VectorArray| of the inverse adjoint operator evaluations.

        Raises
        ------
        InversionError
            The operator could not be inverted.
        """
        from pymor.operators.constructions import FixedParameterOperator
        if not self.linear:
            raise LinAlgError('Operator not linear.')
        assembled_op = self.assemble(mu)
        if assembled_op != self and not isinstance(assembled_op,
                                                   FixedParameterOperator):
            return assembled_op.apply_inverse_adjoint(
                U, least_squares=least_squares)
        else:
            # use generic solver for the adjoint operator
            from pymor.operators.constructions import AdjointOperator
            options = {
                'inverse':
                self.solver_options.get('inverse_adjoint')
                if self.solver_options else None
            }
            adjoint_op = AdjointOperator(self,
                                         with_apply_inverse=False,
                                         solver_options=options)
            return adjoint_op.apply_inverse(U,
                                            mu=mu,
                                            least_squares=least_squares)
Ejemplo n.º 3
0
 def apply_inverse_adjoint(self, U, mu=None, least_squares=False):
     from pymor.operators.constructions import FixedParameterOperator
     if not self.linear:
         raise LinAlgError('Operator not linear.')
     assembled_op = self.assemble(mu)
     if assembled_op != self and not isinstance(assembled_op, FixedParameterOperator):
         return assembled_op.apply_inverse_adjoint(U, least_squares=least_squares)
     else:
         # use generic solver for the adjoint operator
         from pymor.operators.constructions import AdjointOperator
         options = {'inverse': self.solver_options.get('inverse_adjoint') if self.solver_options else None}
         adjoint_op = AdjointOperator(self, with_apply_inverse=False, solver_options=options)
         return adjoint_op.apply_inverse(U, mu=mu, least_squares=least_squares)
Ejemplo n.º 4
0
 def apply_inverse_transpose(self, U, mu=None, least_squares=False):
     from pymor.operators.constructions import FixedParameterOperator
     assembled_op = self.assemble(mu)
     if assembled_op != self and not isinstance(assembled_op, FixedParameterOperator):
         return assembled_op.apply_inverse_transpose(U, least_squares=least_squares)
     else:
         if not self.linear:
             raise NotImplementedError
         # use generic solver for the transpose operator
         from pymor.operators.constructions import AdjointOperator
         options = {'inverse': self.solver_options.get('inverse_transpose') if self.solver_options else None}
         transpose_op = AdjointOperator(self, with_apply_inverse=False, solver_options=options)
         return transpose_op.apply_inverse(U, mu=mu, least_squares=least_squares)
Ejemplo n.º 5
0
 def apply_inverse_transpose(self, U, mu=None, least_squares=False):
     from pymor.operators.constructions import FixedParameterOperator
     assembled_op = self.assemble(mu)
     if assembled_op != self and not isinstance(assembled_op, FixedParameterOperator):
         return assembled_op.apply_inverse_transpose(U, least_squares=least_squares)
     else:
         if not self.linear:
             raise NotImplementedError
         # use generic solver for the transpose operator
         from pymor.operators.constructions import AdjointOperator
         options = {'inverse': self.solver_options.get('inverse_transpose') if self.solver_options else None}
         transpose_op = AdjointOperator(self, with_apply_inverse=False, solver_options=options)
         return transpose_op.apply_inverse(U, mu=mu, least_squares=least_squares)
Ejemplo n.º 6
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)
Ejemplo n.º 7
0
 def apply_inverse_adjoint(self,
                           U,
                           ind=None,
                           mu=None,
                           source_product=None,
                           range_product=None,
                           least_squares=False):
     from pymor.operators.constructions import FixedParameterOperator
     assembled_op = self.assemble(mu)
     if assembled_op != self and not isinstance(assembled_op,
                                                FixedParameterOperator):
         return assembled_op.apply_inverse_adjoint(
             U,
             ind=ind,
             source_product=source_product,
             range_product=range_product,
             least_squares=least_squares)
     elif source_product or range_product:
         if source_product:
             U = source_product.apply(U, ind=ind)
             ind = None
         # maybe there is a better implementation for source_product == None and range_product == None
         V = self.apply_inverse_adjoint(U,
                                        mu=mu,
                                        least_squares=least_squares)
         if range_product:
             return range_product.apply_inverse(V)
         else:
             return V
     else:
         if not self.linear:
             raise NotImplementedError
         # use generic solver for the adjoint operator
         from pymor.operators.constructions import AdjointOperator
         options = {
             'inverse':
             self.solver_options.get('inverse_adjoint')
             if self.solver_options else None
         }
         adjoint_op = AdjointOperator(self,
                                      with_apply_inverse=False,
                                      solver_options=options)
         return adjoint_op.apply_inverse(U,
                                         ind=ind,
                                         mu=mu,
                                         least_squares=least_squares)
Ejemplo n.º 8
0
    def action_AdjointOperator(self, op):
        range_basis, source_basis = self.range_basis, self.source_basis
        if range_basis is not None:
            if op.source_product:
                range_basis = op.source_product.apply_inverse(range_basis)

        if source_basis is not None and op.range_product:
            source_basis = op.range_product.apply(source_basis)

        operator = project(op.operator, source_basis, range_basis)
        range_product = op.range_product if source_basis is None else None
        source_product = op.source_product if range_basis is None else None
        return AdjointOperator(operator, source_product=source_product, range_product=range_product,
                               name=op.name)
Ejemplo n.º 9
0
def test_to_matrix_AdjointOperator():
    np.random.seed(0)
    A = np.random.randn(2, 2)
    S = np.random.randn(2, 2)
    S = S.dot(S.T)
    R = np.random.randn(2, 2)
    R = R.dot(R.T)

    Aop = NumpyMatrixOperator(A)
    Aadj = AdjointOperator(Aop)
    assert_type_and_allclose(A.T, Aadj, 'dense')

    Aop = NumpyMatrixOperator(sps.csc_matrix(A))
    Aadj = AdjointOperator(Aop)
    assert_type_and_allclose(A.T, Aadj, 'sparse')

    Aop = NumpyMatrixOperator(A)
    Sop = NumpyMatrixOperator(S)
    Rop = NumpyMatrixOperator(R)
    Aadj = AdjointOperator(Aop, source_product=Sop, range_product=Rop)
    assert_type_and_allclose(spla.solve(S, A.T.dot(R)), Aadj, 'dense')

    Aop = NumpyMatrixOperator(sps.csc_matrix(A))
    Sop = NumpyMatrixOperator(S)
    Rop = NumpyMatrixOperator(R)
    Aadj = AdjointOperator(Aop, source_product=Sop, range_product=Rop)
    assert_type_and_allclose(spla.solve(S, A.T.dot(R)), Aadj, 'dense')

    Aop = NumpyMatrixOperator(A)
    Sop = NumpyMatrixOperator(S)
    Rop = NumpyMatrixOperator(sps.csc_matrix(R))
    Aadj = AdjointOperator(Aop, source_product=Sop, range_product=Rop)
    assert_type_and_allclose(spla.solve(S, A.T.dot(R)), Aadj, 'dense')

    Aop = NumpyMatrixOperator(sps.csc_matrix(A))
    Sop = NumpyMatrixOperator(sps.csc_matrix(S))
    Rop = NumpyMatrixOperator(sps.csc_matrix(R))
    Aadj = AdjointOperator(Aop, source_product=Sop, range_product=Rop)
    assert_type_and_allclose(spla.solve(S, A.T.dot(R)), Aadj, 'sparse')
Ejemplo n.º 10
0
 def H(self):
     from pymor.operators.constructions import AdjointOperator
     return AdjointOperator(self)
Ejemplo n.º 11
0
def misc_operator_with_arrays_and_products_factory(n):
    if n == 0:
        from pymor.operators.constructions import ComponentProjection
        _, _, U, V, sp, rp = numpy_matrix_operator_with_arrays_and_products_factory(
            100, 10, 4, 3, n)
        op = ComponentProjection(np.random.randint(0, 100, 10), U.space)
        return op, _, U, V, sp, rp
    elif n == 1:
        from pymor.operators.constructions import ComponentProjection
        _, _, U, V, sp, rp = numpy_matrix_operator_with_arrays_and_products_factory(
            100, 0, 4, 3, n)
        op = ComponentProjection([], U.space)
        return op, _, U, V, sp, rp
    elif n == 2:
        from pymor.operators.constructions import ComponentProjection
        _, _, U, V, sp, rp = numpy_matrix_operator_with_arrays_and_products_factory(
            100, 3, 4, 3, n)
        op = ComponentProjection([3, 3, 3], U.space)
        return op, _, U, V, sp, rp
    elif n == 3:
        from pymor.operators.constructions import AdjointOperator
        op, _, U, V, sp, rp = numpy_matrix_operator_with_arrays_and_products_factory(
            100, 20, 4, 3, n)
        op = AdjointOperator(op, with_apply_inverse=True)
        return op, _, V, U, rp, sp
    elif n == 4:
        from pymor.operators.constructions import AdjointOperator
        op, _, U, V, sp, rp = numpy_matrix_operator_with_arrays_and_products_factory(
            100, 20, 4, 3, n)
        op = AdjointOperator(op, with_apply_inverse=False)
        return op, _, V, U, rp, sp
    elif 5 <= n <= 7:
        from pymor.operators.constructions import SelectionOperator
        from pymor.parameters.functionals import ProjectionParameterFunctional
        op0, _, U, V, sp, rp = numpy_matrix_operator_with_arrays_and_products_factory(
            30, 30, 4, 3, n)
        op1 = NumpyMatrixOperator(np.random.random((30, 30)))
        op2 = NumpyMatrixOperator(np.random.random((30, 30)))
        op = SelectionOperator([op0, op1, op2],
                               ProjectionParameterFunctional('x'), [0.3, 0.6])
        return op, op.parameters.parse((n - 5) / 2), V, U, rp, sp
    elif n == 8:
        from pymor.operators.block import BlockDiagonalOperator
        op0, _, U0, V0, sp0, rp0 = numpy_matrix_operator_with_arrays_and_products_factory(
            10, 10, 4, 3, n)
        op1, _, U1, V1, sp1, rp1 = numpy_matrix_operator_with_arrays_and_products_factory(
            20, 20, 4, 3, n + 1)
        op2, _, U2, V2, sp2, rp2 = numpy_matrix_operator_with_arrays_and_products_factory(
            30, 30, 4, 3, n + 2)
        op = BlockDiagonalOperator([op0, op1, op2])
        sp = BlockDiagonalOperator([sp0, sp1, sp2])
        rp = BlockDiagonalOperator([rp0, rp1, rp2])
        U = op.source.make_array([U0, U1, U2])
        V = op.range.make_array([V0, V1, V2])
        return op, _, U, V, sp, rp
    elif n == 9:
        from pymor.operators.block import BlockDiagonalOperator, BlockOperator
        from pymor.parameters.functionals import ProjectionParameterFunctional
        op0a, _, U0, V0, sp0, rp0 = numpy_matrix_operator_with_arrays_and_products_factory(
            10, 10, 4, 3, n)
        op0b, _, _, _, _, _ = numpy_matrix_operator_with_arrays_and_products_factory(
            10, 10, 4, 3, n)
        op0c, _, _, _, _, _ = numpy_matrix_operator_with_arrays_and_products_factory(
            10, 10, 4, 3, n)
        op1, _, U1, V1, sp1, rp1 = numpy_matrix_operator_with_arrays_and_products_factory(
            20, 20, 4, 3, n + 1)
        op2a, _, _, _, _, _ = numpy_matrix_operator_with_arrays_and_products_factory(
            20, 10, 4, 3, n + 2)
        op2b, _, _, _, _, _ = numpy_matrix_operator_with_arrays_and_products_factory(
            20, 10, 4, 3, n + 2)
        op0 = (op0a * ProjectionParameterFunctional('p', 3, 0) +
               op0b * ProjectionParameterFunctional('p', 3, 1) +
               op0c * ProjectionParameterFunctional('p', 3, 1))
        op2 = (op2a * ProjectionParameterFunctional('p', 3, 0) +
               op2b * ProjectionParameterFunctional('q', 1))
        op = BlockOperator([[op0, op2], [None, op1]])
        mu = op.parameters.parse({'p': [1, 2, 3], 'q': 4})
        sp = BlockDiagonalOperator([sp0, sp1])
        rp = BlockDiagonalOperator([rp0, rp1])
        U = op.source.make_array([U0, U1])
        V = op.range.make_array([V0, V1])
        return op, mu, U, V, sp, rp
    elif n == 10:
        from pymor.operators.block import BlockDiagonalOperator, BlockColumnOperator
        from pymor.parameters.functionals import ProjectionParameterFunctional
        op0, _, U0, V0, sp0, rp0 = numpy_matrix_operator_with_arrays_and_products_factory(
            10, 10, 4, 3, n)
        op1, _, U1, V1, sp1, rp1 = numpy_matrix_operator_with_arrays_and_products_factory(
            20, 20, 4, 3, n + 1)
        op2a, _, _, _, _, _ = numpy_matrix_operator_with_arrays_and_products_factory(
            20, 10, 4, 3, n + 2)
        op2b, _, _, _, _, _ = numpy_matrix_operator_with_arrays_and_products_factory(
            20, 10, 4, 3, n + 2)
        op2 = (op2a * ProjectionParameterFunctional('p', 3, 0) +
               op2b * ProjectionParameterFunctional('q', 1))
        op = BlockColumnOperator([op2, op1])
        mu = op.parameters.parse({'p': [1, 2, 3], 'q': 4})
        sp = sp1
        rp = BlockDiagonalOperator([rp0, rp1])
        U = U1
        V = op.range.make_array([V0, V1])
        return op, mu, U, V, sp, rp
    elif n == 11:
        from pymor.operators.block import BlockDiagonalOperator, BlockRowOperator
        from pymor.parameters.functionals import ProjectionParameterFunctional
        op0, _, U0, V0, sp0, rp0 = numpy_matrix_operator_with_arrays_and_products_factory(
            10, 10, 4, 3, n)
        op1, _, U1, V1, sp1, rp1 = numpy_matrix_operator_with_arrays_and_products_factory(
            20, 20, 4, 3, n + 1)
        op2a, _, _, _, _, _ = numpy_matrix_operator_with_arrays_and_products_factory(
            20, 10, 4, 3, n + 2)
        op2b, _, _, _, _, _ = numpy_matrix_operator_with_arrays_and_products_factory(
            20, 10, 4, 3, n + 2)
        op2 = (op2a * ProjectionParameterFunctional('p', 3, 0) +
               op2b * ProjectionParameterFunctional('q', 1))
        op = BlockRowOperator([op0, op2])
        mu = op.parameters.parse({'p': [1, 2, 3], 'q': 4})
        sp = BlockDiagonalOperator([sp0, sp1])
        rp = rp0
        U = op.source.make_array([U0, U1])
        V = V0
        return op, mu, U, V, sp, rp
    else:
        assert False
Ejemplo n.º 12
0
def misc_operator_with_arrays_and_products_factory(n):
    if n == 0:
        from pymor.operators.constructions import ComponentProjection
        _, _, U, V, sp, rp = numpy_matrix_operator_with_arrays_and_products_factory(100, 10, 4, 3, n)
        op = ComponentProjection(np.random.randint(0, 100, 10), U.space)
        return op, _, U, V, sp, rp
    elif n == 1:
        from pymor.operators.constructions import ComponentProjection
        _, _, U, V, sp, rp = numpy_matrix_operator_with_arrays_and_products_factory(100, 0, 4, 3, n)
        op = ComponentProjection([], U.space)
        return op, _, U, V, sp, rp
    elif n == 2:
        from pymor.operators.constructions import ComponentProjection
        _, _, U, V, sp, rp = numpy_matrix_operator_with_arrays_and_products_factory(100, 3, 4, 3, n)
        op = ComponentProjection([3, 3, 3], U.space)
        return op, _, U, V, sp, rp
    elif n == 3:
        from pymor.operators.constructions import AdjointOperator
        op, _, U, V, sp, rp = numpy_matrix_operator_with_arrays_and_products_factory(100, 20, 4, 3, n)
        op = AdjointOperator(op, with_apply_inverse=True)
        return op, _, V, U, rp, sp
    elif n == 4:
        from pymor.operators.constructions import AdjointOperator
        op, _, U, V, sp, rp = numpy_matrix_operator_with_arrays_and_products_factory(100, 20, 4, 3, n)
        op = AdjointOperator(op, with_apply_inverse=False)
        return op, _, V, U, rp, sp
    elif 5 <= n <= 7:
        from pymor.operators.constructions import SelectionOperator
        from pymor.parameters.functionals import ProjectionParameterFunctional
        op0, _, U, V, sp, rp = numpy_matrix_operator_with_arrays_and_products_factory(30, 30, 4, 3, n)
        op1 = NumpyMatrixOperator(np.random.random((30, 30)))
        op2 = NumpyMatrixOperator(np.random.random((30, 30)))
        op = SelectionOperator([op0, op1, op2], ProjectionParameterFunctional('x', ()), [0.3, 0.6])
        return op, op.parse_parameter((n-5)/2), V, U, rp, sp
    elif n == 8:
        from pymor.operators.block import BlockDiagonalOperator
        from pymor.vectorarrays.block import BlockVectorArray
        op0, _, U0, V0, sp0, rp0 = numpy_matrix_operator_with_arrays_and_products_factory(10, 10, 4, 3, n)
        op1, _, U1, V1, sp1, rp1 = numpy_matrix_operator_with_arrays_and_products_factory(20, 20, 4, 3, n+1)
        op2, _, U2, V2, sp2, rp2 = numpy_matrix_operator_with_arrays_and_products_factory(30, 30, 4, 3, n+2)
        op = BlockDiagonalOperator([op0, op1, op2])
        sp = BlockDiagonalOperator([sp0, sp1, sp2])
        rp = BlockDiagonalOperator([rp0, rp1, rp2])
        U = BlockVectorArray([U0, U1, U2])
        V = BlockVectorArray([V0, V1, V2])
        return op, _, U, V, sp, rp
    elif n == 9:
        from pymor.operators.block import BlockDiagonalOperator, BlockOperator
        from pymor.vectorarrays.block import BlockVectorArray
        op0, _, U0, V0, sp0, rp0 = numpy_matrix_operator_with_arrays_and_products_factory(10, 10, 4, 3, n)
        op1, _, U1, V1, sp1, rp1 = numpy_matrix_operator_with_arrays_and_products_factory(20, 20, 4, 3, n+1)
        op2, _, U2, V2, sp2, rp2 = numpy_matrix_operator_with_arrays_and_products_factory(20, 10, 4, 3, n+2)
        op = BlockOperator([[op0, op2],
                            [None, op1]])
        sp = BlockDiagonalOperator([sp0, sp1])
        rp = BlockDiagonalOperator([rp0, rp1])
        U = BlockVectorArray([U0, U1])
        V = BlockVectorArray([V0, V1])
        return op, None, U, V, sp, rp
    else:
        assert False