Ejemplo n.º 1
0
 def action_generic_projection(self,
                               op,
                               range_basis,
                               source_basis,
                               product=None):
     op.logger.warning('Using inefficient generic projection operator')
     return ProjectedOperator(op, range_basis, source_basis, product)
Ejemplo n.º 2
0
 def action_ProjectedOperator(self, op):
     dim_range, dim_source = self.dim_range, self.dim_source
     source_basis = op.source_basis if dim_source is None \
         else op.source_basis[:dim_source]
     range_basis = op.range_basis if dim_range is None \
         else op.range_basis[:dim_range]
     return ProjectedOperator(op.operator, range_basis, source_basis, product=None,
                              solver_options=op.solver_options)
Ejemplo n.º 3
0
def project(op, range_basis, source_basis, product=None):
    """Petrov-Galerkin projection of a given |Operator|.

    Given an inner product `( ⋅, ⋅)`, source vectors `b_1, ..., b_N`
    and range vectors `c_1, ..., c_M`, the projection `op_proj` of `op`
    is defined by ::

        [ op_proj(e_j) ]_i = ( c_i, op(b_j) )

    for all i,j, where `e_j` denotes the j-th canonical basis vector of R^N.

    In particular, if the `c_i` are orthonormal w.r.t. the given product,
    then `op_proj` is the coordinate representation w.r.t. the `b_i/c_i` bases
    of the restriction of `op` to `span(b_i)` concatenated with the
    orthogonal projection onto `span(c_i)`.

    From another point of view, if `op` is viewed as a bilinear form
    (see :meth:`apply2`) and `( ⋅, ⋅ )` is the Euclidean inner
    product, then `op_proj` represents the matrix of the bilinear form restricted
    to `span(b_i) / span(c_i)` (w.r.t. the `b_i/c_i` bases).

    How the projection is realized will depend on the given |Operator|.
    While a projected |NumpyMatrixOperator| will
    again be a |NumpyMatrixOperator|, only a generic
    :class:`~pymor.operators.basic.ProjectedOperator` can be returned
    in general. The exact algorithm is specified in :class:`ProjectRules`.

    Parameters
    ----------
    range_basis
        The vectors `c_1, ..., c_M` as a |VectorArray|. If `None`, no
        projection in the range space is performed.
    source_basis
        The vectors `b_1, ..., b_N` as a |VectorArray| or `None`. If `None`,
        no restriction of the source space is performed.
    product
        An |Operator| representing the inner product.  If `None`, the
        Euclidean inner product is chosen.

    Returns
    -------
    The projected |Operator| `op_proj`.
    """
    assert source_basis is None or source_basis in op.source
    assert range_basis is None or range_basis in op.range
    assert product is None or product.source == product.range == op.range

    rb = product.apply(range_basis) if product is not None and range_basis is not None else range_basis

    try:
        return ProjectRules(rb, source_basis).apply(op)
    except NoMatchingRuleError:
        op.logger.warning('Using inefficient generic projection operator')
        return ProjectedOperator(op, range_basis, source_basis, product)
Ejemplo n.º 4
0
 def projected(self,
               source_basis,
               range_basis,
               product=None,
               name=None):
     name = name or '{}_projected'.format(self.name)
     if self.linear:
         return ProjectedLinearOperator(self, source_basis, range_basis,
                                        product, name)
     else:
         return ProjectedOperator(self, source_basis, range_basis,
                                  product, name)