def test_log():
    ## scaler
    a = Ad_Var(1, -3)
    b = Ad_Var.log(a)
    assert b.get_val() == np.log(1)
    assert b.get_ders() == -3
    ## gradient
    x1 = Ad_Var(1, np.array([1, 0]))
    x2 = Ad_Var(1, np.array([0, 1]))
    f = Ad_Var.log(x1 + x2)
    assert f.get_val() == np.log(1 + 1)
    assert (f.get_ders() == [1 / 2, 1 / 2]).all()
def test_func():
    x = Ad_Var(1, np.array([1, 0, 0]))
    y = Ad_Var(2, np.array([0, 1, 0]))
    z = 's'
    try:
        f = np.array([
            Ad_Var.cos(x) * (y + 2), 1 + y**2 / (x * y * 3),
            3 * Ad_Var.log(x * 2) + Ad_Var.exp(x / y),
            Ad_Var.arctan(Ad_Var.arcsin(y / 4))
        ])
        Ad_Var.get_values(f, z)
    except TypeError:
        print("TypeError sucessfully catched - get_values1")

    try:
        Ad_Var.get_values([3, 2, 1])
    except TypeError:
        print("TypeError sucessfully catched - get_values2")

    try:
        f = np.array([
            Ad_Var.cos(x) * (y + 2), 1 + y**2 / (x * y * 3),
            3 * Ad_Var.log(x * 2) + Ad_Var.exp(x / y),
            Ad_Var.arctan(Ad_Var.arcsin(y / 4))
        ])
        Ad_Var.get_jacobian(f, z)
    except TypeError:
        print("TypeError sucessfully catched - get_jacobian1")

    try:
        f = np.array([
            Ad_Var.cos(x) * (y + 2), 1 + y**2 / (x * y * 3),
            3 * Ad_Var.log(x * 2) + Ad_Var.exp(x / y),
            Ad_Var.arctan(Ad_Var.arcsin(y / 4))
        ])
        Ad_Var.get_jacobian([1, 2, 3], 3, 2)
    except TypeError:
        print("TypeError sucessfully catched - get_jacobian2")

    try:
        f = np.array([
            Ad_Var.cos(x) * (y + 2), 1 + x**2 / (x * y * 3),
            3 * Ad_Var.log(x * 2) + Ad_Var.exp(x / y),
            Ad_Var.arctan(Ad_Var.arcsin(y / 4))
        ])
        Ad_Var.get_jacobian(f, 5, 4)
    except ValueError:
        print("ValueError sucessfully catched - get_jacobian3")
def test_multiple():
    x = Ad_Var(1, np.array([1, 0, 0]))
    y = Ad_Var(2, np.array([0, 1, 0]))
    z = Ad_Var(3, np.array([0, 0, 1]))
    f = np.array([
        Ad_Var.cos(x) * (y + 2), 1 + z**2 / (x * y * 3),
        3 * Ad_Var.log(x * 2) + Ad_Var.exp(x / z),
        Ad_Var.arctan(Ad_Var.arcsin(y / 4))
    ])
    assert (Ad_Var.get_values(f) == [
        np.cos(1) * 4, 1 + 3**2 / 6, 3 * np.log(2) + np.exp(1 / 3),
        np.arctan(np.arcsin(1 / 2))
    ]).all()
    assert (Ad_Var.get_jacobian(f, 4, 3) == [
        [-4 * np.sin(1), np.cos(1), 0], [-1.5, -0.75, 1],
        [3 + np.exp(1 / 3) / 3, 0, -np.exp(1 / 3) / 9],
        [0, 1 / (4 * (np.sqrt(3 / 4)) * (np.arcsin(1 / 2)**2 + 1)), 0]
    ]).all()