Ejemplo n.º 1
0
    def sample_randomly(self, count=None, random_state=None, seed=None):
        """Randomly sample |Parameters| from the space.

        Parameters
        ----------
        count
            `None` or number of random parameters (see below).
        random_state
            :class:`~numpy.random.RandomState` to use for sampling.
            If `None`, a new random state is generated using `seed`
            as random seed, or the :func:`default <pymor.tools.random.default_random_state>`
            random state is used.
        seed
            If not `None`, a new radom state with this seed is used.

        Returns
        -------
        If `count` is `None`, an inexhaustible iterator returning random
        |Parameters|.
        Otherwise a list of `count` random |Parameters|.
        """
        assert not random_state or seed is None
        ranges = self.ranges
        random_state = get_random_state(random_state, seed)
        get_param = lambda: Parameter(((k, random_state.uniform(ranges[k][0], ranges[k][1], shp))
                                       for k, shp in self.parameter_type.items()))
        if count is None:
            def param_generator():
                while True:
                    yield get_param()
            return param_generator()
        else:
            return [get_param() for _ in range(count)]
Ejemplo n.º 2
0
    def sample_randomly(self, count=None, random_state=None, seed=None):
        """Randomly sample |Parameters| from the space.

        Parameters
        ----------
        count
            `None` or number of random parameters (see below).
        random_state
            :class:`~numpy.random.RandomState` to use for sampling.
            If `None`, a new random state is generated using `seed`
            as random seed, or the :func:`default <pymor.tools.random.default_random_state>`
            random state is used.
        seed
            If not `None`, a new radom state with this seed is used.

        Returns
        -------
        If `count` is `None`, an inexhaustible iterator returning random
        |Parameters|.
        Otherwise a list of `count` random |Parameters|.
        """
        assert not random_state or seed is None
        ranges = self.ranges
        random_state = get_random_state(random_state, seed)
        get_param = lambda: Parameter(((k, random_state.uniform(ranges[k][0], ranges[k][1], shp))
                                       for k, shp in self.parameter_type.items()))
        if count is None:
            def param_generator():
                while True:
                    yield get_param()
            return param_generator()
        else:
            return [get_param() for _ in range(count)]
Ejemplo n.º 3
0
def projection_shifts_init(A, E, B, shift_options):
    """Find starting shift parameters for low-rank ADI iteration using
    Galerkin projection on spaces spanned by LR-ADI iterates.

    See :cite:`PK16`, pp. 92-95.

    Parameters
    ----------
    A
        The |Operator| A from the corresponding Lyapunov equation.
    E
        The |Operator| E from the corresponding Lyapunov equation.
    B
        The |VectorArray| B from the corresponding Lyapunov equation.
    shift_options
        The shift options to use (see :func:`lyap_lrcf_solver_options`).

    Returns
    -------
    shifts
        A |NumPy array| containing a set of stable shift parameters.
    """
    random_state = get_random_state(seed=shift_options['init_seed'])
    for i in range(shift_options['init_maxiter']):
        Q = gram_schmidt(B, atol=0, rtol=0)
        shifts = spla.eigvals(A.apply2(Q, Q), E.apply2(Q, Q))
        shifts = shifts[shifts.real < 0]
        if shifts.size == 0:
            # use random subspace instead of span{B} (with same dimensions)
            B = B.random(len(B), distribution='normal', random_state=random_state)
        else:
            return shifts
    raise RuntimeError('Could not generate initial shifts for low-rank ADI iteration.')
Ejemplo n.º 4
0
Archivo: lradi.py Proyecto: pymor/pymor
def projection_shifts_init(A, E, B, shift_options):
    """Find starting shift parameters for low-rank ADI iteration using
    Galerkin projection on spaces spanned by LR-ADI iterates.

    See [PK16]_, pp. 92-95.

    Parameters
    ----------
    A
        The |Operator| A from the corresponding Lyapunov equation.
    E
        The |Operator| E from the corresponding Lyapunov equation.
    B
        The |VectorArray| B from the corresponding Lyapunov equation.
    shift_options
        The shift options to use (see :func:`lyap_lrcf_solver_options`).

    Returns
    -------
    shifts
        A |NumPy array| containing a set of stable shift parameters.
    """
    random_state = get_random_state(seed=shift_options['init_seed'])
    for i in range(shift_options['init_maxiter']):
        Q = gram_schmidt(B, atol=0, rtol=0)
        shifts = spla.eigvals(A.apply2(Q, Q), E.apply2(Q, Q))
        shifts = shifts[shifts.real < 0]
        if shifts.size == 0:
            # use random subspace instead of span{B} (with same dimensions)
            B = B.random(len(B), distribution='normal', random_state=random_state)
        else:
            return shifts
    raise RuntimeError('Could not generate initial shifts for low-rank ADI iteration.')
Ejemplo n.º 5
0
Archivo: numpy.py Proyecto: pymor/pymor
 def random(self, count=1, distribution='uniform', random_state=None, seed=None, reserve=0, **kwargs):
     assert count >= 0
     assert reserve >= 0
     assert random_state is None or seed is None
     random_state = get_random_state(random_state, seed)
     va = self.zeros(count, reserve)
     va._array[:count] = _create_random_values((count, self.dim), distribution, random_state, **kwargs)
     return va
Ejemplo n.º 6
0
 def random(self, count=1, distribution='uniform', random_state=None, seed=None, reserve=0, **kwargs):
     assert count >= 0
     assert reserve >= 0
     assert random_state is None or seed is None
     random_state = get_random_state(random_state, seed)
     va = self.zeros(count, reserve)
     va._array[:count] = _create_random_values((count, self.dim), distribution, random_state, **kwargs)
     return va
Ejemplo n.º 7
0
 def random(self,
            count=1,
            distribution='uniform',
            random_state=None,
            seed=None,
            reserve=0,
            **kwargs):
     assert count >= 0 and reserve >= 0
     assert random_state is None or seed is None
     random_state = get_random_state(random_state, seed)
     return ListVectorArray([
         self.random_vector(
             distribution=distribution, random_state=random_state, **kwargs)
         for _ in range(count)
     ], self)
Ejemplo n.º 8
0
    def random(self,
               count=1,
               distribution='uniform',
               random_state=None,
               seed=None,
               reserve=0,
               **kwargs):
        """Create a |VectorArray| of vectors with random entries.

        Supported random distributions::

            'uniform': Uniform distribution in half-open interval
                       [`low`, `high`).
            'normal':  Normal (Gaussian) distribution with mean
                       `loc` and standard deviation `scale`.

        Note that not all random distributions are necessarily implemented
        by all |VectorSpace| implementations.

        Parameters
        ----------
        count
            The number of vectors.
        distribution
            Random distribution to use (`'uniform'`, `'normal'`).
        low
            Lower bound for `'uniform'` distribution (defaults to `0`).
        high
            Upper bound for `'uniform'` distribution (defaults to `1`).
        loc
            Mean for `'normal'` distribution (defaults to `0`).
        scale
            Standard deviation for `'normal'` distribution (defaults to `1`).
        random_state
            :class:`~numpy.random.RandomState` to use for sampling.
            If `None`, a new random state is generated using `seed`
            as random seed, or the :func:`default <pymor.tools.random.default_random_state>`
            random state is used.
        seed
            If not `None`, a new radom state with this seed is used.
        reserve
            Hint for the backend to which length the array will grow.
        """
        assert random_state is None or seed is None
        random_state = get_random_state(random_state, seed)
        values = _create_random_values((count, self.dim), distribution,
                                       random_state, **kwargs)
        return self.from_numpy(values)
Ejemplo n.º 9
0
    def random(self, count=1, distribution='uniform', random_state=None, seed=None, reserve=0, **kwargs):
        """Create a |VectorArray| of vectors with random entries.

        Supported random distributions::

            'uniform': Uniform distribution in half-open interval
                       [`low`, `high`).
            'normal':  Normal (Gaussian) distribution with mean
                       `loc` and standard deviation `scale`.

        Note that not all random distributions are necessarily implemented
        by all |VectorSpace| implementations.

        Parameters
        ----------
        count
            The number of vectors.
        distribution
            Random distribution to use (`'uniform'`, `'normal'`).
        low
            Lower bound for `'uniform'` distribution (defaults to `0`).
        high
            Upper bound for `'uniform'` distribution (defaults to `1`).
        loc
            Mean for `'normal'` distribution (defaults to `0`).
        scale
            Standard deviation for `'normal'` distribution (defaults to `1`).
        random_state
            :class:`~numpy.random.RandomState` to use for sampling.
            If `None`, a new random state is generated using `seed`
            as random seed, or the :func:`default <pymor.tools.random.default_random_state>`
            random state is used.
        seed
            If not `None`, a new radom state with this seed is used.
        reserve
            Hint for the backend to which length the array will grow.
        """
        assert random_state is None or seed is None
        random_state = get_random_state(random_state, seed)
        values = _create_random_values((count, self.dim), distribution, random_state, **kwargs)
        return self.from_numpy(values)
Ejemplo n.º 10
0
Archivo: list.py Proyecto: pymor/pymor
 def random(self, count=1, distribution='uniform', random_state=None, seed=None, reserve=0, **kwargs):
     assert count >= 0 and reserve >= 0
     assert random_state is None or seed is None
     random_state = get_random_state(random_state, seed)
     return ListVectorArray([self.random_vector(distribution=distribution, random_state=random_state, **kwargs)
                             for _ in range(count)], self)
Ejemplo n.º 11
0
def hamiltonian_shifts_init(A, E, B, C, shift_options):
    """Compute initial shift parameters for low-rank RADI iteration.

    Compute Galerkin projection of Hamiltonian matrix on space spanned by :math:`C` and return the
    eigenvalue of the projected Hamiltonian with the most impact on convergence as the next shift
    parameter.

    See [BBKS18]_, pp. 318-321.

    Parameters
    ----------
    A
        The |Operator| A from the corresponding Riccati equation.
    E
        The |Operator| E from the corresponding Riccati equation.
    B
        The |VectorArray| B from the corresponding Riccati equation.
    C
        The |VectorArray| C from the corresponding Riccati equation.
    shift_options
        The shift options to use (see :func:`ricc_lrcf_solver_options`).

    Returns
    -------
    shifts
        A |NumPy array| containing a set of stable shift parameters.
    """
    random_state = get_random_state(seed=shift_options['init_seed'])
    for _ in range(shift_options['init_maxiter']):
        Q = gram_schmidt(C, atol=0, rtol=0)
        Ap = A.apply2(Q, Q)
        QB = Q.dot(B)
        Gp = QB.dot(QB.T)
        QR = Q.dot(C)
        Rp = QR.dot(QR.T)
        Hp = np.block([[Ap, Gp], [Rp, -Ap.T]])
        Ep = E.apply2(Q, Q)
        EEp = spla.block_diag(Ep, Ep.T)
        eigvals, eigvecs = spla.eig(Hp, EEp)
        eigpairs = zip(eigvals, eigvecs)
        # filter stable eigenvalues
        eigpairs = list(filter(lambda e: e[0].real < 0, eigpairs))
        if len(eigpairs) == 0:
            # use random subspace instead of span{C} (with same dimensions)
            C = C.random(len(C),
                         distribution='normal',
                         random_state=random_state)
            continue
        # find shift with most impact on convergence
        maxval = -1
        maxind = 0
        for i in range(len(eigpairs)):
            eig = eigpairs[i][1]
            y_eig = eig[-len(Q):]
            x_eig = eig[:len(Q)]
            Ey = Ep.T.dot(y_eig)
            xEy = np.abs(np.dot(x_eig, Ey))
            currval = np.linalg.norm(y_eig)**2 / xEy
            if currval > maxval:
                maxval = currval
                maxind = i
        shift = eigpairs[maxind][0]
        # remove imaginary part if it is relatively small
        if np.abs(shift.imag) / np.abs(shift) < 1e-8:
            shift = shift.real
        return np.array([shift])
    raise RuntimeError(
        'Could not generate initial shifts for low-rank RADI iteration.')