Exemplo n.º 1
0
def ieig(A, b, s):
    '''
    Solve inhomogeneous eigenvalue problem, symmetric case:
      A x = lambda x + b
      s.t. ||x|| = s
  '''
    m, n = A.shape
    if m != n:
        print('Not a square matrix.')
        return
    
    M = _np.vstack(( _np.hstack(( A, -_np.eye(n) )),
                    _np.hstack(( -1/s**2 * _np.outer(b, b), A )) ))
    
    d, V = algorithms.sortEig(M, evs=2*n)

    e = _np.zeros((2*n))
    X = _np.zeros((n, 2*n), dtype=complex)
    for ev in range(2*n):
        gamma = V[:n, ev]
        f = gamma.conj().T @ b / s**2
        gamma = gamma/f # normalize

        z = (A - d[ev]*_np.eye(n)) @ gamma
        
        e[ev] = abs(z.conj().T @ z - s**2) # check if constraint is satisfied
     
        X[:, ev] = z
    
    ind, = _np.where(e < 1e-6) # select only valid solutions
    X = X[:, ind]
    d = d[ind]
    return d, X
Exemplo n.º 2
0
def hceig(A, N):
    '''
    Solve standard eigenvalue problem with homogeneous constraints:
      min x^T A x
      s.t. N^T x = 0
           ||x|| = 1
   '''
    n = A.shape[0]
    P = _np.eye(n) - N @ _sp.linalg.pinv(N)
    d, X = algorithms.sortEig(P @ A, evs=n)
    return d, X
Exemplo n.º 3
0
#k = kernels.polynomialKernel(7)
k = kernels.gaussianKernel(0.5)

#%% apply kernel generator EDMD
epsilon = 0.1
S = np.einsum('ijk,ljk->ilk', Z, Z)  # sigma \cdot sigma^T

G_00 = kernels.gramian(X, k)
G_10 = np.zeros((m, m))
for i in range(m):
    for j in range(m):
        G_10[i, j] = Y[:, i].T @ k.diff(X[:, i], X[:, j]) + 0.5 * np.sum(
            S[:, :, i] * k.ddiff(X[:, i], X[:, j]), axis=(0, 1))

A, _, _, _ = np.linalg.lstsq(G_00, G_10, rcond=1e-12)
d, V = algorithms.sortEig(A, evs=m, which='LM')
W = kernels.gramian2(Omega.midpointGrid(), X, k) @ V

#%% plot eigenvalues
plt.figure()
plt.plot(d, '.')
plt.title('Spectrum')

#%% plot eigenfunctions
ind, = np.where(d < -0.1)
for i in ind[:6]:
    plt.figure()
    Omega.plot(np.real(W[:, i] / np.amax(abs(W[:, i]))))
    plt.ylim((-1, 1))
    plt.title('lambda = %f' % np.real(d[i]))
Exemplo n.º 4
0
def gedmd(X, Y, Z, psi, evs=5, operator='K', kramers_moyal=False):
    """
    Generator EDMD for the Koopman operator. The matrices X and Y
    contain the input data. For stochastic systems, Z contains the
    diffusion term evaluated in all data points X. If the system is
    deterministic, set Z = None.

    Modification of 'gedmd' initially implemented in 'D3S - Data-driven
    dynamical systems toolbox' by Stefan Klus: https://github.com/sklus/d3s

    Parameters
    ----------
    X : ndarray
        Input data.
    Y : ndarray
        Input data.
    Z : ndarray
        Input data.
    psi : d3s.observables
        Basis functions.
    evs : int, optional
        Number of eigenvalues to be computed. The default is 5.
    operator : string, optional
        Koopman generator (K) or Perron-Frobenius generator (P).
        The default is 'K'.
    kramers_moyal : bool, optional
        If Z is estimated by the Kramers-Moyal formula, set True. This
        corresponds to Z = sigma * sigma^T. If Z = sigma, set False.
        The default is False.

    Returns
    -------
    A : ndarray
        Matrix approximation of the Koopman or Perron-Frobenius generator.
    d : ndarray
        Eigenvalues of A.
    V : ndarray
        Right eigenvectors of A, which are interpreted as the eigenfunctions
        of the generator.

    """

    PsiX = psi(X)
    dPsiY = np.einsum('ijk,jk->ik', psi.diff(X), Y)
    # stochastic dynamical system
    if not (Z is None):
        # number of basis functions
        n = PsiX.shape[0]
        # second-order derivatives
        ddPsiX = psi.ddiff(X)
        if kramers_moyal:
            S = Z
        else:
            # Compute sigma \cdot sigma^T
            S = np.einsum('ijk,ljk->ilk', Z, Z)
        for i in range(n):
            dPsiY[i, :] += 0.5 * np.sum(ddPsiX[i, :, :, :] * S, axis=(0, 1))

    C_0 = PsiX @ PsiX.T
    C_1 = PsiX @ dPsiY.T
    if operator == 'P':
        C_1 = C_1.T

    A = sp.linalg.pinv(C_0) @ C_1

    if evs > 0:
        d, V = sortEig(A, evs, which='SM')
    else:
        d = None
        V = None

    return (A, d, V)
Exemplo n.º 5
0
X = Omega.rand(m)

#%% define kernel
k = kernels.gaussianKernel(0.3)

#%% apply kernel generator EDMD
evs = 4
G_00 = kernels.gramian(X, k)
G_10 = np.zeros((m, m))
for i in range(m):
    for j in range(m):
        G_10[i, j] = c0(X[:, i]) * k(X[:, i], X[:, j]) + np.sum(
            c2(X[:, i]) * k.ddiff(X[:, i], X[:, j]), axis=(0, 1))

A, _, _, _ = np.linalg.lstsq(G_00, G_10, rcond=1e-12)
d, V = algorithms.sortEig(A, evs=evs, which='SR')

c = Omega.midpointGrid()
W = kernels.gramian2(c, X, k) @ V

#%% plot spectrum
plt.figure()
plt.plot(np.real(d), '.')
plt.title('Spectrum')

printVector(np.real(d), 'd')

#%% plot eigenfunctions
for i in range(evs):
    plt.figure()
    j = evs - i - 1
Exemplo n.º 6
0
for i in range(evs):
    psi.display(np.real(V[:, i]), 2, 'phi_%d' % (i + 1))
print('')

# system identification
B = np.zeros((K.shape[0], Omega.dimension()))
B[1, 0] = 1
B[2, 1] = 1

b_c = K @ B  # coefficients of the identified system
psi.display(np.real(b_c[:, 0]), 2, 'b_1')
psi.display(np.real(b_c[:, 1]), 2, 'b_2')
print('')

# system identification 2 (using Koopman modes)
[d, V] = algorithms.sortEig(K, K.shape[0])

W = B.T @ sp.linalg.inv(V).T
printMatrix(np.real(W), 'W')

psi.display(np.real(W[0, 2] * d[2] * V[:, 2]), 2, 'b_1')
psi.display(np.real(W[1, 1] * d[1] * V[:, 1] + W[1, 5] * d[5] * V[:, 5]), 2,
            'b_2')

#%% pendulum conservation laws --------------------------------------------------------------------

# define domain
bounds = sp.array([[-2, 2], [-2, 2]])
boxes = sp.array([50, 50])
Omega = domain.discretization(bounds, boxes)