Beispiel #1
0
def lyapunov_first(args,
                   initial_cinditions=[-1.5, -1.5, 0.5, 0.5, 0.5, 0.5],
                   ts=8000,
                   nt=2**15):
    """
    Function for the first Lyapunov exponent calculation (Benetin's algorithm)

    :param args: arguments of differential equation
    :param initial_cinditions: list of initial conditions
    :param ts: calculation time
    :param nt: number of calculations steps
    :return: first Lyapunov exponent
    """
    sol, t = calcODE(args, *initial_cinditions, ts=ts, nt=nt)
    epsilon = 0.0001
    M = 1000000
    T = .01
    x1 = sol[-1]
    x2 = x1 + np.array([epsilon, 0, 0, 0, 0, 0])
    perturbations = []
    for i in range(M):
        sol1, t = calcODE(args, *x1, ts=T, nt=10)
        sol2, t = calcODE(args, *x2, ts=T, nt=10)
        perturbations.append(
            np.log(np.linalg.norm(sol2[-1] - sol1[-1]) / epsilon))
        x1 = sol1[-1]
        x2 = x1 + (sol2[-1] - sol1[-1]) / np.linalg.norm(sol2[-1] -
                                                         sol1[-1]) * epsilon
    return np.mean(perturbations) / T
Beispiel #2
0
def bifurcation_diagram(args, Bpbmin, Bpbmax, ylim=(-1, 0.6)):
    """
    Bifurcation diagram plot for BP-system.

    :param args: args of the BP-system
    :param Bpbmin: parameter of the BP-system
    :param Bpbmax: parameter of the BP-system
    :return: xs, periods
    """

    xs = []
    Bpb_list = np.linspace(Bpbmin, Bpbmax, 100)
    Iext, G, Ein, Eex, eps, a, b, A, Bpb, Bbp, vsl = args

    sol, t = calcODE(args, -1.5, -1.5, 0.5, 0.5, 0.5, 0.5, ts=4000, nt=2**25)
    sol = sol[-len(sol) // 2:, :]
    t = t[-len(t) // 2:]

    x0 = sol[0, :]
    n = np.array(ode(x0, t[0], *args))
    q, _ = np.linalg.qr(n[:, None], mode='complete')

    periods = []
    for Bpb in Bpb_list:
        args = (Iext, G, Ein, Eex, eps, a, b, A, Bpb, Bbp, vsl)
        sol, t = calcODE(args, *sol[-1, :], ts=1000, nt=2**15)
        sol = sol[-len(sol) // 2:, :]
        t = t[-len(t) // 2:]

        for i in range(len(sol) - 1):
            x1 = sol[i]
            x2 = sol[i + 1]
            if np.sign(n @ (x2 - x0)) != np.sign(n @ (x1 - x0)):
                c1 = dist(x1, x0, n)
                c2 = dist(x2, x0, n)
                alpha = c2 / (c1 + c2)
                x_new = x1 + alpha * (x2 - x1)
                x = (x_new - x0).dot(q)
                xs.append((Bpb, x[0], x[1], x[2], x[3], x[4], x[5]))
                # if np.linalg.norm(x_new - x0) < 1e-2 and period is None:
                period = t[i] - periods[-1][-1] if len(periods) else 0
                periods.append((Bpb, period, np.linalg.norm(x_new - x0), t[i]))

    plt.figure(figsize=(15, 10))
    plt.scatter([i[0] for i in xs], [i[2] for i in xs], s=10)
    plt.xlabel('$B_{pb}$')

    # plt.ylim(ylim)
    plt.show()

    periods = [i for i in periods if i[1] > 0]

    return periods, xs
Beispiel #3
0
def phase_portrait(args,
                   args1=None,
                   vp0=0,
                   vb0=0,
                   up0=0,
                   ub0=0,
                   sbp0=0,
                   spb0=0,
                   ts=2000,
                   nt=2**13):
    """
    Функция отрисовки фазового портрета системы. Есть возможность нарисовать фп
    для медленно меняющегося параметра Bpb (нужно раскомментировать 21 строчку с calcODE1)
    или для медленно меняющегося параметра Bbp (нужно раскомменировать 22 строчку с calcODE2)

    :param args: arguments of the BP-system
    :param args1: расширенные параметры системы, включающие границы изменения параметра B (pb или bp)
    :param vp0, vb0, up0, ub0, sbp0, spb0: fixed initial conditions
    :param ts: time
    :param nt: number of steps
    :return: None
    """
    sol, t = calcODE(args, vp0, vb0, up0, ub0, sbp0, spb0, ts, nt)
    # sol, t = calcODE1(args1, *sol[-1], ts, nt)
    # sol, t = calcODE2(args1, *sol[-1], ts, nt)
    vp = sol[-nt // 2:, 0]
    vb = sol[-nt // 2:, 1]

    plt.figure(figsize=(10, 10))
    plt.plot(vb, vp, 'b')
    plt.xlabel('$v_b$')
    plt.ylabel('$v_p$')
    plt.grid()
    plt.show()
Beispiel #4
0
def signal_draw(args,
                vp0=-1.5,
                vb0=-1.5,
                up0=0.5,
                ub0=0.5,
                sbp0=0.5,
                spb0=0.5,
                ts=2000,
                nt=2**15):
    """
    Функция отрисовки временных рядов Vp и Vb
    :param args: arguments of the BP-system
    :param vp0, vb0, up0, ub0, sbp0, spb0: fixed initial conditions
    :param ts: time
    :param nt: number of steps
    :return: None
    """
    sol, t = calcODE(args, vp0, vb0, up0, ub0, sbp0, spb0, ts, nt)

    plt.figure(figsize=(15, 5))
    plt.plot(np.linspace(0, ts // 4, nt // 4), sol[-nt // 4:, 0], 'b')
    plt.plot(np.linspace(0, ts // 4, nt // 4), sol[-nt // 4:, 1], 'r')

    plt.xlabel('t')
    plt.ylabel('$v_p$, $v_b$')
    plt.grid()
    plt.show()
Beispiel #5
0
def wavelet_draw(args,
                 args2,
                 scale,
                 vp0=-1.5,
                 vb0=-1.5,
                 up0=0.5,
                 ub0=0.5,
                 sbp0=0.5,
                 spb0=0.5,
                 ts=4000,
                 nt=2**15,
                 Bmin=0.7,
                 Bmax=0.9):
    sol, t = calcODE(args, vp0, vb0, up0, ub0, sbp0, spb0, ts, nt)
    sol, t = calcODE2(args2, *sol[-1], ts, nt)

    vp = sol[:, 0]
    vp = sAnalytics(vp)
    res = 2 * fftMorlet(t, vp, scale, 2 * np.pi)
    fig, ax = plt.subplots(figsize=(15, 5))
    plt.ylabel('ISI')

    ticks = np.array(
        [0, len(res) // 4,
         len(res) // 2, 3 * len(res) // 4,
         len(res) - 1])
    plt.yticks(ticks, scale[ticks])
    plt.imshow(np.abs(res), aspect='auto', origin='lower')
    xticks = np.linspace(0, nt, 10)
    xlabels = np.array([round(i, 3) for i in np.linspace(Bmin, Bmax, 10)])
    ax.set_xticks(xticks)
    ax.set_xticklabels(xlabels)
    ax.set_xlabel('$B_{pb}$')
    plt.show()
Beispiel #6
0
def calc_ode_jac(args, z0, nt=2**10):
    sol0, t = calcODE(args, *z0, ts=2000, nt=nt)
    ts = period(sol0[-nt // 2:, :])
    t = np.linspace(0, ts, nt)
    ode = flattened_jacobian
    sol = odeint(ode, z0, t, args)
    return sol, t
Beispiel #7
0
def poincare_3D(args,
                initial_conditions=(-1.5, -1.5, 0.5, 0.5, 0.5, 0.5),
                ts=4000,
                nt=2**20):
    """
    Poincare map in 3D.

    :param args: arguments and parameters of dynamical system
    :return: None
    """
    fig = plt.figure(figsize=(10, 10))
    ax = fig.add_subplot(111, projection='3d')

    sol, t = calcODE(args, *initial_conditions, ts=ts, nt=nt)

    sol = sol[-len(sol) // 2:, :]
    ax.plot(xs=sol[:, 0], ys=sol[:, 1], zs=sol[:, 2])
    # T = period(sol[-nt // 2:, :])
    # print(f'T = {T}, {t[T] - t[0]}')
    x0 = sol[0, :]
    t = t[-len(sol) // 2:]
    n = ode(x0, t, *args)

    for i in range(len(sol) - 1):
        x1 = sol[i]
        x2 = sol[i + 1]
        if np.sign(n @ (x1 - x0)) != np.sign(n @ (x2 - x0)):
            c1 = dist(x1, x0, n)
            c2 = dist(x2, x0, n)
            alpha = c2 / (c1 + c2)
            x = x1 + alpha * (x2 - x1)
            ax.scatter(x[0], x[1], x[2])
    plt.show()
Beispiel #8
0
def lyapunov_spectra(args, initial_conditions, ts=8000, nt=2**15):
    """
    Function for the Lyapunov exponents calculation (Benetin's algorithm)

    :param args: arguments of the dynamical system
    :param initial_conditions: list of initial conditions
    :param ts: calculation time
    :param nt: number of calculation steps
    :return: vector of the Lyapunov exponents
    """

    n_dims = len(initial_conditions)

    nt_small = 10
    sol, t = calcODE(args, *initial_conditions, ts=ts, nt=nt)
    epsilon = 0.001
    M = 100000
    T = .01
    x = np.zeros((n_dims + 1, n_dims))

    x[0] = sol[-1]
    for i in range(1, n_dims + 1):
        x[i] = x[0] + random_pert(n_dims) * epsilon

    perturbations = np.zeros((M, n_dims))
    sols = np.zeros((n_dims + 1, nt_small, n_dims))

    for i in range(M):
        for j in range(0, n_dims + 1):
            sols[j], _ = calcODE(args, *x[j], ts=T, nt=nt_small)

        for j in range(1, n_dims + 1):
            perturbations[i, j - 1] = np.log(
                np.linalg.norm(sols[j][-1] - sols[0][-1]) / epsilon)

        x[0] = sols[0, -1]
        sol_matrix = np.stack([sols[j, -1] for j in range(1, n_dims + 1)],
                              axis=1) - x[0][:, None]
        pert_ortho, _ = np.linalg.qr(sol_matrix)

        for j in range(1, n_dims + 1):
            x[j] = x[0] + pert_ortho[:, j - 1] * epsilon

    return np.mean(perturbations, 0) / T
Beispiel #9
0
def monodromy(args, initial_conditions, nt=2**25):
    sol, t = calcODE(args, *initial_conditions, 20000, nt)
    T = period(sol[-nt // 2:, :])
    T = t[T] - t[0]
    print(f'T = {T}')

    initial_conditions_M = np.concatenate([sol[-1, :], np.eye(6).reshape(-1)])
    sol_M, t = calcODE_monodromy(args, initial_conditions_M, ts=T, nt=2**20)

    M = sol_M[-1][6:].reshape((6, 6))  # - np.eye(6)
    return M, T
Beispiel #10
0
def poincare(args,
             parameter,
             initial_conditions=(-1.5, -1.5, 0.5, 0.5, 0.5, 0.5),
             ts=4000,
             nt=2**20,
             show=True):
    """
    Poincare map plot.
    Для использования этой функции необходимо определить свою динамическую систему,
    задав функцию calcODE(args, *initial_conditions)

    :param args: arguments of the dynamical system
    :return: periods, xs
    """

    xs = []
    periods = []

    if show:
        plt.figure(figsize=(10, 10))

    sol, t = calcODE(args, *initial_conditions, ts=ts, nt=nt)
    sol = sol[-len(sol) // 2:, :]

    x0 = sol[0, :]
    t = t[-len(t) // 2:]
    n = np.array(ode(x0, t[0], *args))
    q, _ = np.linalg.qr(n[:, None], mode='complete')

    period = None

    for i in range(len(sol) - 1):
        x1 = sol[i]
        x2 = sol[i + 1]
        if np.sign(n @ (x2 - x0)) != np.sign(n @ (x1 - x0)):
            c1 = dist(x1, x0, n)
            c2 = dist(x2, x0, n)
            alpha = c2 / (c1 + c2)
            x_new = x1 + alpha * (x2 - x1)
            x = (x_new - x0).dot(q)
            xs.append((parameter, x))
            if show:
                plt.scatter(x[1], x[2])
            if np.linalg.norm(x_new - x0) < 1e-3 and period is None:
                period = t[i] - t[0]
                periods.append((parameter, period, np.linalg.norm(x_new - x0)))
    #             else:
    #                 print(np.linalg.norm(x_new - x0))

    if show:
        plt.show()
    return periods, xs
Beispiel #11
0
def map_of_multistability(vars,
                          args,
                          vp0=-1.5,
                          vb0=-1.5,
                          up0=0.5,
                          ub0=0.5,
                          sbp0=0.5,
                          spb0=0.5,
                          ts=2000,
                          nt=2**15):
    """
    Plotting of the map of limit cycle periods for various initial conditions

    :param vars: string of variables for map calculations -- "vv", "uu" or "ss" (it will be varied)
    :param args: arguments of the BP-system
    :param vp0, vb0, up0, ub0, sbp0, spb0: fixed initial conditions
    :param ts: time
    :param nt: number of steps
    :return: array of limit cycle periods
    """
    T = []

    if vars == 'ss':
        initials = np.arange(0, 1, 0.05)
    else:
        initials = np.arange(-2, 2, 0.1)

    for var0_0 in initials:
        T_var1 = []
        for var1_0 in initials:

            if vars == 'vv':
                vp0 = var0_0
                vb0 = var1_0
            elif vars == 'uu':
                up0 = var0_0
                ub0 = var1_0
            else:
                sbp0 = var0_0
                spb0 = var1_0

            sol, t = calcODE(args, vp0, vb0, up0, ub0, sbp0, spb0, ts, nt)
            T_one = mean_T_vp(sol[:, 0], t) / 2
            print(f'T = {T_one}')
            print(f'var_p0 = {var0_0}')
            print(f'var_b0 = {var1_0}')
            T_var1.append(T_one)
        T.append(T_var1)
    return T
Beispiel #12
0
def autocorrelation(args):
    PREC = 8
    T = 2**20
    sol, t = calcODE(args, 0, 0, 0, 0, 0, 0, ts=T, nt=PREC * T)
    sol = sol[500 * PREC:]
    sol = sol - np.mean(sol, axis=0, keepdims=True)

    corrs = []
    for tau in range(0, len(sol) // 2, 100):
        corrs.append(np.mean(sol[:tau] * sol[tau:2 * tau]))

    plt.figure(figsize=(30, 10))
    plt.plot(np.abs(corrs))
    plt.xlabel("t")
    plt.ylabel("Autocorrelation")
    plt.title(f"Модуль автокорреляционной функции (Bbp=0.1, Bpb=0.1879)")
    plt.show()
Beispiel #13
0
def floquet(args, initial_conditions):
    M, T = monodromy(args, initial_conditions, nt=2**25)
    mus = np.linalg.eigvals(M)[1:]
    print(f'Multipliers: {mus}')
    print()

    print('Проверка условия с дивергенцией: ')
    sol_cycle, t = calcODE(args, *initial_conditions, T, 2**20)
    res = 0
    for i in trange(len(t)):
        res += np.diag(jacobian(sol_cycle[i, :],
                                (i * T) / len(t), args)).sum() * (t[1] - t[0])

    print('These values must be almost the same')
    print(np.product(mus), np.exp(res))

    return mus
Beispiel #14
0
def signal_draw1(args,
                 args1,
                 vp0=0,
                 vb0=0,
                 up0=0,
                 ub0=0,
                 sbp0=0,
                 spb0=0,
                 ts=2000,
                 nt=2**20):
    """
    Функция отрисовки временных рядов Vp и Vb при медленном изменении параметра Bbp
    По умолчанию оси подписываются как моменты времени, чтобы это изменить, нужно раскомменировать строки 72-73

    :param args: arguments of the BP-system
    :param args1: расширенные параметры системы, включающие границы изменения параметра Bbp
    :param vp0, vb0, up0, ub0, sbp0, spb0: fixed initial conditions
    :param ts: time
    :param nt: number of steps
    :return: None
    """

    sol, t = calcODE(args, vp0, vb0, up0, ub0, sbp0, spb0, ts, nt)
    sol, t = calcODE1(args1, *sol[-1], ts, nt)

    plt.figure(figsize=(15, 5))
    # plt.plot(np.linspace(args[9], args[10], nt), sol[:, 0], 'b')
    # plt.plot(np.linspace(args[9], args[10], nt), sol[:, 1], 'r')
    plt.plot(np.linspace(0, ts, nt), sol[:, 0], 'b')
    plt.plot(np.linspace(0, ts, nt), sol[:, 1], 'r')

    plt.xlabel('t')
    # plt.xlabel('$B_{bp}$')
    plt.ylabel('$v_p, v_b$')
    plt.grid()
    plt.show()