def test_rmul(): t1 = 3 * AD(val=3, der=1) assert t1.val == 9 assert t1.der == 3 t3 = (-4) * AD(val=-3, der=[1, 2]) assert t3.val == 12 assert t3.der.tolist() == [-4, -8]
def test_rsub(): t1 = 3 - AD(val=3, der=1) assert t1.val == 0 assert t1.der == -1 t3 = -4 - AD(val=3, der=[1, 2]) assert t3.val == -7 assert t3.der.tolist() == [-1, -2]
def test_radd(): t1 = 3 + AD(val=3, der=1) assert t1.val == 6 assert t1.der == 1 t3 = -4 + AD(val=3, der=[1, 2]) assert t3.val == -1 assert t3.der.tolist() == [1, 2]
def test_rtruediv(): t1 = 3 / AD(val=3, der=1) assert t1.val == 1 assert t1.der == pytest.approx(-0.3333333333333333) t3 = -8 / AD(val=-4, der=[1, 2]) assert t3.val == 2 assert t3.der.tolist() == [pytest.approx(0.5), pytest.approx(1)]
def test_gt(): t1 = AD(val=3, der=1) assert t1 > 2 t2 = AD(val=2, der=1) assert t1 > t2 t3 = AD(val=3, der=[1, 2]) assert t3 > 2 t4 = AD(val=4, der=[1, 2]) assert t4 > t3
def test_le(): t1 = AD(val=3, der=1) assert t1 <= 3 t2 = AD(val=4, der=1) assert t1 <= t2 t3 = AD(val=3, der=[1, 2]) assert t3 <= 3 t4 = AD(val=3, der=[1, 2]) assert t4 <= t3
def test_lt(): t1 = AD(val=3, der=1) assert t1 < 4 t2 = AD(val=4, der=1) assert t1 < t2 t3 = AD(val=3, der=[1, 2]) assert t3 < 4 t4 = AD(val=2, der=[1, 2]) assert t4 < t3
def test_ge(): t1 = AD(val=3, der=1) assert t1 >= 2 t2 = AD(val=3, der=1) assert t1 >= t2 t3 = AD(val=3, der=[1, 2]) assert t3 >= 2 t4 = AD(val=3, der=[1, 2]) assert t4 >= t3
def test_eq(): t1 = AD(val=3, der=1) assert t1 == 3 t2 = AD(val=3, der=1) assert t1 == t2 t3 = AD(val=3, der=[1, 2]) assert t3 == 3 t4 = AD(val=3, der=[1, 2]) assert t4 == t3
def test_pos(): t1 = +AD(val=3, der=1) assert t1.val == 3 assert t1.der == 1 t2 = +AD(val=-3, der=1) assert t2.val == -3 assert t2.der == 1 t3 = +AD(val=-3, der=[1, 2]) assert t3.val == -3 assert t3.der.tolist() == [1, 2]
def test_neg(): t1 = -AD(val=3, der=1) assert t1.val == -3 assert t1.der == -1 t2 = -AD(val=-3, der=1) assert t2.val == 3 assert t2.der == -1 t3 = -AD(val=-3, der=[1, 2]) assert t3.val == 3 assert t3.der.tolist() == [-1, -2]
def test_rpow(): t1 = 2**AD(val=3, der=1) assert t1.val == 8 assert t1.der == pytest.approx(5.54517744) t2 = 0**AD(val=3, der=1) assert t2.val == 0 assert t2.der == 0 t2 = 1**AD(val=0, der=1) assert t2.val == 1 assert t2.der == 0
def test_multi_var(): fn = expressioncc('log(x,2) + sin(y)', ['x', 'y']).get_fn() x = AD(4, der=[1, 0]) y = AD(3, der=[0, 1]) t1 = fn(x, y) assert t1.val == pytest.approx(2.1411200080598674) assert t1.der.tolist() == [ pytest.approx(0.36067376), pytest.approx(-0.9899925) ]
def test_missing_der_missing_nvars_idx(): # test missing n_vars with pytest.raises(KeyError): t1 = AD(val=3, idx=1) # test missing idx with pytest.raises(KeyError): t2 = AD(val=3, n_vars=2) # test declaring with only n_vars t3 = AD(val=3, n_vars=1)
def test_tanh(): t1 = tanh(AD(val=0.3, der=[1])) assert t1.val == pytest.approx(0.29131261) assert t1.der == pytest.approx(0.91513696) t2 = tanh(AD(val=0.3, der=[1, 2])) assert t2.val == pytest.approx(0.29131261) assert t2.der.tolist() == [ pytest.approx(0.91513696), pytest.approx(1.8302739236532586) ] t3 = tanh(0.3) assert t3 == pytest.approx(0.29131261)
def test_cosh(): t1 = cosh(AD(val=0.3, der=[1])) assert t1.val == pytest.approx(1.04533851) assert t1.der == pytest.approx(0.30452029) t2 = cosh(AD(val=0.3, der=[1, 2])) assert t2.val == pytest.approx(1.04533851) assert t2.der.tolist() == [ pytest.approx(0.30452029), pytest.approx(0.6090405868942852) ] t3 = cosh(0.3) assert t3 == pytest.approx(1.0453385141288605)
def test_sin(): t1 = sin(AD(val=3, der=1)) assert t1.val == pytest.approx(0.1411200080598672, 0.1) assert t1.der == pytest.approx(-0.9899924966004454) t2 = sin(AD(val=3, der=[1, 2])) assert t2.val == pytest.approx(0.1411200080598672, 0.1) assert t2.der.tolist() == [ pytest.approx(-0.9899924966004454), pytest.approx(-1.9799849932008908) ] t3 = sin(3) assert t3 == pytest.approx(0.1411200080598672, 0.1)
def test_sinh(): t1 = sinh(AD(val=0.3, der=[1])) assert t1.val == pytest.approx(0.30452029) assert t1.der == pytest.approx(1.04533851) t2 = sinh(AD(val=0.3, der=[1, 2])) assert t2.val == pytest.approx(0.30452029) assert t2.der.tolist() == [ pytest.approx(1.0453385141), pytest.approx(2.090677028257721) ] t3 = sinh(0.3) assert t3 == pytest.approx(0.30452029)
def test_tan(): t1 = tan(AD(val=3, der=1)) assert t1.val == pytest.approx(-0.1425465430742778) assert t1.der == pytest.approx(1.020319516942427) t2 = tan(AD(val=3, der=[1, 2])) assert t2.val == pytest.approx(-0.1425465430742778) assert t2.der.tolist() == [ pytest.approx(1.020319516942427), pytest.approx(2.040639033884854) ] t3 = tan(3) assert t3 == pytest.approx(-0.1425465430742778)
def test_logistic(): t1 = logistic(AD(val=0.3, der=[1])) assert t1.val == pytest.approx(0.57444252) assert t1.der == pytest.approx(0.24445831) t2 = logistic(AD(val=0.3, der=[1, 2])) assert t2.val == pytest.approx(0.57444252) assert t2.der.tolist() == [ pytest.approx(0.24445831), pytest.approx(0.4889166233814918) ] t3 = logistic(0.3) assert t3 == pytest.approx(0.57444252)
def test_exp(): t1 = exp(AD(val=3, der=1)) assert t1.val == pytest.approx(20.085536923187668) assert t1.der == pytest.approx(20.085536923187668) t2 = exp(AD(val=3, der=[1, 2])) assert t2.val == pytest.approx(20.085536923187668) assert t2.der.tolist() == [ pytest.approx(20.08553692), pytest.approx(40.17107385) ] t3 = exp(3) assert t3 == pytest.approx(20.085536923187668)
def test_cos(): t1 = cos(AD(val=3, der=1)) assert t1.val == pytest.approx(-0.9899924966004454) assert t1.der == pytest.approx(-0.1411200080598672) t2 = cos(AD(val=3, der=[1, 2])) assert t2.val == pytest.approx(-0.9899924966004454) assert t2.der.tolist() == [ pytest.approx(-0.1411200080598672), pytest.approx(-0.2822400161197344) ] t3 = cos(3) assert t3 == pytest.approx(-0.9899924966004454)
def test_arctan(): t1 = arctan(AD(val=0.3, der=[1])) assert t1.val == pytest.approx(0.29145679) assert t1.der == pytest.approx(0.91743119) t2 = arctan(AD(val=0.3, der=[1, 2])) assert t2.val == pytest.approx(0.29145679) assert t2.der.tolist() == [ pytest.approx(0.9174311926605504), pytest.approx(1.8348623853211008) ] t3 = arctan(0.3) assert t3 == pytest.approx(0.2914567944778671)
def test_log(): t1 = log(AD(val=0.3, der=[1])) assert t1.val == pytest.approx(-1.2039728) assert t1.der == pytest.approx(3.33333333) t2 = log(AD(val=0.3, der=[1, 2])) assert t2.val == pytest.approx(-1.2039728) assert t2.der.tolist() == [ pytest.approx(3.33333333), pytest.approx(6.666666666666667) ] t3 = log(0.3) assert t3 == pytest.approx(-1.2039728) with pytest.raises(ValueError): t4 = log(-1) with pytest.raises(ValueError): t4 = log(AD(val=-1, der=[1, 2]))
def arccos(obj): """Returns the arccos of a scalar or an AD object INPUTS ======= obj: AD object, scalar, or vector RETURNS ======== Returns the arccos of obj EXAMPLES ========= >>> x = AD(val=0.5, der=1) >>> print(arccos(x)) (array(1.04719755), array(-1.15470054)) """ if isinstance(obj, AD): values = obj.val if (values < (-1) or values > (1)).any(): raise ValueError('Values are not in the domain of arcsin [-1, 1].') val = np.arccos(obj.val) # this is the negative of the derivative of the arcsin der = -1 * (1 / np.sqrt(1 - (obj.val ** 2) * obj.der)) return AD(val=val, der=der) if (np.array(obj) < -1 or np.array(obj) > 1).any(): raise ValueError('Values are not in the domain of arcsin [-1, 1].') return np.arccos(obj)
def test_arccos(): t1 = arccos(AD(val=0.3, der=[1])) assert t1.val == pytest.approx(1.26610367) assert t1.der == pytest.approx(-1.04828484) t2 = arccos(AD(val=0.3, der=[1, 2])) assert t2.val == pytest.approx(1.26610367) assert t2.der.tolist() == [ pytest.approx(-1.04828484), pytest.approx(-1.1043152607484654) ] t3 = arccos(0.3) assert t3 == pytest.approx(1.26610367) with pytest.raises(ValueError): t4 = arccos(-10) with pytest.raises(ValueError): t5 = arccos(AD(val=-10, der=[1, 2]))
def log(obj, base=None): """Returns the log of a scalar, vector, or an AD object with any base INPUTS ======= obj: AD object, scalar, or vector base: the base of the log, if None defaults to natural log RETURNS ======== Returns the log of obj EXAMPLES ========= >>> x = AD(val = 3, der = 1) >>> log(x) (array(0.47712125), array(0.14476483)) """ if not base: base = np.exp(1) if isinstance(obj, AD): if obj <= 0: raise ValueError('Log accepts only positive numbers') val = np.log(obj.val) / np.log(base) der = (1 / (obj.val * np.log(base))) * obj.der return AD(val=val, der=der) if obj <= 0: raise ValueError('Log accepts only positive numbers') return np.log(obj) / np.log(base)
def test_sqrt(): t1 = sqrt(AD(val=3, der=[1])) assert t1.val == pytest.approx(1.7320508075688772) assert t1.der == pytest.approx(0.28867513459481287) t2 = sqrt(AD(val=3, der=[1, 2])) assert t2.val == pytest.approx(1.7320508075688772) assert t2.der.tolist() == [ pytest.approx(0.28867513459481287), pytest.approx(0.57735027) ] t3 = sqrt(3) assert t3 == pytest.approx(1.7320508075688772) with pytest.raises(TypeError, match=r"Sqrt has a positive domain, input negative"): t4 = sqrt(-1) with pytest.raises(TypeError, match=r"Sqrt has a positive domain, input negative"): t5 = sqrt(AD(val=-1, der=[1, 2]))
def test_pow(): t1 = AD(val=3, der=1)**2 assert t1.val == 9 assert t1.der == 6 t2 = AD(val=3, der=1)**AD(val=5, der=1) assert t2.val == 243 assert t2.der == pytest.approx(671.96278615) t3 = AD(val=0, der=1)**AD(val=5, der=1) assert t3.val == 0 assert t3.der == pytest.approx(0.) t4 = AD(val=0, der=1)**2 assert t4.val.tolist() == 0 assert t4.der.tolist() == 0 t5 = AD(val=-1, der=1)**2 assert t5.val.tolist() == 1 assert t5.der.tolist() == -2
def test_sub(): t1 = AD(val=3, der=1) - 3 assert t1.val == 0 assert t1.der == 1 t2 = AD(val=3, der=1) - AD(val=4, der=1) assert t2.val == -1 assert t2.der == 0 t3 = AD(val=3, der=[1, 2]) - 4 assert t3.val == -1 assert t3.der.tolist() == [1, 2] t4 = AD(val=3, der=[1, 2]) - AD(val=-8, der=[3, 1]) assert t4 == 11 assert t4.der.tolist() == [-2, 1]