Example #1
0
 def collect_vector_ranges(op, image):
     if isinstance(op, (LincombOperator, SelectionOperator)):
         for o in op.operators:
             collect_vector_ranges(o, image)
     elif isinstance(op, AdjointOperator):
         if op.source not in image_space:
             raise ImageCollectionError(op)  # Not implemented
         operator = Concatenation(
             op.range_product,
             op.operator) if op.range_product else op.operator
         collect_operator_ranges(operator, NumpyVectorArray(np.ones(1)),
                                 image)
     elif op.linear and not op.parametric:
         image.append(op.as_vector())
     else:
         raise ImageCollectionError(op)
Example #2
0
 def collect_operator_ranges(op, source, image):
     if isinstance(op, (LincombOperator, SelectionOperator)):
         for o in op.operators:
             collect_operator_ranges(o, source, image)
     elif isinstance(op, EmpiricalInterpolatedOperator):
         if hasattr(op, 'collateral_basis') and not extends:
             image.append(op.collateral_basis)
     elif isinstance(op, Concatenation):
         firstrange = op.first.range.empty()
         collect_operator_ranges(op.first, source, firstrange)
         collect_operator_ranges(op.second, firstrange, image)
     elif op.linear and not op.parametric:
         image.append(op.apply(source))
     else:
         raise ImageCollectionError(op)
Example #3
0
def estimate_image(operators=(),
                   vectors=(),
                   domain=None,
                   extends=False,
                   orthonormalize=True,
                   product=None,
                   riesz_representatives=False):
    """Estimate the image of given |Operators| for all mu.

    Let `operators` be a list of |Operators| with common source and range, and let
    `vectors` be a list of |VectorArrays| or vector-like |Operators| in the range
    of these operators. Given a |VectorArray| `domain` of vectors in the source of the
    operators, this algorithms determines a |VectorArray| `image` of range vectors
    such that the linear span of `image` contains:

    - `op.apply(U, mu=mu)` for all operators `op` in `operators`, for all possible |Parameters|
      `mu` and for all |VectorArrays| `U` contained in the linear span of `domain`,
    - `U` for all |VectorArrays| in `vectors`,
    - `v.as_range_array(mu)` for all |Operators| in `vectors` and all possible |Parameters| `mu`.

    The algorithm will try to choose `image` as small as possible. However, no optimality
    is guaranteed. The image estimation algorithm is specified by :class:`CollectOperatorRangeRules`
    and :class:`CollectVectorRangeRules`.

    Parameters
    ----------
    operators
        See above.
    vectors
        See above.
    domain
        See above. If `None`, an empty `domain` |VectorArray| is assumed.
    extends
        For some operators, e.g. |EmpiricalInterpolatedOperator|, as well as for all
        elements of `vectors`, `image` is estimated independently from the choice of
        `domain`.  If `extends` is `True`, such operators are ignored. (This is useful
        in case these vectors have already been obtained by earlier calls to this
        function.)
    orthonormalize
        Compute an orthonormal basis for the linear span of `image` using the
        :func:`~pymor.algorithms.gram_schmidt.gram_schmidt` algorithm.
    product
        Inner product |Operator| w.r.t. which to orthonormalize.
    riesz_representatives
        If `True`, compute Riesz representatives of the vectors in `image` before
        orthonormalizing (useful for dual norm computation when the range of the
        `operators` is a dual space).

    Returns
    -------
    The |VectorArray| `image`.

    Raises
    ------
    ImageCollectionError
        Is raised when for a given |Operator| no image estimate is possible.
    """
    assert operators or vectors
    domain_space = operators[0].source if operators else None
    image_space = operators[0].range if operators \
        else vectors[0].space if isinstance(vectors[0], VectorArrayInterface) \
        else vectors[0].range
    assert all(op.source == domain_space and op.range == image_space
               for op in operators)
    assert all(
        isinstance(v, VectorArrayInterface) and (v in image_space)
        or isinstance(v, OperatorInterface) and
        (v.range == image_space and isinstance(v.source, NumpyVectorSpace)
         and v.linear) for v in vectors)
    assert domain is None or domain_space is None or domain in domain_space
    assert product is None or product.source == product.range == image_space

    image = image_space.empty()
    if not extends:
        for v in vectors:
            try:
                CollectVectorRangeRules.apply(v, image)
            except NoMatchingRuleError as e:
                raise ImageCollectionError(e.obj)

    if operators and domain is None:
        domain = domain_space.empty()
    for op in operators:
        try:
            CollectOperatorRangeRules.apply(op, domain, image, extends)
        except NoMatchingRuleError as e:
            raise ImageCollectionError(e.obj)

    if riesz_representatives and product:
        image = product.apply_inverse(image)

    if orthonormalize:
        gram_schmidt(image, product=product, copy=False)

    return image