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)
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)
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)
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)