Exemplo n.º 1
0
    def test_array1(self):
        """
        Tests functions with single numpy 1d array output
        """

        def f1(x):
            # single scalar input
            return np.array([i*x**i for i in range(5)])

        df = jacobian(f1)(3.0)
        for i, d in enumerate(df):
            self.assertAlmostEqual(i**2 * 3.0 ** (i - 1), d)

        def f2(params):
            # one list, one numpy array input
            x,y = params[0]
            A = params[1]
            return np.linalg.dot(np.sin(A), np.array([x,y**2]))

        A = np.array([[1.0, 2.0],[3.0, 4.0]])
        x,y = 2.0, np.pi
        params = [[x, y], A]
        df = jacobian(f2)(params)
        # df0_dx
        self.assertAlmostEqual(df[0][0][0],  np.sin(A)[0][0])
        # df1_dx
        self.assertAlmostEqual(df[1][0][0],  np.sin(A)[1][0])
        # df0_dy
        self.assertAlmostEqual(df[0][0][1],  2*np.sin(A)[0][1]*y)
        # df1_dy
        self.assertAlmostEqual(df[1][0][1],  2*np.sin(A)[1][1]*y)
        # df_dA
        assert np.linalg.norm(df[0][1][0] - (np.cos(A)*np.array([x,y**2]))[0]) < 1e-10
        assert np.linalg.norm(df[1][1][1] - (np.cos(A)*np.array([x,y**2]))[1]) < 1e-10
Exemplo n.º 2
0
    def test_multi_scalar(self):
        """
        Tests functions with multiple scalar output
        """

        def f1(x):
            # two scalar input
            return x**3, np.exp(3*x)

        df = jacobian(f1)(0.5)
        self.assertAlmostEqual(3*0.5**2, df[0])
        self.assertAlmostEqual(3*np.exp(3*0.5), df[1])

        def f2(params):
            # one list, one numpy array input
            x,y = params[0]
            A = params[1]
            return np.sum(A**2) + np.cos(x) + np.exp(0.5*y)

        df = jacobian(f2)
        A = np.array([[1.0, 2.0],[3.0, 4.0]])
        params = [[0.5, np.pi], A]
        diff = df(params)
        self.assertAlmostEqual(diff[0][0], -np.sin(0.5))
        self.assertAlmostEqual(diff[0][1], 0.5*np.exp(0.5*np.pi))
        self.assertTrue(np.linalg.norm(2*A - diff[1]) < 1e-10)
Exemplo n.º 3
0
    def test_linear_system(self):
        """
        Tests taking the derivative across a linear system solve
        """

        def linsolve(params):
            A, B = params
            return np.linalg.solve(A, B)


        B = np.array([1.0, 3.0])
        A = np.array([[5.0, 2.0],[1.0, 3.0]])
        df = jacobian(linsolve)

        diff = df([A, B])

        Ainv = np.linalg.inv(A)
        x = np.linalg.solve(A, B)

        #df_dB
        assert np.linalg.norm(diff[0][1] - Ainv[0]) < 1e-10
        assert np.linalg.norm(diff[1][1] - Ainv[1]) < 1e-10

        #df_fA
        dr_da = np.zeros((2,4))
        dr_da[0, 0:2] = x
        dr_da[1, 2:] = x

        df_fa = np.linalg.solve(A, -dr_da)
        assert np.linalg.norm(df_fa[0] - diff[0][0].flatten()) < 1e-10
        assert np.linalg.norm(df_fa[1] - diff[1][0].flatten()) < 1e-10
Exemplo n.º 4
0
    def test_scalar(self):
        """
        Test simple scalar functions - basically a passthrough to autograd.grad
        """

        def f1(x):
            return 2.0*x

        self.assertAlmostEqual(jacobian(f1)(5.0), 2.0)

        def f2(params):
            return np.exp(params[0]) + params[1][0]**2 + np.cos(params[1][1])

        params = [1.0, [2.0, np.pi]]
        df = jacobian(f2)(params)
        self.assertAlmostEqual(df[0], np.exp(1.0))
        self.assertAlmostEqual(df[1][0], 4.0)
        self.assertAlmostEqual(df[1][1], 0.0)
Exemplo n.º 5
0
    def test_mixed1(self):
        """
        Tests functions with mix of scalars and array outputs
        """
        
        def f1(x):

            return x, 0.5*x**3, np.array([2*x, x**2])

        x = 0.5
        diff = jacobian(f1)(x)
        
        self.assertAlmostEqual(diff[0], 1.0)
        self.assertAlmostEqual(diff[1], 3*0.5*x**2)
        self.assertAlmostEqual(diff[2][0], 2.0)
        self.assertAlmostEqual(diff[2][1], 2.0*x)
Exemplo n.º 6
0
    def test_array2(self):
        """
        Tests functions with single numpy 2d array output
        """

        def f1(x):
            # single scalar input
            return np.array([[x, 2*x],[x**2, np.exp(0.5*x)]])

        x = 0.75
        d = np.array([[1.0, 2.0],[2*x, 0.5*np.exp(0.5*x)]])
        df = jacobian(f1)(x)
        assert np.linalg.norm(d - df) < 1e-10


        def f2(params):
            # mixed inputs
            x = params[0] # float
            A = params[1] # 2d array
            B = params[2] # 1d array

            return np.exp(B**2)/x * A