Exemplo n.º 1
0
def rm_test_overload_abs():
    x = DualNumber(-5,Reverse=True)
    y = abs(x)
    assert y.val == 5 and y.der == 0
    x = DualNumber(5,1,Reverse=True)
    y = abs(x)
    assert y.val == 5 and y.der == 0
Exemplo n.º 2
0
def test_overload_abs():
    x = DualNumber(-5,-1)
    y = abs(x)
    assert y.val == 5 and y.der == 1
    x = DualNumber(5,1)
    y = abs(x)
    assert y.val == 5 and y.der == 1
Exemplo n.º 3
0
def test_overload_ne():
    w = DualNumber(5,1)
    x = DualNumber(5,1)
    y = DualNumber(6,1)
    z = DualNumber(5,2)
    assert not w != x
    assert x != y
    assert x != z
Exemplo n.º 4
0
def rm_test_overload_multiply():
    x = DualNumber(5,Reverse=True)
    y = DualNumber(7,Reverse=True)

    assert (x * y).val == 35 and (x * y).der == 0
    assert (x * 5).val == 25 and (x * 5).der == 0
    assert (x * 5.0).val == 25 and (x * 5.0).der == 0
    assert (5.0 * x).val == 25 and (5.0 * x).der == 0
    assert (5 * x).val == 25 and (5 * x).der == 0
Exemplo n.º 5
0
def rm_test_overload_add():
    x = DualNumber(5,Reverse=True)
    y = DualNumber(7,Reverse=True)

    assert (x + y).val == 12 and (x + y).der == 0
    assert (x + 5).val == 10 and (x + 5).der == 0
    assert (x + 5.0).val == 10 and (x + 5.0).der == 0
    assert (5 + x).val == 10 and (5 + x).der == 0
    assert (5.0 + x).val == 10 and (5.0 + x).der == 0
Exemplo n.º 6
0
def test_overload_multiply():
    x = DualNumber(5)
    y = DualNumber(7,2)

    assert (x * y).val == 35 and (x * y).der == 17
    assert (x * 5).val == 25 and (x * 5).der == 5
    assert (x * 5.0).val == 25 and (x * 5.0).der == 5
    assert (5.0 * x).val == 25 and (5.0 * x).der == 5
    assert (5 * x).val == 25 and (5 * x).der == 5
Exemplo n.º 7
0
def test_ArcCos():
    Test_Dual_Number_1 = DualNumber(0.5)
    assert EF.ArcCos(Test_Dual_Number_1).val == np.arccos(0.5) and EF.ArcCos(Test_Dual_Number_1).der == -1 / np.sqrt(
        0.75)
    Test_Dual_Number_1 = 0.5
    assert EF.ArcCos(Test_Dual_Number_1).val == np.arccos(0.5) and EF.ArcCos(Test_Dual_Number_1).der == 0
    with pytest.raises(ValueError):
        x = DualNumber(5)
        EF.ArcCos(x)
Exemplo n.º 8
0
def test_overload_add():
    x = DualNumber(5,1)
    y = DualNumber(7,1)

    assert (x + y).val == 12 and (x + y).der == 2
    assert (x + 5).val == 10 and (x + 5).der == 1
    assert (x + 5.0).val == 10 and (x + 5.0).der == 1
    assert (5 + x).val == 10 and (5 + x).der == 1
    assert (5.0 + x).val == 10 and (5.0 + x).der == 1
Exemplo n.º 9
0
def rm_test_overload_power():
    x = DualNumber(2,Reverse=True)
    y = DualNumber(3,Reverse=True)

    assert (x**y).val == 8 and (x**y).der == 0
    assert (x.__rpow__(y)).val == 9 and (x.__rpow__(y)).der == 0
    assert (x**2).val == 4 and (x**2).der == 0
    assert (x**2.0).val == 4 and (x**2.0).der == 0
    assert (2**x).val == 4 and (2**x).der == 0
    assert (2.0**x).val == 4 and (2.0**x).der == 0
Exemplo n.º 10
0
def rm_test_overload_truediv():
    x = DualNumber(10,Reverse=True)
    y = DualNumber(2,Reverse=True)

    assert (x / y).val == 5 and (x / y).der == 0
    assert (x.__rtruediv__(y)).val == 0.2 and (x.__rtruediv__(y)).der == 0
    assert (x / 5).val == 2 and (x / 5).der == 0
    assert (x / 5.0).val == 2.0 and (x / 5.0).der == 0
    assert (5 / x).val == 0.5 and (5 / x).der == 0
    assert (5.0 / x).val == 0.5 and (5.0 / x).der == 0
Exemplo n.º 11
0
def rm_test_overload_sub():
    x = DualNumber(5,Reverse=True)
    y = DualNumber(7,Reverse=True)

    assert (x - y).val == -2 and (x - y).der == 0
    assert (x.__rsub__(y)).val == 2 and (x.__rsub__(y)).der == 0
    assert (x - 5).val == 0 and (x - 5).der == 0
    assert (x - 5.0).val == 0 and (x - 5.0).der == 0
    assert (5 - x).val == 0 and (5 - x).der == 0
    assert (5.0 - x).val == 0 and (5.0 - x).der == 0
Exemplo n.º 12
0
def test_Log():
    Test_Dual_Number_1 = DualNumber(1)
    assert EF.Log(Test_Dual_Number_1).val == 0 and EF.Log(Test_Dual_Number_1).der == 1
    Test_Dual_Number_1 = 1
    assert EF.Log(Test_Dual_Number_1).val == 0 and EF.Log(Test_Dual_Number_1).der == 0
    
    Test_Dual_Number_1 = DualNumber(2)
    assert EF.Log(Test_Dual_Number_1,base=10).val == np.log(2) / np.log(10)  and EF.Log(Test_Dual_Number_1,base=10).der == 1/(np.log(10)*2)
    Test_Dual_Number_1 = 2
    assert EF.Log(Test_Dual_Number_1,base=10).val == np.log(2) / np.log(10) and EF.Log(Test_Dual_Number_1,base=10).der == 0
Exemplo n.º 13
0
def test_overload_truediv():
    x = DualNumber(10,2)
    y = DualNumber(2,4)
    
    assert (x / y).val == 5 and (x / y).der == (2*2-10*4)/(2**2)
    assert (x.__rtruediv__(y)).val == 0.2 and (x.__rtruediv__(y)).der == (4*10-2*2)/(10*10)
    assert (x / 5).val == 2 and (x / 5).der == 0.4
    assert (x / 5.0).val == 2.0 and (x / 5.0).der == 0.4
    assert (5 / x).val == 0.5 and (5 / x).der == -0.1
    assert (5.0 / x).val == 0.5 and (5.0 / x).der == -0.1
Exemplo n.º 14
0
def test_overload_sub():
    x = DualNumber(5,2)
    y = DualNumber(7,1)

    assert (x - y).val == -2 and (x - y).der == 1
    assert (x.__rsub__(y)).val == 2 and (x.__rsub__(y)).der == -1
    assert (x - 5).val == 0 and (x - 5).der == 2
    assert (x - 5.0).val == 0 and (x - 5.0).der == 2
    assert (5 - x).val == 0 and (5 - x).der == -2
    assert (5.0 - x).val == 0 and (5.0 - x).der == -2
Exemplo n.º 15
0
def test_overload_power():
    x = DualNumber(2,2)
    y = DualNumber(3,4)

    assert (x**y).val == 8 and (x**y).der == 8*(3/2*2+4*np.log(2))
    assert (x.__rpow__(y)).val == 9 and (x.__rpow__(y)).der == 9*(2/3*4+2*np.log(3))
    assert (x**2).val == 4 and (x**2).der == 8
    assert (x**2.0).val == 4 and (x**2.0).der == 8
    assert (2**x).val == 4 and (2**x).der == np.log(2)*4*2
    assert (2.0**x).val == 4 and (2.0**x).der == np.log(2)*4*2
Exemplo n.º 16
0
    def get_value(self, loc):
        """
        DESCRIPTION
        =======
        A class method to get the value of user-specified vector function.  See
        doctests for details on usage.  User inputs location of vector-valued function,
        and get_value returns the value at the specified location.
        
        >>> PAD = Parallelized_AD(fun=['_x * arcSin(_y*_z)+_x'], var=['x', 'y', 'z'])
        >>> print(PAD.get_value([0.4,0.2,1]))
        [0.48054317]
        >>> print(PAD.get_Jacobian([0.4,0.2,1]))
        [[1.20135792 0.40824829 0.08164966]]
        """
        assert len(loc) == len(self.varname)
        self._value = np.zeros((len(self.function)))

        # for each function, if forward, do forward mode calculation, else do reverse
        # see documentation for details on reverse mode calculation
        for i, fun in enumerate(self.function):

            # pre-process each function to be differentatied
            translated_fun = self.preprocess(fun)

            # for each variable, take the derivative at the value specified
            # for each variable, take the derivative at the value specified
            self.variable = [DualNumber(value) for value in loc]
            element = eval(translated_fun)
            self._value[i] = element.val
        return self._value
def Sin(x):
    '''
    >>> print(Sin(DualNumber(5,1)))
    Derivative: 0.28
    Value: -0.96
    >>> print(Sin(DualNumber(5,Reverse=True)))
    Derivative: 0.00
    Value: -0.96
    '''
    if data_type_check(x) == 0:
        if x._rev:
            z = DualNumber(np.sin(x._val), Reverse=True)
            x.children.append((np.cos(x._val), z))
            return z
        return DualNumber(np.sin(x._val), np.cos(x._val) * x._der)
    else:
        return DualNumber(np.sin(x), 0)
def Sqrt(x):
    '''
    >>> print(Sqrt(DualNumber(9,1)))
    Derivative: 0.17
    Value: 3.00
    >>> print(Sqrt(DualNumber(9,Reverse = True)))
    Derivative: 0.00
    Value: 3.00
    '''
    if data_type_check(x) == 0:
        if x._rev:
            z = DualNumber(np.sqrt(x._val), Reverse=True)
            x.children.append((1 / (2 * np.sqrt(x._val)), z))
            return z
        return DualNumber(np.sqrt(x._val), 1 / (2 * np.sqrt(x._val)) * x._der)
    else:
        return DualNumber(np.sqrt(x), 0)
def ArcTan(x):
    '''
    >>> print(ArcTan(DualNumber(0.5)))
    Derivative: 0.80
    Value: 0.46
    >>> print(ArcTan(DualNumber(0.5,Reverse = True)))
    Derivative: 0.00
    Value: 0.46
    '''
    if data_type_check(x) == 0:
        if x._rev:
            z = DualNumber(np.arctan(x._val), Reverse=True)
            x.children.append((1 / (1 + x._val**2), z))
            return z
        return DualNumber(np.arctan(x._val), 1 / (1 + x._val**2) * x._der)
    else:
        return DualNumber(np.arctan(x), 0)
def Power(x, n):
    '''
    >>> print(Power(DualNumber(5,1),2))
    Derivative: 10.00
    Value: 25.00
    >>> print(Power(DualNumber(5,Reverse = True),2))
    Derivative: 0.00
    Value: 25.00
    '''
    if data_type_check(x) == 0:
        if x._rev:
            z = DualNumber(x._val**n, Reverse=True)
            x.children.append(((n * (x._val**(n - 1)), z)))
            return z
        return DualNumber(x._val**n, n * (x._val**(n - 1)) * x._der)
    else:
        return DualNumber(x**n, 0)
def Exp(x):
    '''
    >>> print(Exp(DualNumber(5,1)))
    Derivative: 148.41
    Value: 148.41
    >>> print(Exp(DualNumber(5,Reverse = True)))
    Derivative: 0.00
    Value: 148.41
    '''
    if data_type_check(x) == 0:
        if x._rev:
            z = DualNumber(np.exp(x._val), Reverse=True)
            x.children.append((np.exp(x._val), z))
            return z
        return DualNumber(np.exp(x._val), np.exp(x._val) * x._der)
    else:
        return DualNumber(np.exp(x), 0)
def Logistic(x):
    '''
    >>> print(Logistic(DualNumber(5,1)))
    Derivative: 0.01
    Value: 0.99
    >>> print(Logistic(DualNumber(5,Reverse = True)))
    Derivative: 0.00
    Value: 0.99
    '''
    if data_type_check(x) == 0:
        if x._rev:
            z = DualNumber(1 / (1 + np.exp(-x._val)), Reverse=True)
            x.children.append((np.exp(x._val) / (1 + np.exp(x._val))**2, z))
            return z
        return DualNumber(1 / (1 + np.exp(-x._val)),
                          (np.exp(x._val) / (1 + np.exp(x._val))**2) * x._der)
    else:
        return DualNumber(1 / (1 + np.exp(-x)), 0)
def Tan(x):
    '''
    >>> print(Tan(DualNumber(5,1)))
    Derivative: 12.43
    Value: -3.38
    >>> print(Tan(DualNumber(5,Reverse = True)))
    Derivative: 0.00
    Value: -3.38
    '''
    if data_type_check(x) == 0:
        if x._rev:
            z = DualNumber(np.tan(x._val), Reverse=True)
            x.children.append(((1 + np.tan(x._val) * np.tan(x._val)), z))
            return z
        return DualNumber(np.tan(x._val),
                          (1 + np.tan(x._val) * np.tan(x._val)) * x._der)
    else:
        return DualNumber(np.tan(x), 0)
def Cosh(x):
    '''
    >>> print(Cosh(DualNumber(5,1)))
    Derivative: 74.20
    Value: 74.21
    >>> print(Cosh(DualNumber(5,Reverse =  True)))
    Derivative: 0.00
    Value: 74.21
    '''
    if data_type_check(x) == 0:
        if x._rev:
            z = DualNumber((np.exp(x._val) + np.exp(-x._val)) / 2,
                           Reverse=True)
            x.children.append(((np.exp(x._val) - np.exp(-x._val)) / 2, z))
            return z
        return DualNumber((np.exp(x._val) + np.exp(-x._val)) / 2,
                          ((np.exp(x._val) - np.exp(-x._val)) / 2) * x._der)
    else:
        return DualNumber((np.exp(x) + np.exp(-x)) / 2, 0)
def Log(x, base=np.exp(1)):
    '''
    >>> print(Log(DualNumber(5,1)))
    Derivative: 0.20
    Value: 1.61
    >>> print(Log(DualNumber(5,Reverse = True)))
    Derivative: 0.00
    Value: 1.61
    '''
    if data_type_check(x) == 0:
        if x._rev:
            z = DualNumber(np.log(x._val) / np.log(base), Reverse=True)
            x.children.append((1 / (x._val * np.log(base)), z))
            return z
        return DualNumber(
            np.log(x._val) / np.log(base),
            (1 / (x._val * np.log(base))) * x._der)
    else:
        return DualNumber(np.log(x) / np.log(base), 0)
Exemplo n.º 26
0
    def get_Jacobian(self, loc, forward=False):
        """
        DESCRIPTION
        =======
        A class method to get the Jacobian of user-specified vector function.  See
        doctests for details on usage.  User inputs location to take Jacobian, and
        function returns the Jacobian at that point.  Assert conditions ensure 
        dimension of location input is the same as the number of variables.
        
        forward argument specifies whether reverse (False) or forward (True) mode
        is used
        """

        assert len(loc) == len(self.varname)
        self._Jacobian = np.zeros((len(self.function), len(self.varname)))

        # for each function, if forward, do forward mode calculation, else do reverse
        # see documentation for details on reverse mode calculation
        for i, fun in enumerate(self.function):
            if forward:
                # pre-process each function to be differentatied
                translated_fun = self.preprocess(fun)
                # for each variable, take the derivative at the value specified
                for j in range(len(self.varname)):
                    self.variable = [
                        DualNumber(value, dual=0) for value in loc
                    ]
                    self.variable[j] = DualNumber(loc[j], dual=1)
                    element = eval(translated_fun)
                    self._Jacobian[i, j] = element.der
            # similarly, if reverse, carry out reverse mode
            else:

                self.variable = [
                    DualNumber(value, Reverse=True) for value in loc
                ]
                translated_fun = self.preprocess(fun)
                element = eval(translated_fun)
                element.set_der(1)
                for j in range(len(self.varname)):
                    self._Jacobian[i, j] = self.variable[j].der
        return self._Jacobian
def ArcCos(x):
    '''
    >>> print(ArcCos(DualNumber(0.5)))
    Derivative: -1.15
    Value: 1.05
    >>> print(ArcCos(DualNumber(0.5,Reverse = True)))
    Derivative: 0.00
    Value: 1.05
    '''
    if abs(x) >= 1:
        raise ValueError('ArcCos is only defined on (-1,1)!')
    if data_type_check(x) == 0:
        if x._rev:
            z = DualNumber(np.arccos(x._val), Reverse=True)
            x.children.append((-1 / np.sqrt(1 - x._val**2), z))
            return z
        return DualNumber(np.arccos(x._val),
                          -1 / np.sqrt(1 - x._val**2) * x._der)
    else:
        return DualNumber(np.arccos(x), 0)
def Tanh(x):
    '''
    >>> print(Tanh(DualNumber(5,1)))
    Derivative: 0.00
    Value: 1.00
    >>> print(Tanh(DualNumber(5,Reverse =  True)))
    Derivative: 0.00
    Value: 1.00
    '''
    if data_type_check(x) == 0:
        Z = (np.exp(x._val) - np.exp(-x._val)) / (np.exp(x._val) +
                                                  np.exp(-x._val))
        if x._rev:
            z = DualNumber(Z, Reverse=True)
            x.children.append((1 - Z**2, z))
            return z
        return DualNumber(Z, (1 - Z**2) * x._der)
    else:
        return DualNumber((np.exp(x) - np.exp(-x)) / (np.exp(x) + np.exp(-x)),
                          0)
Exemplo n.º 29
0
 def Demo_gradient(x):
     x=DualNumber(x);
     y=-EF.Sin(x)*EF.Cos(x)*EF.Tan(x)+EF.Exp(x)*EF.Log(x)*EF.Sqrt(x)*2
     return y.der #y=sin(x)cos(x)tan(x)-2exp(x)log(x)sqrt(x)
Exemplo n.º 30
0
def Given_function(x):
    x = DualNumber(x)
    y = EF.Sin(x) * EF.Cos(x) * EF.Tan(x) - EF.Exp(x) * EF.Log(x) * EF.Sqrt(
        x) * 2
    return y  #y=sin(x)cos(x)tan(x)-2exp(x)log(x)sqrt(x)