示例#1
0
def test_not_fitted(data_1d):
    x, t = data_1d
    model = SINDy()

    with pytest.raises(NotFittedError):
        model.predict(x)
    with pytest.raises(NotFittedError):
        model.get_feature_names()
    with pytest.raises(NotFittedError):
        model.coefficients()
    with pytest.raises(NotFittedError):
        model.equations()
    with pytest.raises(NotFittedError):
        model.simulate(x[0], t)
示例#2
0
def test_predict_discrete_time(data_discrete_time):
    x = data_discrete_time
    model = SINDy(discrete_time=True)
    model.fit(x)
    assert len(model.predict(x)) == len(x)
示例#3
0
def test_score_discrete_time(data_discrete_time):
    x = data_discrete_time
    model = SINDy(discrete_time=True)
    model.fit(x)
    assert model.score(x) > 0.75
    assert model.score(x, x_dot=x) < 1
示例#4
0
def test_bad_t(data):
    x, t = data
    model = SINDy()

    # No t
    with pytest.raises(ValueError):
        model.fit(x, t=None)

    # Invalid value of t
    with pytest.raises(ValueError):
        model.fit(x, t=-1)

    # t is a list
    with pytest.raises(ValueError):
        model.fit(x, list(t))

    # Wrong number of time points
    with pytest.raises(ValueError):
        model.fit(x, t[:-1])

    # Two points in t out of order
    t[2], t[4] = t[4], t[2]
    with pytest.raises(ValueError):
        model.fit(x, t)
    t[2], t[4] = t[4], t[2]

    # Two matching times in t
    t[3] = t[5]
    with pytest.raises(ValueError):
        model.fit(x, t)
示例#5
0
def test_fit_multiple_trajectores(data_multiple_trajctories):
    x, t = data_multiple_trajctories
    model = SINDy()

    # Should fail if multiple_trajectories flag is not set
    with pytest.raises(ValueError):
        model.fit(x, t=t)

    model.fit(x, multiple_trajectories=True)
    check_is_fitted(model)

    model.fit(x, t=t, multiple_trajectories=True)
    assert model.score(x, t=t, multiple_trajectories=True) > 0.8

    model = SINDy()
    model.fit(x, x_dot=x, multiple_trajectories=True)
    check_is_fitted(model)

    model = SINDy()
    model.fit(x, t=t, x_dot=x, multiple_trajectories=True)
    check_is_fitted(model)
示例#6
0
def test_multiple_trajectories_errors(data_multiple_trajctories,
                                      data_discrete_time):
    x, t = data_multiple_trajctories

    model = SINDy()
    with pytest.raises(TypeError):
        model.process_multiple_trajectories(np.array(x), t, x)
    with pytest.raises(TypeError):
        model.process_multiple_trajectories(x, t, np.array(x))

    # Test an option that doesn't get tested elsewhere
    model.process_multiple_trajectories(x, t, x, return_array=False)

    x = data_discrete_time
    model = SINDy(discrete_time=True)
    with pytest.raises(TypeError):
        model.process_multiple_trajectories(x, t, np.array(x))
示例#7
0
def test_improper_shape_input(data_1d):
    x, t = data_1d
    u = np.ones_like(x)

    # Ensure model successfully handles different data shapes
    model = SINDy()
    model.fit(x.flatten(), u=u, t=t)
    check_is_fitted(model)

    model = SINDy()
    model.fit(x.flatten(), u=u, t=t, x_dot=x.flatten())
    check_is_fitted(model)

    model = SINDy()
    model.fit(x, u=u, t=t, x_dot=x.flatten())
    check_is_fitted(model)

    model = SINDy()
    model.fit(x.flatten(), u=u.flatten(), t=t)
    check_is_fitted(model)

    model = SINDy()
    model.fit(x.flatten(), u=u.flatten(), t=t, x_dot=x.flatten())
    check_is_fitted(model)

    model = SINDy()
    model.fit(x, u=u.flatten(), t=t, x_dot=x.flatten())
    check_is_fitted(model)

    # Should fail if x and u have incompatible numbers of rows
    with pytest.raises(ValueError):
        model.fit(x[:-1, :], u=u, t=t[:-1])
示例#8
0
def test_t_default(data):
    x, t = data
    dt = t[1] - t[0]

    with pytest.raises(ValueError):
        model = SINDy(t_default=0)
    with pytest.raises(ValueError):
        model = SINDy(t_default="1")

    model = SINDy()
    model.fit(x, dt)

    model_t_default = SINDy(t_default=dt)
    model_t_default.fit(x)

    np.testing.assert_allclose(model.coefficients(),
                               model_t_default.coefficients())
    np.testing.assert_almost_equal(model.score(x, t=dt),
                                   model_t_default.score(x))
    np.testing.assert_almost_equal(model.differentiate(x, t=dt),
                                   model_t_default.differentiate(x))
示例#9
0
def test_integration_derivative_methods(data_lorenz, derivative_kws):
    x, t = data_lorenz
    model = SINDy(differentiation_method=SINDyDerivative(**derivative_kws))
    model.fit(x, t=t)

    check_is_fitted(model)
示例#10
0
def test_predict_discrete_time(data_discrete_time_c):
    x, u = data_discrete_time_c
    model = SINDy(discrete_time=True)
    model.fit(x, u=u)
    assert len(model.predict(x, u=u)) == len(x)
示例#11
0
def test_score_discrete_time(data_discrete_time_c):
    x, u = data_discrete_time_c
    model = SINDy(discrete_time=True)
    model.fit(x, u=u)
    assert model.score(x, u=u) > 0.75
    assert model.score(x, u=u, x_dot=x) < 1
示例#12
0
def test_fit_multiple_trajectores(data_multiple_trajctories):
    x, t = data_multiple_trajctories
    u = [np.ones((xi.shape[0], 2)) for xi in x]

    model = SINDy()

    # Should fail if multiple_trajectories flag is not set
    with pytest.raises(ValueError):
        model.fit(x, u=u, t=t)

    # Should fail if either x or u is not a list
    with pytest.raises(ValueError):
        model.fit(x, u=u[0], multiple_trajectories=True)

    with pytest.raises(ValueError):
        model.fit(x[0], u=u, multiple_trajectories=True)

    # x and u should be lists of the same length
    with pytest.raises(ValueError):
        model.fit([x[:-1]], u=u, multiple_trajectories=True)

    model.fit(x, u=u, multiple_trajectories=True)
    check_is_fitted(model)

    model.fit(x, u=u, t=t, multiple_trajectories=True)
    assert model.score(x, u=u, t=t, multiple_trajectories=True) > 0.8

    model = SINDy()
    model.fit(x, u=u, x_dot=x, multiple_trajectories=True)
    check_is_fitted(model)

    model = SINDy()
    model.fit(x, u=u, t=t, x_dot=x, multiple_trajectories=True)
    check_is_fitted(model)
示例#13
0
def test_t_default(data):
    x, t, u, _ = data
    dt = t[1] - t[0]

    model = SINDy()
    model.fit(x, u=u, t=dt)

    model_t_default = SINDy(t_default=dt)
    model_t_default.fit(x, u=u)

    np.testing.assert_allclose(model.coefficients(),
                               model_t_default.coefficients())
    np.testing.assert_almost_equal(model.score(x, u=u, t=dt),
                                   model_t_default.score(x, u=u))
示例#14
0
def test_bad_control_input(data_lorenz_c_1d):
    x, t, u, _ = data_lorenz_c_1d
    model = SINDy()

    with pytest.raises(TypeError):
        model.fit(x, u=set(u), t=t)
示例#15
0
def test_coefficients(data_lorenz):
    x, t = data_lorenz
    model = SINDy()
    model.fit(x, t)
    c = model.coefficients()
    assert np.count_nonzero(c) < 10
示例#16
0
def test_nan_derivatives(data_lorenz):
    x, t = data_lorenz

    model = SINDy(differentiation_method=FiniteDifference(drop_endpoints=True))
    model.fit(x, t)
    check_is_fitted(model)
示例#17
0
def test_complexity(data_lorenz):
    x, t = data_lorenz
    model = SINDy()
    model.fit(x, t)
    assert model.complexity < 10
示例#18
0
def test_mixed_inputs(data):
    x, t = data

    # Scalar t
    model = SINDy()
    model.fit(x, t=2)
    check_is_fitted(model)

    # x_dot is passed in
    model = SINDy()
    model.fit(x, x_dot=x)
    check_is_fitted(model)

    model = SINDy()
    model.fit(x, t, x_dot=x)
    check_is_fitted(model)
示例#19
0
def test_improper_shape_input(data_1d):
    x, t = data_1d

    # Ensure model successfully handles different data shapes
    model = SINDy()
    model.fit(x.flatten(), t)
    check_is_fitted(model)

    model = SINDy()
    model.fit(x.flatten(), t, x_dot=x.flatten())
    check_is_fitted(model)

    model = SINDy()
    model.fit(x, t, x_dot=x.flatten())
    check_is_fitted(model)
def compressible_Framework(inner_prod, time, poly_order, threshold, r, tfac,
                           SR3Enhanced, make_3Dphaseplots):
    """
    Performs the entire vector_POD + SINDy framework for a given polynomial
    order and thresholding for the SINDy method.

    Parameters
    ----------
    inner_prod: 2D numpy array of floats
    (M = number of time samples, M = number of time samples)
        The scaled matrix of inner products X*X

    time: numpy array of floats
    (M = number of time samples)
        Time in microseconds

    poly_order: int
    (1)
        Highest polynomial order to use in the SINDy library

    threshold: float
    (1)
        Threshold in the SINDy algorithm, below which coefficients
        will be zeroed out.

    r: int
    (1)
        Truncation number of the SVD

    tfac: float
    (1)
        Fraction of the data to treat as training data

    SR3Enhanced: SINDy optimizer object
    (1)
        The SR3 optimizer with linear equality constraints

    make_3Dphaseplots: bool
    (1)
        Flag to make 3D phase plots or not

    Returns
    -------
    t_test: numpy array of floats
    (M_test = number of time samples in the test data region)
        Time in microseconds in the test data region

    x_true: 2D numpy array of floats
    (M_test = number of time samples in the test data region,
    r = truncation number of the SVD)
        The true evolution of the temporal BOD modes

    x_sim: 2D numpy array of floats
    (M_test = number of time samples in the test data region,
    r = truncation number of the SVD)
        The model evolution of the temporal BOD modes

    S2: 2D numpy array of floats
    (M = number of time samples, M = number of time samples)
        The singular value matrix

    """
    plt.clf()
    plt.close('all')
    M_train = int(len(time) * tfac)
    t_train = time[:M_train]
    t_test = time[M_train:]
    x, feature_names, S2, Vh, = vector_POD(inner_prod, time, r)
    print('Now fitting SINDy model')
    if poly_order == 1:
        library_functions = [lambda x: x]
        library_function_names = [lambda x: x]
    if poly_order == 2:
        library_functions = [lambda x: x, lambda x, y: x * y, lambda x: x**2]
        library_function_names = [
            lambda x: x, lambda x, y: x + y, lambda x: x + x
        ]
    if poly_order == 3:
        library_functions = [
            lambda x: x, lambda x, y: x * y, lambda x: x**2,
            lambda x, y, z: x * y * z, lambda x, y: x**2 * y,
            lambda x, y: x * y**2, lambda x: x**3
        ]
        library_function_names = [
            lambda x: x, lambda x, y: x + y, lambda x: x + x,
            lambda x, y, z: x + y + z, lambda x, y: x + x + y,
            lambda x, y: x + y + y, lambda x: x + x + x
        ]
    if poly_order == 4:
        library_functions = [
            lambda x: x, lambda x, y: x * y, lambda x: x**2,
            lambda x, y, z: x * y * z, lambda x, y: x**2 * y,
            lambda x, y: x * y**2, lambda x: x**3,
            lambda x, y, z, w: x * y * z * w, lambda x, y, z: x * y * z**2,
            lambda x, y: x**2 * y**2, lambda x, y: x**3 * y, lambda x: x**4
        ]
        library_function_names = [
            lambda x: x, lambda x, y: x + y, lambda x: x + x,
            lambda x, y, z: x + y + z, lambda x, y: x + x + y,
            lambda x, y: x + y + y, lambda x: x + x + x,
            lambda x, y, z, w: x + y + z + w, lambda x, y, z: x + y + z + z,
            lambda x, y: x + x + y + y, lambda x, y: x + x + x + y,
            lambda x: x + x + x + x
        ]
    sindy_library = CustomLibrary(library_functions=library_functions, \
        function_names=library_function_names)
    constraint_zeros = np.zeros(int(r * (r + 1) / 2))
    if poly_order == 1:
        constraint_matrix = np.zeros((int(r * (r + 1) / 2), r**2))
        for i in range(r):
            constraint_matrix[i, i * (r + 1)] = 1.0
        q = r
        for i in range(r):
            counter = 1
            for j in range(i + 1, r):
                constraint_matrix[q, i * r + j] = 1.0
                constraint_matrix[q, i * r + j + counter * (r - 1)] = 1.0
                counter = counter + 1
                q = q + 1
    else:
        if poly_order == 2:
            #constraint_zeros = np.zeros(6+int(r*(r+1)/2))
            #constraint_matrix = np.zeros((6+int(r*(r+1)/2),int(r*(r**2+3*r)/2)))
            constraint_matrix = np.zeros(
                (int(r * (r + 1) / 2), int(r * (r**2 + 3 * r) / 2)))
        if poly_order == 3:
            #constraint_matrix = np.zeros((int(r*(r+1)/2),int(r*(r**2+3*r)/2)+336))
            constraint_matrix = np.zeros(
                (int(r * (r + 1) / 2),
                 int(r * (r**2 + 3 * r) / 2) + 588))  # 30
        if poly_order == 4:
            constraint_matrix = np.zeros(
                (int(r * (r + 1) / 2), int(r * (r**2 + 3 * r) / 2) + 60))
        for i in range(r):
            constraint_matrix[i, i * (r + 1)] = 1.0
        q = r
        for i in range(r):
            counter = 1
            for j in range(i + 1, r):
                constraint_matrix[q, i * r + j] = 1.0
                constraint_matrix[q, i * r + j + counter * (r - 1)] = 1.0
                counter = counter + 1
                q = q + 1
    # linear_r4_mat or linear_r12_mat are initial guesses
    # for the optimization
    linear_r4_mat = np.zeros((r, r))
    linear_r4_mat[0, 1] = 0.091
    linear_r4_mat[1, 0] = -0.091
    linear_r4_mat[2, 3] = 0.182
    linear_r4_mat[3, 2] = -0.182
    linear_r4_mat[5, 4] = -3 * 0.091
    linear_r4_mat[4, 5] = 3 * 0.091
    #linear_r4_mat[8,7] = -4*0.091
    #linear_r4_mat[7,8] = 4*0.091
    #linear_r4_mat[6,7] = 4*0.091
    #linear_r4_mat[7,6] = -4*0.091
    linear_r12_mat = np.zeros((12, 90))
    linear_r12_mat[0, 1] = 0.089
    linear_r12_mat[1, 0] = -0.089
    linear_r12_mat[2, 3] = 0.172
    linear_r12_mat[3, 2] = -0.172
    linear_r12_mat[2, 5] = 0.03
    linear_r12_mat[5, 2] = -0.03
    linear_r12_mat[2, 6] = 0.022
    linear_r12_mat[6, 2] = -0.022
    linear_r12_mat[6, 4] = 0.022
    linear_r12_mat[4, 6] = 0.023
    linear_r12_mat[7, 5] = -0.023
    linear_r12_mat[5, 7] = -0.123
    linear_r12_mat[7, 5] = 0.123
    sindy_opt = SR3Enhanced(threshold=threshold, nu=1, max_iter=20000, \
        constraint_lhs=constraint_matrix,constraint_rhs=constraint_zeros, \
        tol=1e-6,thresholder='l0',initial_guess=linear_r4_mat)
    model = SINDy(optimizer=sindy_opt, \
        feature_library=sindy_library, \
        differentiation_method=FiniteDifference(drop_endpoints=True), \
        feature_names=feature_names)
    x_train = x[:M_train, :]
    x0_train = x[0, :]
    x_true = x[M_train:, :]
    x0_test = x[M_train, :]
    model.fit(x_train, t=t_train, unbias=False)
    t_cycle = np.linspace(time[M_train], time[M_train] * 1.3,
                          int(len(time) / 2.0))
    print(model.coefficients())
    x_sim,output = model.simulate(x0_test,t_test, \
        integrator=odeint,stop_condition=None,full_output=True, \
        rtol=1e-20,h0=1e-5) #h0=1e-20
    x_sim1,output = model.simulate(-0.4*np.ones(r),t_cycle, \
        integrator=odeint,stop_condition=None,full_output=True, \
        rtol=1e-20,h0=1e-5)
    x_sim2,output = model.simulate(0.15*np.ones(r),t_cycle, \
        integrator=odeint,stop_condition=None,full_output=True, \
        rtol=1e-20,h0=1e-5)
    x_dot = model.differentiate(x, t=time)
    x_dot_train = model.predict(x_train)
    x_dot_sim = model.predict(x_true)
    print('Model score: %f' % model.score(x, t=time))
    make_evo_plots(x_dot,x_dot_train, \
        x_dot_sim,x_true,x_sim,time,t_train,t_test)
    make_table(model, feature_names)
    # Makes 3D phase space plots
    if make_3Dphaseplots:
        make_3d_plots(x_true, x_sim, t_test, 'sim', 0, 1, 2)
        make_3d_plots(x_true, x_sim, t_test, 'sim', 0, 1, 3)
        make_3d_plots(x_true, x_sim, t_test, 'sim', 0, 1, 4)
        make_3d_plots(x_true, x_sim, t_test, 'sim', 0, 1, 5)
        make_3d_plots(x_true, x_sim, t_test, 'sim', 0, 1, 6)
        make_3d_plots(x_true, x_sim, t_test, 'sim', 3, 4, 5)
        make_3d_plots(x_true, x_sim, t_test, 'sim', 4, 5, 6)
        make_3d_plots(x_sim1, x_sim2, t_cycle, 'limitcycle')
    for i in range(r):
        x_sim[:, i] = x_sim[:, i] * sum(np.amax(abs(Vh), axis=1)[0:r])
        x_true[:, i] = x_true[:, i] * sum(np.amax(abs(Vh), axis=1)[0:r])
    return t_test, x_true, x_sim, S2