def test_parent_dof_transitive_behavior(self):
     iden1 = Identity()
     iden2 = Identity()
     lsp = LeastSquaresProblem.from_sigma([3, -4], [2, 5], opts_in=[iden1, iden2])
     iden1.x = [10]
     self.assertAlmostEqual(np.abs(lsp.residuals()[0]), 3.5)
     self.assertAlmostEqual(np.abs(lsp.residuals()[1]), 0.8)
    def test_local_x(self):
        # Check with leaf type Optimizable objects
        adder = Adder(n=3, x0=[1, 2, 3], dof_names=['x', 'y', 'z'])
        iden = Identity(x=10, dof_fixed=True)
        adder_x = adder.local_x
        iden_x = iden.local_x
        self.assertAlmostEqual(adder_x[0], 1)
        self.assertAlmostEqual(adder_x[1], 2)
        self.assertAlmostEqual(adder_x[2], 3)
        self.assertTrue(len(iden_x) == 0)

        adder.local_x = [4, 5, 6]
        self.assertAlmostEqual(adder._dofs.loc['x', '_x'], 4)
        self.assertAlmostEqual(adder._dofs.loc['y', '_x'], 5)
        self.assertAlmostEqual(adder._dofs.loc['z', '_x'], 6)
        with self.assertRaises(ValueError):
            iden.local_x = np.array([
                11,
            ], dtype=float)
        self.assertAlmostEqual(iden.full_x[0], 10)

        # Check with Optimizable objects containing parents
        adder2 = Adder(3)
        iden2 = Identity(x=10)
        test_obj1 = OptClassWithParents(10, opts_in=[iden2, adder2])
        test_obj1.local_x = np.array([25])
        self.assertAlmostEqual(test_obj1._dofs.loc['val', '_x'], 25)

        adder3 = Adder(3)
        test_obj2 = OptClassWithParents(10, opts_in=[iden, adder3])

        test_obj2.local_x = np.array([25])
        self.assertAlmostEqual(test_obj2._dofs.loc['val', '_x'], 25)
    def test_dof_size(self):
        # Define Null class
        class EmptyOptimizable(Optimizable):
            def f(self):
                return 0

            return_fn_map = {'f': f}

        opt = EmptyOptimizable()
        self.assertEqual(opt.dof_size, 0)

        self.assertEqual(self.iden.dof_size, 1)
        self.assertEqual(self.adder.dof_size, 3)
        self.assertEqual(self.rosen.dof_size, 2)

        iden2 = Identity(x=10, dof_fixed=True)
        self.assertEqual(iden2.dof_size, 0)

        # Use Optimizable object with parents
        test_obj = OptClassWithParents(10)
        self.assertEqual(test_obj.dof_size, 6)

        test_obj1 = OptClassWithParents(
            10,
            opts_in=[Identity(x=10, dof_fixed=True),
                     Adder(n=3, x0=[1, 2, 3])])
        self.assertEqual(test_obj1.dof_size, 4)
    def test_full_dof_size(self):

        # Define Null class
        class EmptyOptimizable(Optimizable):
            def f(self):
                return 0

        opt = EmptyOptimizable()
        self.assertEqual(opt.full_dof_size, 0)

        self.assertEqual(self.iden.full_dof_size, 1)
        self.assertEqual(self.adder.full_dof_size, 3)
        self.assertEqual(self.rosen.full_dof_size, 2)

        iden2 = Identity(x=10, dof_fixed=True)
        self.assertEqual(iden2.full_dof_size, 1)

        # Use Optimizable object with parents
        test_obj = OptClassWithParents(10)
        self.assertEqual(test_obj.full_dof_size, 6)

        test_obj1 = OptClassWithParents(
            10, opts_in=[Identity(x=10, dof_fixed=True),
                         Adder(3)])
        self.assertEqual(test_obj1.full_dof_size, 5)
    def test_unfix_all(self):
        # Test with leaf nodes
        adder = Adder(n=3,
                      x0=[1, 2, 3],
                      dof_names=['x', 'y', 'z'],
                      dof_fixed=[True, False, False])
        iden = Identity(x=10, dof_fixed=True)
        adder_x = adder.x
        iden_x = iden.x
        self.assertEqual(len(adder_x), 2)
        self.assertEqual(adder.dof_size, 2)
        self.assertAlmostEqual(adder_x[0], 2)
        self.assertAlmostEqual(adder_x[1], 3)
        self.assertEqual(len(iden_x), 0)

        with self.assertRaises(ValueError):
            iden.x = [10]
        with self.assertRaises(ValueError):
            adder.x = [4, 5, 6]

        iden.unfix_all()
        adder.unfix_all()
        iden.x = [10]
        adder.x = [4, 5, 6]
        self.assertEqual(iden.dof_size, 1)
        self.assertEqual(adder.dof_size, 3)
        self.assertAlmostEqual(adder._dofs.loc['x', '_x'], 4)
        self.assertAlmostEqual(adder._dofs.loc['y', '_x'], 5)
        self.assertAlmostEqual(adder._dofs.loc['z', '_x'], 6)
        self.assertAlmostEqual(iden._dofs.loc['x0', '_x'], 10)

        # Check with Optimizable objects containing parents
        adder = Adder(n=3,
                      x0=[1, 2, 3],
                      dof_names=['x', 'y', 'z'],
                      dof_fixed=[True, False, False])
        iden = Identity(x=10, dof_fixed=True)
        test_obj = OptClassWithParents(10, opts_in=[iden, adder])

        with self.assertRaises(ValueError):
            test_obj.x = np.array([20, 4, 5, 6, 25])

        adder.unfix_all()
        test_obj.x = np.array([4, 5, 6, 25])
        self.assertAlmostEqual(test_obj._dofs.loc['val', '_x'], 25)
        self.assertAlmostEqual(adder._dofs.loc['x', '_x'], 4)
        self.assertAlmostEqual(adder._dofs.loc['y', '_x'], 5)
        self.assertAlmostEqual(adder._dofs.loc['z', '_x'], 6)

        iden.unfix_all()
        test_obj.x = np.array([1, 1, 2, 3, 10])

        self.assertAlmostEqual(iden._dofs.loc['x0', '_x'], 1)
        self.assertAlmostEqual(adder._dofs.loc['x', '_x'], 1)
        self.assertAlmostEqual(adder._dofs.loc['y', '_x'], 2)
        self.assertAlmostEqual(adder._dofs.loc['z', '_x'], 3)
        self.assertAlmostEqual(test_obj._dofs.loc['val', '_x'], 10)
 def test_least_squares_combination(self):
     iden1 = Identity()
     iden2 = Identity()
     term1 = LeastSquaresProblem.from_sigma(3, 2, opts_in=[iden1])
     term2 = LeastSquaresProblem.from_sigma(-4, 5, opts_in=[iden2])
     lsp = term1 + term2
     iden1.x = [10]
     self.assertAlmostEqual(np.abs(lsp.residuals()[0]), 3.5)
     self.assertAlmostEqual(np.abs(lsp.residuals()[1]), 0.8)
    def test_get(self):
        adder = Adder(n=3,
                      x0=[1, 2, 3],
                      dof_names=['x', 'y', 'z'],
                      dof_fixed=[True, False, False])
        iden = Identity(x=10, dof_fixed=True)

        self.assertAlmostEqual(adder.get(0), 1.)
        self.assertAlmostEqual(adder.get('y'), 2.)
        self.assertAlmostEqual(iden.get('x0'), 10.)
 def test_is_free(self):
     iden = Identity(x=10, dof_fixed=True)
     adder = Adder(n=3,
                   x0=[1, 2, 3],
                   dof_names=['x', 'y', 'z'],
                   dof_fixed=[True, False, False])
     self.assertFalse(adder.is_free(0))
     self.assertFalse(adder.is_free('x'))
     self.assertTrue(adder.is_free(1))
     self.assertTrue(adder.is_free('y'))
     self.assertFalse(iden.is_free(0))
     self.assertFalse(iden.is_free('x0'))
    def test_set(self):
        adder = Adder(n=3,
                      x0=[1, 2, 3],
                      dof_names=['x', 'y', 'z'],
                      dof_fixed=[True, False, False])
        iden = Identity(x=10, dof_fixed=True)

        adder.set(0, 2)
        adder.set('y', 20)
        iden.set('x0', 20)
        self.assertAlmostEqual(adder.full_x[0], 2)
        self.assertAlmostEqual(adder.full_x[1], 20)
        self.assertAlmostEqual(iden.full_x[0], 20)
    def test_get_ancestors(self):
        iden = Identity(x=10, dof_fixed=True)
        adder = Adder(n=3, x0=[1, 2, 3])
        self.assertEqual(len(iden._get_ancestors()), 0)
        self.assertEqual(len(adder._get_ancestors()), 0)

        test_obj = OptClassWithParents(10, opts_in=[iden, adder])
        ancestors = test_obj._get_ancestors()
        self.assertEqual(len(ancestors), 2)
        self.assertIn(iden, ancestors)
        self.assertIn(adder, ancestors)

        test_obj2 = OptClassWith2LevelParents(10, 20)
        ancestors = test_obj2._get_ancestors()
        self.assertEqual(len(ancestors), 4)
 def test_multiple_funcs_single_input(self):
     iden1 = Identity(x=10)
     iden2 = Identity()
     # Objective function
     # f(x,y) = ((x - 3) / 2) ** 2 + ((y + 4) / 5) ** 2
     lsp = LeastSquaresProblem.from_sigma([3, -4], [2, 5], opts_in=[iden1, iden2])
     self.assertAlmostEqual(np.abs(lsp.residuals()[0]), 3.5)
     self.assertAlmostEqual(np.abs(lsp.residuals()[1]), 0.8)
     lsp.x = [5, -7]
     self.assertAlmostEqual(np.abs(lsp.residuals()[0]), 1.0)
     self.assertAlmostEqual(np.abs(lsp.residuals()[1]), 0.6)
     self.assertAlmostEqual(np.abs(lsp.residuals([10, 0])[0]), 3.5)
     self.assertAlmostEqual(np.abs(lsp.residuals([10, 0])[1]), 0.8)
     self.assertAlmostEqual(np.abs(lsp.residuals([5, -7])[0]), 1.0)
     self.assertAlmostEqual(np.abs(lsp.residuals([5, -7])[1]), 0.6)
 def test_name(self):
     self.assertTrue('Identity' in self.iden.name)
     self.assertTrue('Adder' in self.adder.name)
     self.assertTrue('Rosenbrock' in self.rosen.name)
     self.assertNotEqual(self.iden.name, Identity().name)
     self.assertNotEqual(self.adder.name, Adder().name)
     self.assertNotEqual(self.rosen.name, Rosenbrock().name)
 def test_solve_quadratic_fixed(self):
     """
     Same as test_solve_quadratic, except with different weights and x
     and z are fixed, so only y is optimized.
     """
     for solver in solvers:
         iden1 = Identity(4, dof_name='x1', dof_fixed=True)
         iden2 = Identity(5, dof_name='x2')
         iden3 = Identity(6, dof_name='x3', dof_fixed=True)
         term1 = (iden1.f, 1, 1)
         term2 = (iden2.f, 2, 1 / 4.)
         term3 = (iden3.f, 3, 1 / 9.)
         prob = LeastSquaresProblem.from_tuples([term1, term2, term3])
         solver(prob)
         self.assertAlmostEqual(prob.objective(), 10)
         self.assertTrue(np.allclose(iden1.x, [4]))
         self.assertTrue(np.allclose(iden2.x, [2]))
         self.assertTrue(np.allclose(iden3.x, [6]))
 def test_solve_quadratic(self):
     """
     Minimize f(x,y,z) = 1 * (x - 1) ^ 2 + 2 * (y - 2) ^ 2 + 3 * (z - 3) ^ 2.
     The optimum is at (x,y,z)=(1,2,3), and f=0 at this point.
     """
     for solver in solvers:
         iden1 = Identity()
         iden2 = Identity()
         iden3 = Identity()
         term1 = (iden1.f, 1, 1)
         term2 = (iden2.f, 2, 2)
         term3 = (iden3.f, 3, 3)
         prob = LeastSquaresProblem.from_tuples([term1, term2, term3])
         solver(prob)
         self.assertAlmostEqual(prob.objective(), 0)
         self.assertTrue(np.allclose(iden1.x, [1]))
         self.assertTrue(np.allclose(iden2.x, [2]))
         self.assertTrue(np.allclose(iden3.x, [3]))
    def test_single_value_opt_in(self):
        iden = Identity()
        lst = LeastSquaresProblem.from_sigma(3, 0.1, opts_in=iden)

        iden.x = [17]
        correct_value = ((17 - 3) / 0.1)  # ** 2
        self.assertAlmostEqual(np.abs(lst.residuals()[0]),
                               correct_value,
                               places=11)

        iden.x = [0]
        term1 = LeastSquaresProblem.from_sigma(3, 2, opts_in=iden)
        self.assertAlmostEqual(np.abs(term1.residuals()[0]), 1.5)

        term1.x = [10]
        self.assertAlmostEqual(np.abs(term1.residuals()[0]), 3.5)
        self.assertAlmostEqual(np.abs(term1.residuals(x=[0])), 1.5)
        self.assertAlmostEqual(np.abs(term1.residuals(x=[5])), 1)
    def test_exceptions(self):
        """
        Test that exceptions are thrown when invalid inputs are
        provided.
        """
        iden = Identity()

        # sigma cannot be zero
        with self.assertRaises(ValueError):
            lst = LeastSquaresProblem.from_sigma(3, 0, opts_in=iden)

        # Weight cannot be negative
        with self.assertRaises(ValueError):
            lst = LeastSquaresProblem(3, -1.0, opts_in=iden)
    def test_full_x(self):
        # Check with leaf type Optimizable objects
        adder = Adder(n=3, x0=[1, 2, 3], dof_names=['x', 'y', 'z'])
        iden = Identity(x=10, dof_fixed=True)
        adder_full_x = adder.full_x
        self.assertAlmostEqual(adder_full_x[0], 1)
        self.assertAlmostEqual(adder_full_x[1], 2)
        self.assertAlmostEqual(adder_full_x[2], 3)
        self.assertEqual(len(iden.full_x), 1)
        self.assertAlmostEqual(iden.full_x[0], 10)

        # Check with Optimizable objects containing parents
        test_obj1 = OptClassWithParents(20, opts_in=[iden, adder])
        full_x = test_obj1.full_x
        self.assertTrue(np.allclose(full_x, np.array([10, 1, 2, 3, 20])))

        test_obj1.x = np.array([4, 5, 6, 25])
        full_x = test_obj1.full_x
        self.assertTrue(np.allclose(full_x, np.array([10, 4, 5, 6, 25])))
Beispiel #18
0
class DOFsTests(unittest.TestCase):

    def setUp(self):
        self.identity_dofs = Identity(x=1, dof_name='x')._dofs
        self.adder_dofs = Adder(3, x0=[2, 3, 4], dof_names=["x", "y", "z"])._dofs
        self.rosenbrock_dofs = Rosenbrock()._dofs

    def tearDown(self) -> None:
        self.identity_dofs = None
        self.adder_dofs = None
        self.rosenbrock_dofs = None

    def test_init(self):
        # Create an empty dof and check all the methods
        empty_dof = DOFs()
        empty_dof.fix_all()
        empty_dof.unfix_all()
        self.assertFalse(empty_dof.any_free())
        self.assertFalse(empty_dof.any_fixed())
        self.assertTrue(empty_dof.all_free())
        self.assertTrue(empty_dof.all_fixed())
        empty_dof.x = []  # This statement working is what is desired
        self.assertTrue(len(empty_dof) == 0)
        self.assertTrue(empty_dof.reduced_len == 0)

    def test_fix(self):
        # TODO: This test uses too many methods of DOFs.
        self.adder_dofs.fix("x")
        self.assertTrue(self.adder_dofs.any_fixed())
        self.assertFalse(self.adder_dofs.all_free())
        self.assertEqual(self.adder_dofs.reduced_len, 2)
        with self.assertRaises(ValueError):
            self.adder_dofs.x = np.array([4, 5, 6])

        self.adder_dofs.fix("x")
        self.assertEqual(self.adder_dofs.reduced_len, 2)

        self.adder_dofs.fix("y")
        self.assertEqual(self.adder_dofs.reduced_len, 1)

    def test_fix_all(self):
        self.identity_dofs.fix_all()
        self.adder_dofs.fix_all()
        self.rosenbrock_dofs.fix_all()

        self.assertEqual(self.identity_dofs.reduced_len, 0)
        self.assertEqual(self.adder_dofs.reduced_len, 0)
        self.assertEqual(self.rosenbrock_dofs.reduced_len, 0)

    def test_unfix(self):
        self.adder_dofs.fix("x")
        self.adder_dofs.fix("y")
        self.rosenbrock_dofs.fix("x")
        self.assertEqual(self.adder_dofs.reduced_len, 1)
        self.assertEqual(self.rosenbrock_dofs.reduced_len, 1)

        self.adder_dofs.unfix("x")
        self.assertEqual(self.adder_dofs.reduced_len, 2)
        self.adder_dofs.unfix("x")
        self.assertEqual(self.adder_dofs.reduced_len, 2)
        self.rosenbrock_dofs.unfix("y")
        self.assertEqual(self.rosenbrock_dofs.reduced_len, 1)

    def test_unfix_all(self):
        self.adder_dofs.fix("x")
        self.rosenbrock_dofs.fix("x")

        self.adder_dofs.unfix_all()
        self.rosenbrock_dofs.unfix_all()

        self.assertEqual(self.identity_dofs.reduced_len, 1)
        self.assertEqual(self.adder_dofs.reduced_len, 3)
        self.assertEqual(self.rosenbrock_dofs.reduced_len, 2)

    def test_any_free(self):
        fixed_dofs = DOFs(x=np.array([1, 2, 3]),
                          names=np.array(['x', 'y', 'z']),
                          free=np.array([False, False, False]))
        self.assertFalse(fixed_dofs.any_free())
        one_fixed_dofs = DOFs(x=np.array([1, 2, 3]),
                              names=np.array(['x', 'y', 'z']),
                              free=np.array([True, True, False]))
        self.assertTrue(one_fixed_dofs.any_free())

    def test_any_fixed(self):
        free_dofs = DOFs(x=np.array([1, 2, 3]),
                         names=np.array(['x', 'y', 'z']),
                         free=np.array([True, True, True]))
        self.assertFalse(free_dofs.any_fixed())
        one_fixed_dofs = DOFs(x=np.array([1, 2, 3]),
                              names=np.array(['x', 'y', 'z']),
                              free=np.array([True, True, False]))
        self.assertTrue(one_fixed_dofs.any_fixed())

    def test_all_free(self):
        free_dofs = DOFs(x=np.array([1, 2, 3]),
                         names=np.array(['x', 'y', 'z']),
                         free=np.array([True, True, True]))
        self.assertTrue(free_dofs.all_free())
        one_fixed_dofs = DOFs(x=np.array([1, 2, 3]),
                              names=np.array(['x', 'y', 'z']),
                              free=np.array([True, True, False]))
        self.assertFalse(one_fixed_dofs.all_free())

    def test_all_fixed(self):
        fixed_dofs = DOFs(x=np.array([1, 2, 3]),
                          names=np.array(['x', 'y', 'z']),
                          free=np.array([False, False, False]))
        self.assertTrue(fixed_dofs.all_fixed())
        one_fixed_dofs = DOFs(x=np.array([1, 2, 3]),
                              names=np.array(['x', 'y', 'z']),
                              free=np.array([True, True, False]))
        self.assertFalse(one_fixed_dofs.all_fixed())

    def test_x(self):
        # Test the getter
        fixed_dofs = DOFs(x=np.array([1, 2, 3]),
                          names=np.array(['x', 'y', 'z']),
                          free=np.array([False, False, False]))
        free_dofs = DOFs(x=np.array([1, 2, 3]),
                         names=np.array(['x', 'y', 'z']),
                         free=np.array([True, True, True]))
        one_fixed_dofs = DOFs(x=np.array([1, 2, 3]),
                              names=np.array(['x', 'y', 'z']),
                              free=np.array([True, True, False]))
        self.assertTrue(np.allclose(fixed_dofs.x, np.array([])))
        self.assertTrue(np.allclose(free_dofs.x, np.array([1, 2, 3])))
        self.assertTrue(np.allclose(one_fixed_dofs.x, np.array([1, 2])))

        # Test the setter

        # Use full array size
        with self.assertRaises(ValueError):
            fixed_dofs.x = np.array([4, 5, 6])
        with self.assertRaises(ValueError):
            one_fixed_dofs.x = np.array([4, 5, 6])

        free_dofs.x = np.array([4, 5, 6])
        self.assertTrue(np.allclose(free_dofs.x, np.array([4, 5, 6])))
        one_fixed_dofs.x = np.array([4, 5])
        self.assertTrue(np.allclose(one_fixed_dofs.full_x, np.array([4, 5, 3])))

    def test_full_x(self):
        fixed_dofs = DOFs(x=np.array([1, 2, 3]),
                          names=np.array(['x', 'y', 'z']),
                          free=np.array([False, False, False]))
        free_dofs = DOFs(x=np.array([1, 2, 3]),
                         names=np.array(['x', 'y', 'z']),
                         free=np.array([True, True, True]))
        one_fixed_dofs = DOFs(x=np.array([1, 2, 3]),
                              names=np.array(['x', 'y', 'z']),
                              free=np.array([True, True, False]))
        output = np.array([1, 2, 3])
        self.assertTrue(np.allclose(fixed_dofs.full_x, output))
        self.assertTrue(np.allclose(free_dofs.full_x, output))
        self.assertTrue(np.allclose(one_fixed_dofs.full_x, output))

    def test_lower_bounds(self):
        dofs = DOFs(x=np.array([1, 2, 3]),
                    names=np.array(['x', 'y', 'z']),
                    free=np.array([True, True, False]))
        self.assertTrue(np.allclose(dofs.lower_bounds,
                                    np.array([np.NINF, np.NINF])))

        with self.assertRaises(ValueError):
            dofs.lower_bounds = np.array([-1000.0, -1001.0, -1002.0])
        with self.assertRaises(ValueError):
            dofs.lower_bounds = np.array([-1000.0])
        dofs.lower_bounds = np.array([-1000.0, -1001.0])
        self.assertTrue(np.allclose(dofs.lower_bounds,
                                    np.array([-1000.0, -1001.0])))

        dofs.unfix_all()
        self.assertTrue(np.allclose(dofs.lower_bounds,
                                    np.array([-1000.0, -1001.0, np.NINF])))

        dofs.lower_bounds = np.array([-1000.0, -1001.0, -1002.])
        self.assertTrue(np.allclose(dofs.lower_bounds,
                                    np.array([-1000.0, -1001.0, -1002.0])))

        with self.assertRaises(ValueError):
            dofs.lower_bounds = np.array([-1000.0])
        with self.assertRaises(ValueError):
            dofs.lower_bounds = np.array([-1000.0, -1001.0])

    def test_upper_bounds(self):
        dofs = DOFs(x=np.array([1, 2, 3]),
                    names=np.array(['x', 'y', 'z']),
                    free=np.array([True, True, False]))
        self.assertTrue(np.allclose(dofs.upper_bounds,
                                    np.array([np.inf, np.inf])))

        with self.assertRaises(ValueError):
            dofs.upper_bounds = np.array([1000.0, 1001.0, 1002.0])
        with self.assertRaises(ValueError):
            dofs.upper_bounds = np.array([1000.0])
        dofs.upper_bounds = np.array([1000.0, 1001.0])
        self.assertTrue(np.allclose(dofs.upper_bounds,
                                    np.array([1000.0, 1001.0])))

        dofs.unfix_all()
        self.assertTrue(np.allclose(dofs.upper_bounds,
                                    np.array([1000.0, 1001.0, np.inf])))

        dofs.upper_bounds = np.array([1000.0, 1001.0, 1002.])
        self.assertTrue(np.allclose(dofs.upper_bounds,
                                    np.array([1000.0, 1001.0, 1002.0])))

        with self.assertRaises(ValueError):
            dofs.upper_bounds = np.array([1000.0])
        with self.assertRaises(ValueError):
            dofs.upper_bounds = np.array([1000.0, 1001.0])

    def test_bounds(self):
        dofs = DOFs(x=np.array([1, 2, 3]),
                    names=np.array(['x', 'y', 'z']),
                    free=np.array([True, True, False]),
                    lower_bounds=np.array([-100.0, -101.0, -102.0]),
                    upper_bounds=np.array([100.0, 101.0, 102.0]))
        bounds = dofs.bounds
        self.assertTrue(np.allclose(bounds[0],
                                    np.array([-100.0, -101.0]))
                        and np.allclose(bounds[1],
                                        np.array([100.0, 101.0])))

    def test_update_upper_bound(self):
        dofs = DOFs(x=np.array([1, 2, 3]),
                    names=np.array(['x', 'y', 'z']),
                    free=np.array([True, True, False]),
                    lower_bounds=np.array([-100.0, -101.0, -102.0]),
                    upper_bounds=np.array([100.0, 101.0, 102.0]))
        dofs.update_upper_bound("x", 200)
        self.assertTrue(np.allclose(dofs.upper_bounds,
                                    np.array([200.0, 101.0])))

        # Test with integer keys

    def test_update_lower_bound(self):
        dofs = DOFs(x=np.array([1, 2, 3]),
                    names=np.array(['x', 'y', 'z']),
                    free=np.array([True, True, False]),
                    lower_bounds=np.array([-100.0, -101.0, -102.0]),
                    upper_bounds=np.array([100.0, 101.0, 102.0]))
        dofs.update_lower_bound("x", -200)
        self.assertTrue(np.allclose(dofs.lower_bounds,
                                    np.array([-200.0, -101.0])))
        # Test with integer keys

    def test_update_bounds(self):
        pass
Beispiel #19
0
 def setUp(self):
     self.identity_dofs = Identity(x=1, dof_name='x')._dofs
     self.adder_dofs = Adder(3, x0=[2, 3, 4], dof_names=["x", "y", "z"])._dofs
     self.rosenbrock_dofs = Rosenbrock()._dofs
class OptimizableTests(unittest.TestCase):
    def setUp(self) -> None:
        self.iden = Identity(x=10)
        self.adder = Adder(n=3, dof_names=['x', 'y', 'z'])
        self.rosen = Rosenbrock()

    def tearDown(self) -> None:
        self.iden = None
        self.adder = None
        self.rosen = None

    def test_name(self):
        self.assertTrue('Identity' in self.iden.name)
        self.assertTrue('Adder' in self.adder.name)
        self.assertTrue('Rosenbrock' in self.rosen.name)
        self.assertNotEqual(self.iden.name, Identity().name)
        self.assertNotEqual(self.adder.name, Adder().name)
        self.assertNotEqual(self.rosen.name, Rosenbrock().name)

    def test_hash(self):
        hash1 = hash(self.adder)
        hash2 = hash(Adder())
        self.assertNotEqual(hash1, hash2)

    def test_add_parent(self):
        opt1 = Adder(3, x0=[2, 3, 4])
        opt2 = Adder(2, x0=[1, 2])
        opt_with_parents = OptClassWithParents(10, opts_in=[opt1])

        with self.assertRaises(IndexError):  # Missing second parent
            opt_with_parents()

        opt_with_parents.add_parent(1, opt2)
        self.assertAlmostEqual(opt_with_parents(), 28.0 / 13.0)

    def test_append_parent(self):
        opt1 = Adder(3, x0=[2, 3, 4])
        opt2 = Adder(2, x0=[1, 2])
        opt_with_parents = OptClassWithParents(10, opts_in=[opt1])

        with self.assertRaises(IndexError):  # Missing second parent
            opt_with_parents()

        opt_with_parents.append_parent(opt2)
        self.assertAlmostEqual(opt_with_parents(), 28.0 / 13.0)

    def test_pop_parent(self):
        opt1 = Adder(3, x0=[2, 3, 4])
        opt2 = Adder(2, x0=[1, 2])
        opt_with_parents = OptClassWithParents(10, opts_in=[opt1, opt2])

        self.assertEqual(len(opt_with_parents.parents), 2)
        self.assertAlmostEqual(opt_with_parents(), 28.0 / 13.0)
        opt_with_parents.pop_parent()
        self.assertEqual(len(opt_with_parents.parents), 1)
        with self.assertRaises(IndexError):  # Missing second parent
            opt_with_parents()

    def test_remove_parent(self):
        opt1 = Adder(3, x0=[2, 3, 4])
        opt2 = Adder(2, x0=[1, 2])
        opt_with_parents = OptClassWithParents(10, opts_in=[opt1, opt2])

        self.assertEqual(len(opt_with_parents.parents), 2)
        self.assertAlmostEqual(opt_with_parents(), 28.0 / 13.0)
        opt_with_parents.remove_parent(opt1)
        self.assertEqual(len(opt_with_parents.parents), 1)
        with self.assertRaises(IndexError):  # Missing second parent
            opt_with_parents()

    def test_dof_size(self):
        # Define Null class
        class EmptyOptimizable(Optimizable):
            def f(self):
                return 0

            return_fn_map = {'f': f}

        opt = EmptyOptimizable()
        self.assertEqual(opt.dof_size, 0)

        self.assertEqual(self.iden.dof_size, 1)
        self.assertEqual(self.adder.dof_size, 3)
        self.assertEqual(self.rosen.dof_size, 2)

        iden2 = Identity(x=10, dof_fixed=True)
        self.assertEqual(iden2.dof_size, 0)

        # Use Optimizable object with parents
        test_obj = OptClassWithParents(10)
        self.assertEqual(test_obj.dof_size, 6)

        test_obj1 = OptClassWithParents(
            10,
            opts_in=[Identity(x=10, dof_fixed=True),
                     Adder(n=3, x0=[1, 2, 3])])
        self.assertEqual(test_obj1.dof_size, 4)

    def test_full_dof_size(self):

        # Define Null class
        class EmptyOptimizable(Optimizable):
            def f(self):
                return 0

        opt = EmptyOptimizable()
        self.assertEqual(opt.full_dof_size, 0)

        self.assertEqual(self.iden.full_dof_size, 1)
        self.assertEqual(self.adder.full_dof_size, 3)
        self.assertEqual(self.rosen.full_dof_size, 2)

        iden2 = Identity(x=10, dof_fixed=True)
        self.assertEqual(iden2.full_dof_size, 1)

        # Use Optimizable object with parents
        test_obj = OptClassWithParents(10)
        self.assertEqual(test_obj.full_dof_size, 6)

        test_obj1 = OptClassWithParents(
            10, opts_in=[Identity(x=10, dof_fixed=True),
                         Adder(3)])
        self.assertEqual(test_obj1.full_dof_size, 5)

    def test_local_dof_size(self):
        # Define Null class
        class EmptyOptimizable(Optimizable):
            def f(self):
                return 0

        opt = EmptyOptimizable()
        self.assertEqual(opt.local_dof_size, 0)

        self.assertEqual(self.iden.local_dof_size, 1)
        self.assertEqual(self.adder.local_dof_size, 3)
        self.assertEqual(self.rosen.local_dof_size, 2)

        iden2 = Identity(x=10, dof_fixed=True)
        self.assertEqual(iden2.local_dof_size, 0)

        # Use Optimizable object with parents
        test_obj = OptClassWithParents(10)
        self.assertEqual(test_obj.local_dof_size, 1)

        test_obj1 = OptClassWithParents(
            10, opts_in=[Identity(x=10, dof_fixed=True),
                         Adder(3)])
        self.assertEqual(test_obj1.local_dof_size, 1)

    def test_local_full_dof_size(self):
        # Define Null class
        class EmptyOptimizable(Optimizable):
            def f(self):
                return 0

        opt = EmptyOptimizable()
        self.assertEqual(opt.local_full_dof_size, 0)

        self.assertEqual(self.iden.local_full_dof_size, 1)
        self.assertEqual(self.adder.local_full_dof_size, 3)
        self.assertEqual(self.rosen.local_full_dof_size, 2)

        iden2 = Identity(x=10, dof_fixed=True)
        self.assertEqual(iden2.local_full_dof_size, 1)

        # Use Optimizable object with parents
        test_obj = OptClassWithParents(10)
        self.assertEqual(test_obj.local_full_dof_size, 1)

        test_obj1 = OptClassWithParents(
            10, opts_in=[Identity(x=10, dof_fixed=True),
                         Adder(3)])
        self.assertEqual(test_obj1.local_full_dof_size, 1)

    def test_x(self):
        # Check with leaf type Optimizable objects
        adder = Adder(n=3, x0=[1, 2, 3], dof_names=['x', 'y', 'z'])
        iden = Identity(x=10, dof_fixed=True)
        adder_dofs = adder.x
        iden_dofs = iden.x
        self.assertAlmostEqual(adder_dofs[0], 1)
        self.assertAlmostEqual(adder_dofs[1], 2)
        self.assertAlmostEqual(adder_dofs[2], 3)
        self.assertEqual(len(iden_dofs), 0)

        adder.x = [4, 5, 6]
        self.assertAlmostEqual(adder._dofs.loc['x', '_x'], 4)
        self.assertAlmostEqual(adder._dofs.loc['y', '_x'], 5)
        self.assertAlmostEqual(adder._dofs.loc['z', '_x'], 6)
        with self.assertRaises(ValueError):
            iden.x = np.array([
                11,
            ], dtype=float)
        self.assertAlmostEqual(iden.full_x[0], 10)

        # Check with Optimizable objects containing parents
        adder2 = Adder(3)
        iden2 = Identity(x=10)
        test_obj1 = OptClassWithParents(10, opts_in=[iden2, adder2])
        with self.assertRaises(ValueError):
            test_obj1.x = np.array([20])

        test_obj1.x = np.array([20, 4, 5, 6, 25])
        self.assertAlmostEqual(test_obj1._dofs.loc['val', '_x'], 25)
        self.assertAlmostEqual(iden2._dofs.loc['x0', '_x'], 20)
        self.assertAlmostEqual(adder2._dofs.loc['x0', '_x'], 4)
        self.assertAlmostEqual(adder2._dofs.loc['x1', '_x'], 5)
        self.assertAlmostEqual(adder2._dofs.loc['x2', '_x'], 6)

        adder3 = Adder(3)
        test_obj2 = OptClassWithParents(10, opts_in=[iden, adder3])
        with self.assertRaises(ValueError):
            test_obj2.x = np.array([20, 4, 5, 6, 25])

        test_obj2.x = np.array([4, 5, 6, 25])
        self.assertAlmostEqual(iden._dofs.loc['x0', '_x'], 10)
        self.assertAlmostEqual(adder3._dofs.loc['x0', '_x'], 4)
        self.assertAlmostEqual(adder3._dofs.loc['x1', '_x'], 5)
        self.assertAlmostEqual(adder3._dofs.loc['x2', '_x'], 6)
        self.assertAlmostEqual(test_obj2._dofs.loc['val', '_x'], 25)

    def test_local_x(self):
        # Check with leaf type Optimizable objects
        adder = Adder(n=3, x0=[1, 2, 3], dof_names=['x', 'y', 'z'])
        iden = Identity(x=10, dof_fixed=True)
        adder_x = adder.local_x
        iden_x = iden.local_x
        self.assertAlmostEqual(adder_x[0], 1)
        self.assertAlmostEqual(adder_x[1], 2)
        self.assertAlmostEqual(adder_x[2], 3)
        self.assertTrue(len(iden_x) == 0)

        adder.local_x = [4, 5, 6]
        self.assertAlmostEqual(adder._dofs.loc['x', '_x'], 4)
        self.assertAlmostEqual(adder._dofs.loc['y', '_x'], 5)
        self.assertAlmostEqual(adder._dofs.loc['z', '_x'], 6)
        with self.assertRaises(ValueError):
            iden.local_x = np.array([
                11,
            ], dtype=float)
        self.assertAlmostEqual(iden.full_x[0], 10)

        # Check with Optimizable objects containing parents
        adder2 = Adder(3)
        iden2 = Identity(x=10)
        test_obj1 = OptClassWithParents(10, opts_in=[iden2, adder2])
        test_obj1.local_x = np.array([25])
        self.assertAlmostEqual(test_obj1._dofs.loc['val', '_x'], 25)

        adder3 = Adder(3)
        test_obj2 = OptClassWithParents(10, opts_in=[iden, adder3])

        test_obj2.local_x = np.array([25])
        self.assertAlmostEqual(test_obj2._dofs.loc['val', '_x'], 25)

    def test_full_x(self):
        # Check with leaf type Optimizable objects
        adder = Adder(n=3, x0=[1, 2, 3], dof_names=['x', 'y', 'z'])
        iden = Identity(x=10, dof_fixed=True)
        adder_full_x = adder.full_x
        self.assertAlmostEqual(adder_full_x[0], 1)
        self.assertAlmostEqual(adder_full_x[1], 2)
        self.assertAlmostEqual(adder_full_x[2], 3)
        self.assertEqual(len(iden.full_x), 1)
        self.assertAlmostEqual(iden.full_x[0], 10)

        # Check with Optimizable objects containing parents
        test_obj1 = OptClassWithParents(20, opts_in=[iden, adder])
        full_x = test_obj1.full_x
        self.assertTrue(np.allclose(full_x, np.array([10, 1, 2, 3, 20])))

        test_obj1.x = np.array([4, 5, 6, 25])
        full_x = test_obj1.full_x
        self.assertTrue(np.allclose(full_x, np.array([10, 4, 5, 6, 25])))

    def test_local_full_x(self):
        # Check with leaf type Optimizable objects
        # Check with Optimizable objects containing parents
        adder = Adder(n=3, x0=[1, 2, 3], dof_names=['x', 'y', 'z'])
        iden = Identity(x=10, dof_fixed=True)
        adder_local_full_x = adder.local_full_x
        self.assertAlmostEqual(adder_local_full_x[0], 1)
        self.assertAlmostEqual(adder_local_full_x[1], 2)
        self.assertAlmostEqual(adder_local_full_x[2], 3)
        self.assertEqual(len(iden.local_full_x), 1)
        self.assertAlmostEqual(iden.local_full_x[0], 10)

        # Check with Optimizable objects containing parents
        test_obj1 = OptClassWithParents(20, opts_in=[iden, adder])
        local_full_x = test_obj1.local_full_x
        self.assertTrue(np.allclose(local_full_x, np.array([20])))

        test_obj1.x = np.array([4, 5, 6, 25])
        local_full_x = test_obj1.local_full_x
        self.assertTrue(np.allclose(local_full_x, np.array([25])))

    def test_get(self):
        adder = Adder(n=3,
                      x0=[1, 2, 3],
                      dof_names=['x', 'y', 'z'],
                      dof_fixed=[True, False, False])
        iden = Identity(x=10, dof_fixed=True)

        self.assertAlmostEqual(adder.get(0), 1.)
        self.assertAlmostEqual(adder.get('y'), 2.)
        self.assertAlmostEqual(iden.get('x0'), 10.)

    def test_set(self):
        adder = Adder(n=3,
                      x0=[1, 2, 3],
                      dof_names=['x', 'y', 'z'],
                      dof_fixed=[True, False, False])
        iden = Identity(x=10, dof_fixed=True)

        adder.set(0, 2)
        adder.set('y', 20)
        iden.set('x0', 20)
        self.assertAlmostEqual(adder.full_x[0], 2)
        self.assertAlmostEqual(adder.full_x[1], 20)
        self.assertAlmostEqual(iden.full_x[0], 20)

    def test_call(self):
        # Test for leaf nodes
        adder = Adder(n=3,
                      x0=[1, 2, 3],
                      dof_names=['x', 'y', 'z'],
                      dof_fixed=[True, False, False])
        self.assertAlmostEqual(adder(), 6.0)
        adder.fix('y')
        self.assertAlmostEqual(adder(), 6.0)

        iden = Identity(x=10, dof_fixed=True)
        self.assertAlmostEqual(iden(), 10.0)

        # Set dofs and call
        adder.x = [6]
        self.assertAlmostEqual(adder(), 9.0)
        adder.unfix_all()
        adder.x = [4, 5, 6]
        self.assertAlmostEqual(adder(), 15.0)
        iden.unfix_all()
        iden.x = [20]
        self.assertAlmostEqual(iden(), 20.0)

        # Call with arguments
        self.assertAlmostEqual(adder(x=[10, 11, 12]), 33)
        self.assertAlmostEqual(iden(x=[20]), 20)

        # Now call without arguments to make sure the previous value is returned
        self.assertAlmostEqual(adder(), 33)
        self.assertAlmostEqual(iden(), 20)

        # Fix dofs and now call
        adder.fix('x')
        self.assertAlmostEqual(adder([1, 2]), 13)
        adder.fix_all()
        self.assertAlmostEqual(adder(), 13)
        iden.fix_all()
        self.assertAlmostEqual(iden(), 20)

        # Check with Optimizable objects containing parents
        adder = Adder(n=3,
                      x0=[1, 2, 3],
                      dof_names=['x', 'y', 'z'],
                      dof_fixed=[True, False, False])
        iden = Identity(x=10, dof_fixed=True)
        test_obj1 = OptClassWithParents(20, opts_in=[iden, adder])
        # Value returned by test_obj1 is (val + 2*iden())/(10.0 + adder())
        self.assertAlmostEqual(test_obj1(), 2.5)

        # Set the parents nodes' x and call
        adder.x = [4, 5]
        self.assertAlmostEqual(test_obj1(), 2.0)

        # Set the dofs and call
        test_obj1.x = np.array([14, 15, 30])
        self.assertAlmostEqual(test_obj1(), 1.25)

        # Set only the node  local dofs and call
        test_obj1.local_x = [20]
        self.assertAlmostEqual(test_obj1(), 1.0)

        # Call with arguments
        self.assertAlmostEqual(test_obj1([2, 3, 20]), 2.5)
        # Followed by Call with no arguments
        self.assertAlmostEqual(test_obj1(), 2.5)

    def test_bounds(self):
        pass

    def test_local_bounds(self):
        pass

    def test_lower_bounds(self):
        pass

    def test_local_lower_bounds(self):
        pass

    def test_upper_bounds(self):
        pass

    def test_local_upper_bounds(self):
        pass

    def test_is_fixed(self):
        iden = Identity(x=10, dof_fixed=True)
        adder = Adder(n=3,
                      x0=[1, 2, 3],
                      dof_names=['x', 'y', 'z'],
                      dof_fixed=[True, False, False])
        self.assertTrue(adder.is_fixed(0))
        self.assertTrue(adder.is_fixed('x'))
        self.assertFalse(adder.is_fixed(1))
        self.assertFalse(adder.is_fixed('y'))
        self.assertTrue(iden.is_fixed(0))
        self.assertTrue(iden.is_fixed('x0'))

    def test_is_free(self):
        iden = Identity(x=10, dof_fixed=True)
        adder = Adder(n=3,
                      x0=[1, 2, 3],
                      dof_names=['x', 'y', 'z'],
                      dof_fixed=[True, False, False])
        self.assertFalse(adder.is_free(0))
        self.assertFalse(adder.is_free('x'))
        self.assertTrue(adder.is_free(1))
        self.assertTrue(adder.is_free('y'))
        self.assertFalse(iden.is_free(0))
        self.assertFalse(iden.is_free('x0'))

    def test_fix(self):
        self.iden.fix(0)
        self.adder.fix('x')
        self.rosen.fix('y')

        self.assertEqual(self.iden.dof_size, 0)
        self.assertEqual(self.adder.dof_size, 2)
        self.assertEqual(self.rosen.dof_size, 1)

    def test_fix_all(self):
        self.iden.fix_all()
        self.adder.fix_all()
        self.rosen.fix_all()

        self.assertEqual(self.iden.dof_size, 0)
        self.assertEqual(self.adder.dof_size, 0)
        self.assertEqual(self.rosen.dof_size, 0)

    def test_unfix(self):
        pass

    def test_unfix_all(self):
        # Test with leaf nodes
        adder = Adder(n=3,
                      x0=[1, 2, 3],
                      dof_names=['x', 'y', 'z'],
                      dof_fixed=[True, False, False])
        iden = Identity(x=10, dof_fixed=True)
        adder_x = adder.x
        iden_x = iden.x
        self.assertEqual(len(adder_x), 2)
        self.assertEqual(adder.dof_size, 2)
        self.assertAlmostEqual(adder_x[0], 2)
        self.assertAlmostEqual(adder_x[1], 3)
        self.assertEqual(len(iden_x), 0)

        with self.assertRaises(ValueError):
            iden.x = [10]
        with self.assertRaises(ValueError):
            adder.x = [4, 5, 6]

        iden.unfix_all()
        adder.unfix_all()
        iden.x = [10]
        adder.x = [4, 5, 6]
        self.assertEqual(iden.dof_size, 1)
        self.assertEqual(adder.dof_size, 3)
        self.assertAlmostEqual(adder._dofs.loc['x', '_x'], 4)
        self.assertAlmostEqual(adder._dofs.loc['y', '_x'], 5)
        self.assertAlmostEqual(adder._dofs.loc['z', '_x'], 6)
        self.assertAlmostEqual(iden._dofs.loc['x0', '_x'], 10)

        # Check with Optimizable objects containing parents
        adder = Adder(n=3,
                      x0=[1, 2, 3],
                      dof_names=['x', 'y', 'z'],
                      dof_fixed=[True, False, False])
        iden = Identity(x=10, dof_fixed=True)
        test_obj = OptClassWithParents(10, opts_in=[iden, adder])

        with self.assertRaises(ValueError):
            test_obj.x = np.array([20, 4, 5, 6, 25])

        adder.unfix_all()
        test_obj.x = np.array([4, 5, 6, 25])
        self.assertAlmostEqual(test_obj._dofs.loc['val', '_x'], 25)
        self.assertAlmostEqual(adder._dofs.loc['x', '_x'], 4)
        self.assertAlmostEqual(adder._dofs.loc['y', '_x'], 5)
        self.assertAlmostEqual(adder._dofs.loc['z', '_x'], 6)

        iden.unfix_all()
        test_obj.x = np.array([1, 1, 2, 3, 10])

        self.assertAlmostEqual(iden._dofs.loc['x0', '_x'], 1)
        self.assertAlmostEqual(adder._dofs.loc['x', '_x'], 1)
        self.assertAlmostEqual(adder._dofs.loc['y', '_x'], 2)
        self.assertAlmostEqual(adder._dofs.loc['z', '_x'], 3)
        self.assertAlmostEqual(test_obj._dofs.loc['val', '_x'], 10)

    def test_get_ancestors(self):
        iden = Identity(x=10, dof_fixed=True)
        adder = Adder(n=3, x0=[1, 2, 3])
        self.assertEqual(len(iden._get_ancestors()), 0)
        self.assertEqual(len(adder._get_ancestors()), 0)

        test_obj = OptClassWithParents(10, opts_in=[iden, adder])
        ancestors = test_obj._get_ancestors()
        self.assertEqual(len(ancestors), 2)
        self.assertIn(iden, ancestors)
        self.assertIn(adder, ancestors)

        test_obj2 = OptClassWith2LevelParents(10, 20)
        ancestors = test_obj2._get_ancestors()
        self.assertEqual(len(ancestors), 4)
 def setUp(self) -> None:
     self.iden = Identity(x=10)
     self.adder = Adder(n=3, dof_names=['x', 'y', 'z'])
     self.rosen = Rosenbrock()
    def test_call(self):
        # Test for leaf nodes
        adder = Adder(n=3,
                      x0=[1, 2, 3],
                      dof_names=['x', 'y', 'z'],
                      dof_fixed=[True, False, False])
        self.assertAlmostEqual(adder(), 6.0)
        adder.fix('y')
        self.assertAlmostEqual(adder(), 6.0)

        iden = Identity(x=10, dof_fixed=True)
        self.assertAlmostEqual(iden(), 10.0)

        # Set dofs and call
        adder.x = [6]
        self.assertAlmostEqual(adder(), 9.0)
        adder.unfix_all()
        adder.x = [4, 5, 6]
        self.assertAlmostEqual(adder(), 15.0)
        iden.unfix_all()
        iden.x = [20]
        self.assertAlmostEqual(iden(), 20.0)

        # Call with arguments
        self.assertAlmostEqual(adder(x=[10, 11, 12]), 33)
        self.assertAlmostEqual(iden(x=[20]), 20)

        # Now call without arguments to make sure the previous value is returned
        self.assertAlmostEqual(adder(), 33)
        self.assertAlmostEqual(iden(), 20)

        # Fix dofs and now call
        adder.fix('x')
        self.assertAlmostEqual(adder([1, 2]), 13)
        adder.fix_all()
        self.assertAlmostEqual(adder(), 13)
        iden.fix_all()
        self.assertAlmostEqual(iden(), 20)

        # Check with Optimizable objects containing parents
        adder = Adder(n=3,
                      x0=[1, 2, 3],
                      dof_names=['x', 'y', 'z'],
                      dof_fixed=[True, False, False])
        iden = Identity(x=10, dof_fixed=True)
        test_obj1 = OptClassWithParents(20, opts_in=[iden, adder])
        # Value returned by test_obj1 is (val + 2*iden())/(10.0 + adder())
        self.assertAlmostEqual(test_obj1(), 2.5)

        # Set the parents nodes' x and call
        adder.x = [4, 5]
        self.assertAlmostEqual(test_obj1(), 2.0)

        # Set the dofs and call
        test_obj1.x = np.array([14, 15, 30])
        self.assertAlmostEqual(test_obj1(), 1.25)

        # Set only the node  local dofs and call
        test_obj1.local_x = [20]
        self.assertAlmostEqual(test_obj1(), 1.0)

        # Call with arguments
        self.assertAlmostEqual(test_obj1([2, 3, 20]), 2.5)
        # Followed by Call with no arguments
        self.assertAlmostEqual(test_obj1(), 2.5)