예제 #1
0
def test_abs():
    x = VAD([-1, 2, 3])
    f = abs(x)
    print(f.der)
    print(f.der2)
    assert np.sum(f.val == np.array(
        [[1], [2], [3]])) == 3, "Error: abs didn't apply properly on VAD."
    assert np.sum(
        f.der == np.array([[-1., 0., 0.], [0., 1., 0.], [0., 0., 1.]
                           ])) == 9, "Error: der1 for abs(VAD) is not correct."
    x = AD.AD(-1, tag=0)
    f = abs(x)
    assert f.val == 1, "Error: abs didn't apply properly on AD."
    assert f.der == -1, "Error: der1 for abs(AD) is not correct."
    assert abs(-5) == 5, "Error: abs didn't apply properly on numbers."
    x = AD.AD(0, tag=0)
    with pytest.raises(Exception):
        f = abs(x)
    with pytest.raises(TypeError):
        f = admath.abs('error')
    xv = AD.AD(-2, tag=0, order=3)
    f = admath.abs(xv)
    assert f.higherdiff(3) == 0, "Error: abs didn't apply on higher properly"
    [x] = VAD([-5], order=3)
    f = abs(x)
    print(f.der)
    print(f.der2)
    print(f.higher)
예제 #2
0
def test_AD_init_hw():
    with pytest.raises(TypeError):
        x = ad.AD(-1, tag=0, size=1.5)
        x = ad.AD(-1, tag=0, order=1.5)
        x = ad.AD(-1, tag=0, order='error')
        x = VAD([-1], order='error')
    with pytest.raises(ValueError):
        x = ad.AD(-1, order=0)
    with pytest.raises(Exception):
        x = VAD([1, 2, 3], order=5)
        x = ad.AD([1, 2, 3], order=5)
    def __init__(self, val, der=None, der2=None, order=2, higher=None):
        """
        Overwrites the __init__ dunder method to create a new VAD object with initial value and derivatives.
    
                Parameters:
                        val (int or float or list or np.array): the initial value of the new VAD object.
                        der (int or float or list or np.array): first-order derivatives of the new AD object. 
                        der2 (int or float or list or np.array): second-order derivatives of the new AD object. 

                Returns:
                        None, but initializes AD object(s) when called
                
                Example:
                >>> x, y = VAD([1,2]) 
                >>> x
                AD(value: [1], derivatives: [1., 0.])

                >>> fs = VAD([1,2]) 
                >>> fs
                VAD(value: [1 2], derivatives: [[1. 0.]
                                                [0. 1.]])
        """
        self.val = np.array(val)
        if der is None:
            self.der = np.eye(len(self))
            self.der2 = np.zeros((len(self),len(self),len(self)))
        else:
            self.der = der
            self.der2 = der2
        self.tag = np.array([i for i in range(len(self))])
        self.size = len(self)

        if not isinstance(order, numbers.Integral):
            raise TypeError("Highest order of derivatives must be a positive integer.")
        elif order < 1:
            raise ValueError("Highest order of derivatives must be at least 1.")
        elif order > 2 and self.size > 1:
            raise Exception("We cannot handle derivatives of order > 2 for more than one scalar variables.")

        self.order = order
        self.higher = higher

        if self.size > 1:
            arr_ad = np.array([None]*len(self))
            for i in range(len(self)):
                arr_ad[i] = ad.AD(val=self.val[i], tag=self.tag[i], size = self.size,
                                der=self.der[i], der2=self.der2[i])
            self.variables = arr_ad
        else:
            arr_ad = np.array([None]*len(self))
            arr_ad[0] = ad.AD(val=self.val[0], tag=self.tag[0], size = 1,
                                der=self.der[0], der2=self.der2[0], 
                                order=self.order, higher = self.higher)
            self.variables = arr_ad
예제 #4
0
def test_AD_pow_hw():
    x = ad.AD(val=1, order=10, size=1, tag=0)
    f = x**5

    assert np.abs(f.val - 1) < 1e-8, "rpow not working for AD"
    x = ad.AD(val=0, order=10, size=1, tag=0)

    with pytest.raises(ValueError):
        f = x**5
        f = x**2
    with pytest.raises(TypeError):
        f = x**'a'
예제 #5
0
def test_higher_hw():
    x = ad.AD(val=1, order=10, size=1, tag=0)
    f = x**5
    assert f.higherdiff(1) == 5, "higherdiff not working"
    with pytest.raises(TypeError):
        f.higherdiff('error')
    with pytest.raises(ValueError):
        f.higherdiff(0)
        f.higherdiff(15)
    with pytest.raises(Exception):
        x = ad.AD(val=1, size=1, tag=0)
        f = x**5
        f.higherdiff(10)
예제 #6
0
def test_log():
    x = AD.AD(1, tag=0, order=5)
    f = log(x)
    assert f.val[0] == np.log(1), "Error: log didn't apply properly on AD."
    assert np.allclose(f.der, 1), "Error: der1 for log(AD) is not correct."
    assert np.allclose(f.der2, -1), "Error: der2 for log(AD) is not correct."
    higherarr = np.array([1, -1, 2, -6, 24])
    assert np.allclose(
        f.higher, higherarr), "Error: higherder for log(AD) is not correct."
    y = VAD([1, 2, 3])
    g = log(y)
    assert np.allclose(g.val,
                       np.log([1, 2,
                               3])), "Error: log didn't apply properly on VAD."
    dertest = np.zeros((3, 3))
    dertest[0, 0] = 1
    dertest[1, 1] = 1 / 2
    dertest[2, 2] = 1 / 3
    assert np.allclose(g.der,
                       dertest), "Error: der1 for log(VAD) is not correct."
    der2test = np.zeros((3, 3, 3))
    der2test[0, 0, 0] = -1**-2
    der2test[1, 1, 1] = -2**-2
    der2test[2, 2, 2] = -3**-2
    assert np.allclose(g.der2,
                       der2test), "Error: der2 for log(VAD) is not correct."
    assert log(5) == np.log(5), "Error: log didn't apply properly on number."
    with pytest.raises(TypeError):
        f = admath.log('error')
    x, y = VAD([2, 3])
    p = log(x, base=y)
    assert np.allclose(p.val[0], np.log(2) / np.log(3))
예제 #7
0
def test_exp():
    x = AD.AD(1, tag=0, order=5)
    f = exp(x)
    assert f.val[0] == np.exp(1), "Error: exp didn't apply properly on AD."
    assert np.allclose(f.der,
                       np.exp(1)), "Error: der1 for exp(AD) is not correct."
    assert np.allclose(f.der2,
                       np.exp(1)), "Error: der2 for exp(AD) is not correct."
    higherarr = np.array(
        [np.exp(1), np.exp(1),
         np.exp(1), np.exp(1),
         np.exp(1)])
    assert np.allclose(
        f.higher, higherarr), "Error: higherder for exp(AD) is not correct."
    y = VAD([1, 2, 3])
    g = exp(y)
    assert np.allclose(g.val,
                       np.exp([1, 2,
                               3])), "Error: exp didn't apply properly on VAD."
    dertest = np.zeros((3, 3))
    dertest[0, 0] = np.exp(1)
    dertest[1, 1] = np.exp(2)
    dertest[2, 2] = np.exp(3)
    assert np.allclose(g.der,
                       dertest), "Error: der1 for exp(VAD) is not correct."
    der2test = np.zeros((3, 3, 3))
    der2test[0, 0, 0] = np.exp(1)
    der2test[1, 1, 1] = np.exp(2)
    der2test[2, 2, 2] = np.exp(3)
    assert np.allclose(g.der2,
                       der2test), "Error: der2 for exp(VAD) is not correct."
    assert exp(5) == np.exp(5), "Error: exp didn't apply properly on number."
    with pytest.raises(TypeError):
        f = admath.exp('error')
예제 #8
0
def test_sqrt():
    x = AD.AD(2, tag=0, order=3)
    f = sqrt(x)
    assert f.val[0] == np.sqrt(2), "Error: sqrt didn't apply properly on AD."
    assert np.allclose(f.der, 0.5 * 1 /
                       np.sqrt(2)), "Error: der1 for sqrt(AD) is not correct."
    assert np.allclose(f.der2, -0.25 / 2 /
                       np.sqrt(2)), "Error: der2 for sqrt(AD) is not correct."
    assert np.abs(f.higherdiff(3) - 3 / 32 / np.sqrt(2)
                  ) < 1e-8, "Error: higherder for sqrt(AD) is not correct."
    y = VAD([1, 2])
    g = sqrt(y)
    assert np.allclose(g.val, np.sqrt(
        [1, 2])), "Error: sqrt didn't apply properly on VAD."
    dertest = np.zeros((2, 2))
    dertest[0, 0] = 0.5
    dertest[1, 1] = 0.5 * 1 / np.sqrt(2)
    assert np.allclose(g.der,
                       dertest), "Error: der1 for sqrt(VAD) is not correct."
    der2test = np.zeros((2, 2, 2))
    der2test[0, 0, 0] = -0.25
    der2test[1, 1, 1] = -0.25 / 2 / np.sqrt(2)
    assert np.allclose(g.der2,
                       der2test), "Error: der2 for sqrt(VAD) is not correct."
    assert sqrt(5) == np.sqrt(
        5), "Error: sqrt didn't apply properly on number."
    with pytest.raises(TypeError):
        f = admath.sqrt('error')
예제 #9
0
def test_AD_ueq_hw():
    x = ad.AD([1], tag=0, der=[1], order=5)
    y = 2 * x
    assert x != y, "Error: ne not working for AD"
    assert x < y, "Error: ne not working for AD"
    assert y > x, "Error: ne not working for AD"
    assert x <= y, "Error: ne not working for AD"
    assert y >= x, "Error: ne not working for AD"
예제 #10
0
def test_chain_rule():
    x = AD.AD(2, order=5)
    newad = 5 * x**3 + 2
    higherde = np.array([60, 60, 30, 0, 0])
    adres = admath.chain_rule(x, 42, 60, 60, higher_der=higherde)
    assert newad == adres, "Error: chain rule doesn't apply to AD object properly."
    assert np.allclose(
        newad.higher, adres.higher
    ), "Error: chain rule doesn't carry higher derivatives properly."
예제 #11
0
def chain_rule(ad, new_val, der, der2, higher_der=None):
    """
    Applies chain rule to returns a new AD object with correct value and derivatives.

            Parameters:
                    ad (AD): An AD object
                    new_val (float): Value of the new AD object
                    der (float): Derivative of the outer function in chain rule

            Returns:
                    new_ad (AD): a new AD object with correct value and derivatives

            Example:
            >>> import AD as AD
            >>> x = AD.AD(2,order=5)
            >>> newad = 5*x**3+2
            >>> higherde = np.array([60,60,30,0,0])
            >>> chain_rule(x, 42, 60, 60, higher_der=higherde)
            AD(value: [42], derivatives: [60.])
    """
    new_der = der * ad.der
    new_der2 = der * ad.der2 + der2 * np.matmul(
        np.array([ad.der]).T, np.array([ad.der]))
    if ad.higher is None:
        new_ad = AD.AD(new_val, tag=ad.tag, der=new_der, der2=new_der2)
    else:
        new_higher_der = np.array([0.0] * len(ad.higher))
        new_higher_der[0] = new_der
        new_higher_der[1] = new_der2
        for i in range(2, len(ad.higher)):
            n = i + 1
            sum = 0
            for k in range(1, n + 1):
                sum += higher_der[k - 1] * sp.bell(n, k,
                                                   ad.higher[0:n - k + 1])
            new_higher_der[i] = sum
        new_ad = AD.AD(new_val,
                       tag=ad.tag,
                       der=new_der,
                       der2=new_der2,
                       order=len(ad.higher))
        new_ad.higher = new_higher_der

    return new_ad
예제 #12
0
def test_AD_eq_hw():
    x = ad.AD([1], tag=0, der=[1], order=5)
    y = VAD([1])
    with pytest.raises(TypeError):
        x == y
        x.fullequal(y)
        x < y
        x > y
        x <= y
        x >= y
        y = VAD([1])

    y = 0
    with pytest.raises(TypeError):
        x == y
        x.fullequal(y)
        x < y
        x > y
        x <= y
        x >= y
예제 #13
0
def test_AD_rpow_hw():
    x = ad.AD(val=1, order=10, size=1, tag=0)
    f = 5**x
    assert np.abs(f.val - 5) < 1e-8, "rpow not working for AD"
예제 #14
0
def test_set_VAD():
    x = ad.AD(1, tag=0, size=2)
    y = ad.AD(2, tag=1, size=2)
    ADs = np.array([x, y])
    assert set_VAD(ADs) == VAD([1, 2]), "Error: set_VAD is wrong."
예제 #15
0
def test_AD_add_hw():
    x = ad.AD([1], tag=0, der=[1], order=5)
    y = ad.AD([1], tag=0, der=[1], order=7)
    f = x + x
    with pytest.raises(Exception):
        f = x + y
예제 #16
0
def test_AD_ne_hw():
    x = ad.AD([1], tag=0, der=[1], order=5)
    assert not x != x, "Error: ne not working for AD"
예제 #17
0
def test_AD_repr_hw():
    x = ad.AD([1], tag=0, der=[1], order=5)
    assert x.__repr__(
    ) == 'AD(value: [[1]], derivatives: [1.])', "Error: repr is not working"
    assert x.__str__(
    ) == 'AD(value: [[1]], derivatives: [1.])', "Error: str is not working"