def test_sin():
    x = AutoDiff(2, name="x")
    x1 = AutoDiff.sin(x)
    assert x1.val == [np.sin(2)]
    assert x1.der['x'] == [np.cos(2)]

    x = AutoDiff(2.0, 1.0, "x")
    f1 = AutoDiff.sin(3 * x + 2)
    assert f1.val == np.sin(8.0)
    assert f1.der["x"] == 3 * np.cos(8.0)
def test_complicated_func():
    tol = 1e-4
    x = AutoDiff(2.0, name="x")
    f1 = AutoDiff.sin((AutoDiff.cos(x)**2.0 + x**2.0)**0.5)
    assert abs(f1.val - 0.890643) < tol
    assert abs(f1.der["x"] - (-0.529395)) < tol

    x = AutoDiff([1.0, 3.0, 5.0, 7.0], name="x")
    f2 = AutoDiff.sin(AutoDiff.ln(x) + (3 * x**2) + (2 * x) + 7)
    assert np.array_equal(
        f2.val,
        np.array([
            np.sin(12),
            np.sin(40 + np.log(3)),
            np.sin(92 + np.log(5)),
            np.sin(168 + np.log(7))
        ]))
    assert np.array_equal(
        f2.der["x"],
        np.array([
            9 * np.cos(12), 61 / 3 * np.cos(40 + np.log(3)),
            161 / 5 * np.cos(92 + np.log(5)), 309 / 7 * np.cos(168 + np.log(7))
        ]))

    x = AutoDiff([-1.0, -3.0, -5.0, -7.0, 0.1], name="x")
    f3 = AutoDiff.logistic(AutoDiff.tan(x) + (3 * x**(-2)) + (2 * x) + 7)
    assert np.less(
        abs(f3.val - np.array([
            1 / (1 + np.exp(np.tan(1) - 8)), 1 /
            (1 + np.exp(np.tan(3) - 4 / 3)), 1 /
            (1 + np.exp(np.tan(5) + 72 / 25)), 1 /
            (1 + np.exp(np.tan(7) + 340 / 49)), 1
        ])),
        np.ones((5, 1)) * tol).all()
    assert np.less(
        abs(f3.der["x"] -
            np.array([0.018135, 0.49104, 3.40145666, 0.001531, 0])),
        np.ones((5, 1)) * tol).all()