예제 #1
0
def test_evaluate_fitness_vector_implicit():
    print("-----test_evaluate_fitness_vector_implicit-----")
    x_t = snake_walk()
    y = (x_t[:, 0] + x_t[:, 1])
    x = np.hstack((x_t, y.reshape([-1, 1])))

    py_training_data = ImplicitTrainingData(x)
    py_implicit_regressor = ImplicitRegression()
    c_training_data = bingocpp.ImplicitTrainingData(x)
    c_implicit_regressor = bingocpp.ImplicitRegression()

    py_manip = AGraphCpp.AGraphCppManipulator(3, 64, nloads=2)
    py_manip.add_node_type(2)
    py_manip.add_node_type(3)
    py_manip.add_node_type(4)
    c_manip = bingocpp.AcyclicGraphManipulator(3, 64, nloads=2)
    c_manip.add_node_type(2)
    c_manip.add_node_type(3)
    c_manip.add_node_type(4)

    temp = np.array([[1, 0, 0], [0, 0, 0], [0, 1, 1], [3, 2, 2], [4, 2, 3],
                     [4, 4, 0], [3, 2, 0], [3, 0, 0], [3, 4, 2], [3, 1, 4],
                     [2, 6, 0], [3, 8, 7], [2, 3, 11], [3, 7, 7], [3, 2, 7],
                     [2, 9, 5], [4, 4, 14], [3, 9, 1], [3, 4, 5], [0, 1, 1],
                     [4, 8, 4], [1, -1, -1], [3, 20, 5],
                     [2, 9, 17], [1, -1, -1], [4, 23, 4], [4, 25, 19],
                     [2, 26, 14], [4, 22, 10], [0, 0, 0], [2, 0, 17],
                     [2, 29, 16], [4, 23, 14], [4, 3, 22], [0, 2, 2],
                     [2, 31, 27], [2, 35, 28], [2, 25, 29], [2, 36, 28],
                     [3, 8, 29], [3, 4, 24], [2, 14, 9], [4, 25, 9], [0, 2, 2],
                     [3, 26, 10], [3, 12, 6], [0, 1, 1], [4, 42,
                                                          26], [3, 41, 6],
                     [3, 13, 1], [3, 42, 36], [3, 15, 34], [2, 14, 23],
                     [2, 13, 12], [0, 2, 2], [2, 28, 45], [3, 1, 12],
                     [3, 15, 30], [3, 34, 38], [3, 43, 50], [2, 31, 9],
                     [2, 54, 46], [1, -1, -1], [4, 60, 29]])

    py_1 = py_manip.generate()
    c_1 = c_manip.generate()
    py_1.command_array = np.copy(temp)
    c_1.stack = np.copy(temp)
    c_manip.simplify_stack(c_1)

    assert py_training_data.x.all() == pytest.approx(c_training_data.x.all())
    assert py_training_data.dx_dt.all() == pytest.approx(
        c_training_data.dx_dt.all())

    py_fit = py_implicit_regressor.evaluate_fitness(py_1, py_training_data)
    py_fit = py_implicit_regressor.evaluate_fitness_vector(
        py_1, py_training_data)

    c_fit = c_implicit_regressor.evaluate_fitness(c_1, c_training_data)
    c_fit = c_implicit_regressor.evaluate_fitness_vector(c_1, c_training_data)

    assert py_fit.all() == pytest.approx(c_fit.all())
예제 #2
0
def test_cpp_agcpp_explicit_cos():
    """test add primitive in sym reg"""
    # get independent vars
    x_true = snake_walk()

    # make solutions
    y = np.cos(x_true[:, 0])

    # test solution
    operator = 7
    params = (0, 0)
    compare_cpp_agcpp_explicit(x_true, y, operator, params)
예제 #3
0
def test_ag_explicit_mul():
    """test multiply primitive in sym reg"""
    # get independent vars
    x_true = snake_walk()

    # make solutions
    y = (x_true[:, 0] * x_true[:, 1])

    # test solution
    operator = AGNodes.Multiply
    params = (0, 1)
    compare_ag_explicit(x_true, y, operator, params)
예제 #4
0
def test_ag_explicit_div():
    """test divide primitive in sym reg"""
    # get independent vars
    x_true = snake_walk()

    # make solutions
    y = (x_true[:, 0] / x_true[:, 1])

    # test solution
    operator = AGNodes.Divide
    params = (0, 1)
    compare_ag_explicit(x_true, y, operator, params)
예제 #5
0
def test_ag_explicit_log():
    """test logarithm primitive in sym reg"""
    # get independent vars
    x_true = snake_walk()

    # make solutions
    y = np.log(x_true[:, 0])

    # test solution
    operator = AGNodes.Log
    params = (0, )
    compare_ag_explicit(x_true, y, operator, params)
예제 #6
0
def test_ag_explicit_pow():
    """test absolute value primitive in sym reg"""
    # get independent vars
    x_true = snake_walk()

    # make solutions
    y = np.power(x_true[:, 0], x_true[:, 1])

    # test solution
    operator = AGNodes.Pow
    params = (0, 1)
    compare_ag_explicit(x_true, y, operator, params)
예제 #7
0
def test_agcpp_implicit_sub():
    """test subtract primitive in sym reg"""
    # get independent vars
    x_true = snake_walk()

    # make solutions
    y = (x_true[:, 0] - x_true[:, 1])

    # test solution
    operator = 3
    params = (0, 1)
    compare_agcpp_implicit(x_true, y, operator, params)
예제 #8
0
def test_ag_explicit_exp():
    """test exponential primitive in sym reg"""
    # get independent vars
    x_true = snake_walk()

    # make solutions
    y = np.exp(x_true[:, 0])

    # test solution
    operator = AGNodes.Exp
    params = (0, )
    compare_ag_explicit(x_true, y, operator, params)
예제 #9
0
def test_ag_implicit_add():
    """test add primitive in sym reg"""
    # get independent vars
    x_true = snake_walk()

    # make solutions
    y = (x_true[:, 0] + x_true[:, 1])

    # test solution
    operator = AGNodes.Add
    params = (0, 1)
    compare_ag_implicit(x_true, y, operator, params)
예제 #10
0
def test_cpp_agcpp_implicit_pow():
    """test add primitive in sym reg"""
    # get independent vars
    x_true = snake_walk()

    # make solutions
    y = np.power(x_true[:, 0], x_true[:, 1])

    # test solution
    operator = 10
    params = (0, 1)
    compare_cpp_agcpp_implicit(x_true, y, operator, params)
예제 #11
0
def test_ag_implicit_abs():
    """test absolute value primitive in sym reg"""
    # get independent vars
    x_true = snake_walk()

    # make solutions
    y = np.abs(x_true[:, 0])

    # test solution
    operator = AGNodes.Abs
    params = (0, )
    compare_ag_implicit(x_true, y, operator, params)
예제 #12
0
def test_ag_explicit_sin():
    """test sine primitive in sym reg"""
    # get independent vars
    x_true = snake_walk()

    # make solutions
    y = np.sin(x_true[:, 0])

    # test solution
    operator = AGNodes.Sin
    params = (0, )
    compare_ag_explicit(x_true, y, operator, params)
예제 #13
0
def test_agcpp_explicit_div():
    """test add primative in sym reg"""
    # get independent vars
    x_true = snake_walk()

    # make solutions
    y = (x_true[:, 0] / x_true[:, 1])

    # test solution
    operator = 5
    params = (0, 1)
    compare_agcpp_explicit(x_true, y, operator, params)
예제 #14
0
def test_const_opt_agraphcpp_explicit_evo():
    """test add primative in sym reg"""
    print("-----test_const_opt_agraphcpp_explicit_evo-----")
    # get independent vars
    x_true = snake_walk()

    # make solutions
    const_1 = np.random.rand() * 90 + 10
    const_2 = np.random.rand() * 90 + 10
    print("CONSTANTS: ", const_1, const_2)
    y = (const_1 * x_true[:, 0] + const_2 * x_true[:, 1]).reshape([-1, 1])

    # test solution
    compare_agraphcpp_explicit(x_true, y)
예제 #15
0
def test_const_opt_agraph_explicit():
    """test optimization code"""
    print("-----test_const_opt_agraph_explicit-----")
    # get independent vars
    x_true = snake_walk()

    # make solutions
    consts = np.random.rand(6) * 90 + 10
    print("CONSTANTS: ", consts)
    y = consts[0] + consts[1] * x_true[:, 0] + consts[2] * x_true[:, 1] + \
        consts[3] * x_true[:, 0] * x_true[:, 0] + \
        consts[4] * x_true[:, 1] * x_true[:, 1] + \
        consts[5] * x_true[:, 0] * x_true[:, 1]

    # create manipulator to set things up
    sol_manip = agm(x_true.shape[1], 21, nloads=2)
    sol_manip.add_node_type(AGNodes.Add)
    sol_manip.add_node_type(AGNodes.Multiply)

    # create gene with proper functional form
    sol = sol_manip.generate()
    sol.command_list[0] = (AGNodes.LoadConst, (None, ))
    sol.command_list[1] = (AGNodes.LoadConst, (None, ))
    sol.command_list[2] = (AGNodes.LoadConst, (None, ))
    sol.command_list[3] = (AGNodes.LoadConst, (None, ))
    sol.command_list[4] = (AGNodes.LoadConst, (None, ))
    sol.command_list[5] = (AGNodes.LoadConst, (None, ))

    sol.command_list[6] = (AGNodes.LoadData, (0, ))
    sol.command_list[7] = (AGNodes.LoadData, (1, ))
    sol.command_list[8] = (AGNodes.Multiply, (6, 6))
    sol.command_list[9] = (AGNodes.Multiply, (7, 7))
    sol.command_list[10] = (AGNodes.Multiply, (6, 7))

    sol.command_list[11] = (AGNodes.Multiply, (1, 6))
    sol.command_list[12] = (AGNodes.Multiply, (2, 7))
    sol.command_list[13] = (AGNodes.Multiply, (3, 8))
    sol.command_list[14] = (AGNodes.Multiply, (4, 9))
    sol.command_list[15] = (AGNodes.Multiply, (5, 10))

    sol.command_list[16] = (AGNodes.Add, (0, 11))
    sol.command_list[17] = (AGNodes.Add, (16, 12))
    sol.command_list[18] = (AGNodes.Add, (17, 13))
    sol.command_list[19] = (AGNodes.Add, (18, 14))
    sol.command_list[20] = (AGNodes.Add, (19, 15))
    # print(sol.latexstring())
    sol.set_constants(consts)

    # create training data
    y = y.reshape([-1, 1])
    training_data = ExplicitTrainingData(x_true, y)

    # create fitness metric
    explicit_regressor = StandardRegression()

    # fit the constants
    explicit_regressor.evaluate_fitness(sol, training_data)

    # make sure constants are close
    c_fit = sol.constants
    print("FITTED:    ", c_fit)
    print("REL DIFF:  ", (consts - c_fit) / consts)
    for tru, fit in zip(consts, c_fit):
        assert np.abs(tru - fit) < 1e-8
예제 #16
0
def main(max_steps, epsilon, data_size):
    """main function which runs regression"""
    comm = MPI.COMM_WORLD
    rank = comm.Get_rank()

    # load data on rank 0
    if rank == 0:
        # make data
        # n_lin = int(math.pow(data_size, 1.0/3)) + 1
        # x_1 = np.linspace(0, 5, n_lin)
        # x_2 = np.linspace(0, 5, n_lin)
        # x_3 = np.linspace(0, 5, n_lin)
        # x = np.array(np.meshgrid(x_1, x_2, x_3)).T.reshape(-1, 3)
        # x = x[np.random.choice(x.shape[0], data_size, replace=False), :]

        # make solution
        # y = (x[:,0]*x[:,0]+3.5*x[:,1])
        # x_true = x
        # y_true = y

        x = snake_walk()
        y = (x[:, 0] + x[:, 1])
        x_true = np.hstack((x, y.reshape([-1, 1])))
        y_true = None
    else:
        x_true = None
        y_true = None
    # then broadcast to all ranks
    x_true = MPI.COMM_WORLD.bcast(x_true, root=0)
    y_true = MPI.COMM_WORLD.bcast(y_true, root=0)

    # make solution manipulator
    # sol_manip = agm(x_true.shape[1], 64, nloads=2)
    # sol_manip.add_node_type(AGNodes.Add)
    # sol_manip.add_node_type(AGNodes.Subtract)
    # sol_manip.add_node_type(AGNodes.Multiply)
    # sol_manip.add_node_type(AGNodes.Divide)
    # sol_manip.add_node_type(AGNodes.Exp)
    # sol_manip.add_node_type(AGNodes.Log)
    # sol_manip.add_node_type(AGNodes.Sin)
    # sol_manip.add_node_type(AGNodes.Cos)
    # sol_manip.add_node_type(AGNodes.Abs)
    # sol_manip.add_node_type(AGNodes.Sqrt)


    # make solution manipulator
    # y_true = y_true.reshape(-1, 1)
    # sol_manip2 = AGraphCpp.AGraphCppManipulator(x_true.shape[1], 64, nloads=2)
    sol_manip2 = bingocpp.AcyclicGraphManipulator(x_true.shape[1], 64, nloads=2)
    # sol_manip2 = bingocpp.AcyclicGraphManipulator(x_true.shape[1], 64, nloads=2, opt_rate=0)

    # sol_manip.add_node_type(2)  # +
    # sol_manip.add_node_type(3)  # -
    # sol_manip.add_node_type(4)  # *
    # sol_manip.add_node_type(5)  # /
    # sol_manip.add_node_type(6)  # sin
    # sol_manip.add_node_type(7)  # cos
    # sol_manip.add_node_type(8)  # exp
    # sol_manip.add_node_type(9)  # log
    # # sol_manip.add_node_type(10)  # pow
    # sol_manip.add_node_type(11)  # abs
    # sol_manip.add_node_type(12)  # sqrt


    sol_manip2.add_node_type(2)  # +
    sol_manip2.add_node_type(3)  # -
    sol_manip2.add_node_type(4)  # *
    sol_manip2.add_node_type(5)  # /
    sol_manip2.add_node_type(6)  # sin
    sol_manip2.add_node_type(7)  # cos
    sol_manip2.add_node_type(8)  # exp
    sol_manip2.add_node_type(9)  # log
    # sol_manip2.add_node_type(10)  # pow
    sol_manip2.add_node_type(11)  # abs
    sol_manip2.add_node_type(12)  # sqrt

    # make predictor manipulator
    pred_manip = fpm(128, data_size)

    # make training data
    # training_data = ImplicitTrainingData(x_true)
    training_data = bingocpp.ImplicitTrainingData(x_true)
    # training_data = ExplicitTrainingData(x_true, y_true)
    # training_data2 = bingocpp.ExplicitTrainingData(x_true, y_true)

    # make fitness metric
    # implicit_regressor = ImplicitRegression()
    implicit_regressor = bingocpp.ImplicitRegression()
    # explicit_regressor = StandardRegression(const_deriv=True)
    # explicit_regressor2 = bingocpp.StandardRegression()


    # make and run island manager
    islmngr = ParallelIslandManager(#restart_file='test.p',
        solution_training_data=training_data,
        solution_manipulator=sol_manip2,
        predictor_manipulator=pred_manip,
        solution_pop_size=64,
        fitness_metric=implicit_regressor)
        # fitness_metric=explicit_regressor)

    # islmngr2 = ParallelIslandManager(#restart_file='test.p',
    #     solution_training_data=training_data,
    #     solution_manipulator=sol_manip,
    #     predictor_manipulator=pred_manip,
    #     solution_pop_size=64,
    #     fitness_metric=explicit_regressor)


    # islmngr = ParallelIslandManager(#restart_file='test.p',
    #     data_x=x_true, data_y=y_true,
    #     solution_manipulator=sol_manip,
    #     predictor_manipulator=pred_manip,
    #     solution_pop_size=64,
    #     fitness_metric=StandardRegression)

    # islmngr2 = ParallelIslandManager(#restart_file='test.p',
    #     data_x=x_true, data_y=y_true,
    #     solution_manipulator=sol_manip,
    #     predictor_manipulator=pred_manip,
    #     solution_pop_size=64,
    #     fitness_metric=StandardRegression)
    non_one = time.time()
    islmngr.run_islands(max_steps, epsilon, min_steps=500,
                        step_increment=500, when_update=50)
    non_two = time.time()
    non_time = non_two - non_one
    
    timesN.append(non_time)
    agesN.append(islmngr.age)
예제 #17
0
def test_const_opt_agraph_implicit():
    """test optimization code"""
    print("-----test_const_opt_agraph_implicit-----")
    # get independent vars
    x_true = snake_walk()

    # make solutions
    consts = np.random.rand(6) * 90 + 10
    print("CONSTANTS: ", consts[1:])
    y = consts[0] + consts[1] * x_true[:, 0] + consts[2] * x_true[:, 1] + \
        consts[3] * x_true[:, 0] * x_true[:, 0] + \
        consts[4] * x_true[:, 1] * x_true[:, 1] + \
        consts[5] * x_true[:, 0] * x_true[:, 1]
    x_true = np.hstack((x_true, y.reshape((-1, 1))))

    # create manipulator to set things up
    sol_manip = agm(x_true.shape[1], 23, nloads=2)
    sol_manip.add_node_type(AGNodes.Add)
    sol_manip.add_node_type(AGNodes.Subtract)
    sol_manip.add_node_type(AGNodes.Multiply)

    # create gene with proper functional form
    sol = sol_manip.generate()
    sol.command_list[0] = (AGNodes.LoadConst, (None, ))
    sol.command_list[1] = (AGNodes.LoadConst, (None, ))
    sol.command_list[2] = (AGNodes.LoadConst, (None, ))
    sol.command_list[3] = (AGNodes.LoadConst, (None, ))
    sol.command_list[4] = (AGNodes.LoadConst, (None, ))
    sol.command_list[5] = (AGNodes.LoadConst, (None, ))

    sol.command_list[6] = (AGNodes.LoadData, (0, ))
    sol.command_list[7] = (AGNodes.LoadData, (1, ))
    sol.command_list[8] = (AGNodes.Multiply, (6, 6))
    sol.command_list[9] = (AGNodes.Multiply, (7, 7))
    sol.command_list[10] = (AGNodes.Multiply, (6, 7))

    sol.command_list[11] = (AGNodes.Multiply, (1, 6))
    sol.command_list[12] = (AGNodes.Multiply, (2, 7))
    sol.command_list[13] = (AGNodes.Multiply, (3, 8))
    sol.command_list[14] = (AGNodes.Multiply, (4, 9))
    sol.command_list[15] = (AGNodes.Multiply, (5, 10))

    sol.command_list[16] = (AGNodes.Add, (0, 11))
    sol.command_list[17] = (AGNodes.Add, (16, 12))
    sol.command_list[18] = (AGNodes.Add, (17, 13))
    sol.command_list[19] = (AGNodes.Add, (18, 14))
    sol.command_list[20] = (AGNodes.Add, (19, 15))
    sol.command_list[21] = (AGNodes.LoadData, (2, ))
    sol.command_list[22] = (AGNodes.Subtract, (20, 21))
    # print(sol.latexstring())
    sol.set_constants(consts)

    # create training data
    training_data = ImplicitTrainingData(x_true)

    # create fitness metric
    implicit_regressor = ImplicitRegression(required_params=3)

    # fit the constants
    t0 = time.time()

    implicit_regressor.evaluate_fitness(sol, training_data)

    t1 = time.time()
    print("fit time: ", t1 - t0, "seconds")

    # make sure constants are close
    c_fit = sol.constants
    print(
        "average accuracy: ",
        np.mean(
            np.abs(np.array(c_fit[1:]) - np.array(consts[1:])) /
            np.array(consts[1:])))
    print("FITTED:    ", c_fit[1:])
    for tru, fit in zip(consts[1:], c_fit[1:]):
        print(np.abs(tru - fit) / tru)
        assert np.abs(tru - fit) / tru < 0.1
예제 #18
0
def test_const_opt_agraphcpp_explicit():
    """test optimization code"""
    print("-----test_const_opt_agraphcpp_explicit-----")
    # get independent vars
    x_true = snake_walk()

    # make solutions
    consts = np.random.rand(6) * 90 + 10
    print("CONSTANTS: ", consts)
    y = consts[0] + consts[1] * x_true[:, 0] + consts[2] * x_true[:, 1] + \
        consts[3] * x_true[:, 0] * x_true[:, 0] + \
        consts[4] * x_true[:, 1] * x_true[:, 1] + \
        consts[5] * x_true[:, 0] * x_true[:, 1]
    y = y.reshape([-1, 1])

    # create manipulator to set things up
    sol_manip = agcm(x_true.shape[1], 21, nloads=2)
    sol_manip.add_node_type(2)
    sol_manip.add_node_type(4)

    # create gene with proper functional form
    sol = sol_manip.generate()
    sol.command_array[0] = (1, -1, -1)
    sol.command_array[1] = (1, -1, -1)
    sol.command_array[2] = (1, -1, -1)
    sol.command_array[3] = (1, -1, -1)
    sol.command_array[4] = (1, -1, -1)
    sol.command_array[5] = (1, -1, -1)

    sol.command_array[6] = (0, 0, 0)
    sol.command_array[7] = (0, 1, 1)
    sol.command_array[8] = (4, 6, 6)
    sol.command_array[9] = (4, 7, 7)
    sol.command_array[10] = (4, 6, 7)

    sol.command_array[11] = (4, 1, 6)
    sol.command_array[12] = (4, 2, 7)
    sol.command_array[13] = (4, 3, 8)
    sol.command_array[14] = (4, 4, 9)
    sol.command_array[15] = (4, 5, 10)

    sol.command_array[16] = (2, 0, 11)
    sol.command_array[17] = (2, 16, 12)
    sol.command_array[18] = (2, 17, 13)
    sol.command_array[19] = (2, 18, 14)
    sol.command_array[20] = (2, 19, 15)
    # print(sol.latexstring())
    # sol.set_constants(consts)

    # create training data
    training_data = ExplicitTrainingData(x_true, y)

    # create fitness metric
    explicit_regressor = StandardRegression()
    explicit_regressor_w_deriv = StandardRegression(const_deriv=True)

    # fit the constants
    explicit_regressor.evaluate_fitness(sol, training_data)
    c_fit_1 = sol.constants

    # fit the constants ausing const derivatives
    sol.set_constants([])
    explicit_regressor_w_deriv.evaluate_fitness(sol, training_data)
    c_fit_2 = sol.constants

    # make sure constants are close
    print("FITTED:    ", c_fit_1)
    print("REL DIFF:  ", (consts - c_fit_1) / consts)
    print("FITTED W DERIV:    ", c_fit_2)
    print("REL DIFF W DERIV:  ", (consts - c_fit_2) / consts)
    for tru, fit1, fit2 in zip(consts, c_fit_1, c_fit_2):
        assert np.abs(tru - fit1) < 1e-8
        assert np.abs(tru - fit2) < 1e-8
예제 #19
0
def test_const_opt_agraphcpp_implicit():
    """test optimization code"""
    print("-----test_const_opt_agraphcpp_implicit-----")
    # get independent vars
    x_true = snake_walk()

    # make solutions
    consts = np.random.rand(6) * 90 + 10
    print("CONSTANTS: ", consts[1:])
    y = consts[0] + consts[1] * x_true[:, 0] + consts[2] * x_true[:, 1] + \
        consts[3] * x_true[:, 0] * x_true[:, 0] + \
        consts[4] * x_true[:, 1] * x_true[:, 1] + \
        consts[5] * x_true[:, 0] * x_true[:, 1]
    x_true = np.hstack((x_true, y.reshape((-1, 1))))
    x_true, dx_dt, _ = calculate_partials(x_true)

    # create manipulator to set things up
    sol_manip = agcm(x_true.shape[1], 23, nloads=2)
    sol_manip.add_node_type(2)
    sol_manip.add_node_type(3)
    sol_manip.add_node_type(4)

    # create gene with proper functional form
    sol = sol_manip.generate()
    sol.command_array[0] = (1, -1, -1)
    sol.command_array[1] = (1, -1, -1)
    sol.command_array[2] = (1, -1, -1)
    sol.command_array[3] = (1, -1, -1)
    sol.command_array[4] = (1, -1, -1)
    sol.command_array[5] = (1, -1, -1)

    sol.command_array[6] = (0, 0, 0)
    sol.command_array[7] = (0, 1, 1)
    sol.command_array[8] = (4, 6, 6)
    sol.command_array[9] = (4, 7, 7)
    sol.command_array[10] = (4, 6, 7)

    sol.command_array[11] = (4, 1, 6)
    sol.command_array[12] = (4, 2, 7)
    sol.command_array[13] = (4, 3, 8)
    sol.command_array[14] = (4, 4, 9)
    sol.command_array[15] = (4, 5, 10)

    sol.command_array[16] = (2, 0, 11)
    sol.command_array[17] = (2, 16, 12)
    sol.command_array[18] = (2, 17, 13)
    sol.command_array[19] = (2, 18, 14)
    sol.command_array[20] = (2, 19, 15)
    sol.command_array[21] = (0, 2, 2)
    sol.command_array[22] = (3, 20, 21)
    # print(sol.latexstring())())

    # create training data
    training_data = ImplicitTrainingData(x_true)

    # create fitness metric
    implicit_regressor = ImplicitRegression(required_params=3)

    # fit the constants
    t0 = time.time()
    implicit_regressor.evaluate_fitness(sol, training_data)
    t1 = time.time()
    print("fit time: ", t1 - t0, "seconds")

    # make sure constants are close
    c_fit = sol.constants
    print(
        "average accuracy: ",
        np.mean(
            np.abs(np.array(c_fit[1:]) - np.array(consts[1:])) /
            np.array(consts[1:])))
    print("FITTED:    ", c_fit[1:])
    for tru, fit in zip(consts[1:], c_fit[1:]):
        print(np.abs(tru - fit) / tru)
        assert np.abs(tru - fit) / tru < 0.1