def setUp(self): self._index = 3 self._value = 2.0 self._uncertainty = 1.2 self._constraint = GaussianSimpleParameterConstraint( index=self._index, value=self._value, uncertainty=self._uncertainty) self._roundtrip_stringstream = IOStreamHandle(StringIO()) self._testfile_stringstream_abs = IOStreamHandle( StringIO(TEST_SIMPLE_GAUSSIAN_CONSTRAINT_ABS)) self._testfile_stringstream_rel = IOStreamHandle( StringIO(TEST_SIMPLE_GAUSSIAN_CONSTRAINT_REL)) self._roundtrip_streamreader = ConstraintYamlReader( self._roundtrip_stringstream) self._roundtrip_streamwriter = ConstraintYamlWriter( self._constraint, self._roundtrip_stringstream) self._testfile_streamreader_abs = ConstraintYamlReader( self._testfile_stringstream_abs) self._testfile_streamreader_rel = ConstraintYamlReader( self._testfile_stringstream_rel) self._testfile_stringstream_missing_keyword = IOStreamHandle( StringIO(TEST_SIMPLE_GAUSSIAN_CONSTRAINT_MISSING_KEYWORD)) self._testfile_stringstream_extra_keyword = IOStreamHandle( StringIO(TEST_SIMPLE_GAUSSIAN_CONSTRAINT_EXTRA_KEYWORD)) self._testfile_streamreader_missing_keyword = ConstraintYamlReader( self._testfile_stringstream_missing_keyword) self._testfile_streamreader_extra_keyword = ConstraintYamlReader( self._testfile_stringstream_extra_keyword)
def test_cost_simple_rel(self): for _i in range(3): for _j in range(3): for _k in range(3): _constraint = GaussianSimpleParameterConstraint( self._par_indices[_i], self._par_values[_j], self._par_uncertainties_rel[_k], relative=True) self.assertTrue( np.allclose(_constraint.cost(self._fit_par_values), self._expected_cost_rel[_i, _j, _k])) # ensure that results are consistent with matrix constraints _constraint = GaussianMatrixParameterConstraint( [self._par_indices[_i]], [self._par_values[_j]], [[self._par_uncertainties_rel[_k]**2]], relative=True) self.assertTrue( np.allclose(_constraint.cost(self._fit_par_values), self._expected_cost_rel[_i, _j, _k])) _constraint = GaussianMatrixParameterConstraint( [self._par_indices[_i]], [self._par_values[_j]], [[1.0]], matrix_type='cor', uncertainties=[self._par_uncertainties_rel[_k]], relative=True) self.assertTrue( np.allclose(_constraint.cost(self._fit_par_values), self._expected_cost_rel[_i, _j, _k]))
def setUp(self): self._data_chi2 = np.array([-0.5, 2.1, 8.9]) self._model_chi2 = np.array([5.7, 8.4, -2.3]) self._data_poisson = np.array([0.0, 2.0, 9.0]) self._model_poisson = np.array([5.7, 8.4, 2.3]) self._res = self._data_chi2 - self._model_chi2 self._cov_mat = np.array([ [1.0, 0.1, 0.2], [0.1, 2.0, 0.3], [0.2, 0.3, 3.0] ]) self._cov_mat_inv = np.linalg.inv(self._cov_mat) self._pointwise_errors = np.sqrt(np.diag(self._cov_mat)) self._cost_chi2_cov_mat = self._res.dot(self._cov_mat_inv).dot(self._res) self._cost_chi2_pointwise = np.sum((self._res / self._pointwise_errors) ** 2) self._cost_chi2_no_errors = np.sum(self._res ** 2) self._cost_nll_gaussian = self._cost_chi2_pointwise + 2.0 * np.sum(np.log( np.sqrt((2.0 * np.pi)) * self._pointwise_errors)) self._cost_nll_poisson = -2.0 * np.sum( np.log(self._model_poisson ** self._data_poisson) - np.log(factorial(self._data_poisson)) - self._model_poisson) self._cost_nllr_poisson = self._cost_nll_poisson + 2.0 * np.sum( np.log(self._data_poisson ** self._data_poisson) - np.log(factorial(self._data_poisson)) - self._data_poisson) self._par_vals = np.array([12.3, 0.001, -1.9]) self._simple_constraint = GaussianSimpleParameterConstraint( index=0, value=10.0, uncertainty=2.5) self._matrix_constraint = GaussianMatrixParameterConstraint( indices=(0, 1, 2), values=(1.0, 2.0, 3.0), matrix=[ [1.5, 0.1, 0.1], [0.1, 2.2, 0.1], [0.1, 0.1, 0.3] ] ) self. _par_constraints = [self._simple_constraint, self._matrix_constraint] self._par_cost = self._simple_constraint.cost(self._par_vals) \ + self._matrix_constraint.cost(self._par_vals)
def setUp(self): def my_cost(a, b, c, d): return a ** 2 + (b + c) ** 2 + (d - 1) ** 2 def my_cost_varargs(*args): return args[0] ** 2 + (args[1] + args[2]) ** 2 + (args[3] - 1) ** 2 self._ref_par_vals = [1, 2, 5, 7] self._ref_cost = my_cost(*self._ref_par_vals) self._constraint = GaussianSimpleParameterConstraint(index=0, value=0, uncertainty=1) self._matrix_constraint = GaussianMatrixParameterConstraint( indices=[1], values=[0], matrix=[[1]]) self._constraint_cost = self._ref_par_vals[0] ** 2 + self._ref_par_vals[1] ** 2 self._ref_par_vals_constraints = self._ref_par_vals + [ self._ref_par_vals, [self._constraint, self._matrix_constraint]] self._cost_func = CostFunction(my_cost, arg_names=None, add_constraint_cost=False) self._cost_func_constraints = CostFunction( my_cost, arg_names=None, add_constraint_cost=True) self._cost_func_varargs = CostFunction( my_cost_varargs, arg_names=["a", "b", "c", "d"], add_constraint_cost=False) self._cost_func_varargs_constraints = CostFunction( my_cost_varargs, arg_names=["a", "b", "c", "d"], add_constraint_cost=True)
class TestCostBuiltin(unittest.TestCase): CHI2_COST_FUNCTION = CostFunction_Chi2 NLL_COST_FUNCTION = CostFunction_NegLogLikelihood def setUp(self): self._data_chi2 = np.array([-0.5, 2.1, 8.9]) self._model_chi2 = np.array([5.7, 8.4, -2.3]) self._data_poisson = np.array([0.0, 2.0, 9.0]) self._model_poisson = np.array([5.7, 8.4, 2.3]) self._res = self._data_chi2 - self._model_chi2 self._cov_mat = np.array([ [1.0, 0.1, 0.2], [0.1, 2.0, 0.3], [0.2, 0.3, 3.0] ]) self._cov_mat_inv = np.linalg.inv(self._cov_mat) self._pointwise_errors = np.sqrt(np.diag(self._cov_mat)) self._cost_chi2_cov_mat = self._res.dot(self._cov_mat_inv).dot(self._res) self._cost_chi2_pointwise = np.sum((self._res / self._pointwise_errors) ** 2) self._cost_chi2_no_errors = np.sum(self._res ** 2) self._cost_nll_gaussian = self._cost_chi2_pointwise + 2.0 * np.sum(np.log( np.sqrt((2.0 * np.pi)) * self._pointwise_errors)) self._cost_nll_poisson = -2.0 * np.sum( np.log(self._model_poisson ** self._data_poisson) - np.log(factorial(self._data_poisson)) - self._model_poisson) self._cost_nllr_poisson = self._cost_nll_poisson + 2.0 * np.sum( np.log(self._data_poisson ** self._data_poisson) - np.log(factorial(self._data_poisson)) - self._data_poisson) self._par_vals = np.array([12.3, 0.001, -1.9]) self._simple_constraint = GaussianSimpleParameterConstraint( index=0, value=10.0, uncertainty=2.5) self._matrix_constraint = GaussianMatrixParameterConstraint( indices=(0, 1, 2), values=(1.0, 2.0, 3.0), matrix=[ [1.5, 0.1, 0.1], [0.1, 2.2, 0.1], [0.1, 0.1, 0.3] ] ) self. _par_constraints = [self._simple_constraint, self._matrix_constraint] self._par_cost = self._simple_constraint.cost(self._par_vals) \ + self._matrix_constraint.cost(self._par_vals) def test_chi2_no_errors(self): self.assertAlmostEqual( self._cost_chi2_no_errors, self.CHI2_COST_FUNCTION(errors_to_use=None) (self._data_chi2, self._model_chi2, None, None)) self.assertAlmostEqual( self._cost_chi2_no_errors + self._par_cost, self.CHI2_COST_FUNCTION(errors_to_use=None) (self._data_chi2, self._model_chi2, self._par_vals, self._par_constraints)) def test_chi2_pointwise(self): self.assertAlmostEqual( self._cost_chi2_pointwise, self.CHI2_COST_FUNCTION(errors_to_use='pointwise') (self._data_chi2, self._model_chi2, self._pointwise_errors, None, None)) self.assertAlmostEqual( self._cost_chi2_pointwise + self._par_cost, self.CHI2_COST_FUNCTION(errors_to_use='pointwise') (self._data_chi2, self._model_chi2, self._pointwise_errors, self._par_vals, self._par_constraints)) def test_chi2_cov_mat(self): self.assertAlmostEqual( self._cost_chi2_cov_mat, self.CHI2_COST_FUNCTION(errors_to_use='covariance') (self._data_chi2, self._model_chi2, self._cov_mat_inv, None, None)) self.assertAlmostEqual( self._cost_chi2_cov_mat + self._par_cost, self.CHI2_COST_FUNCTION(errors_to_use='covariance') (self._data_chi2, self._model_chi2, self._cov_mat_inv, self._par_vals, self._par_constraints)) def test_nll_gaussian(self): self.assertAlmostEqual( self._cost_nll_gaussian, self.NLL_COST_FUNCTION(data_point_distribution='gaussian') (self._data_chi2, self._model_chi2, self._pointwise_errors, None, None)) self.assertAlmostEqual( self._cost_nll_gaussian + self._par_cost, self.NLL_COST_FUNCTION(data_point_distribution='gaussian') (self._data_chi2, self._model_chi2, self._pointwise_errors, self._par_vals, self._par_constraints)) def test_nll_poisson(self): self.assertAlmostEqual( self._cost_nll_poisson, self.NLL_COST_FUNCTION(data_point_distribution='poisson') (self._data_poisson, self._model_poisson, None, None)) self.assertAlmostEqual( self._cost_nll_poisson + self._par_cost, self.NLL_COST_FUNCTION(data_point_distribution='poisson') (self._data_poisson, self._model_poisson, self._par_vals, self._par_constraints)) def test_nllr_gaussian(self): self.assertAlmostEqual( self._cost_chi2_pointwise, self.NLL_COST_FUNCTION(data_point_distribution='gaussian', ratio=True) (self._data_chi2, self._model_chi2, self._pointwise_errors, None, None)) self.assertAlmostEqual( self._cost_chi2_pointwise + self._par_cost, self.NLL_COST_FUNCTION(data_point_distribution='gaussian', ratio=True) (self._data_chi2, self._model_chi2, self._pointwise_errors, self._par_vals, self._par_constraints)) def test_nllr_poisson(self): self.assertAlmostEqual( self._cost_nllr_poisson, self.NLL_COST_FUNCTION(data_point_distribution='poisson', ratio=True) (self._data_poisson, self._model_poisson, None, None)) self.assertAlmostEqual( self._cost_nllr_poisson + self._par_cost, self.NLL_COST_FUNCTION(data_point_distribution='poisson', ratio=True) (self._data_poisson, self._model_poisson, self._par_vals, self._par_constraints)) def test_chi2_raise(self): with self.assertRaises(ValueError): self.CHI2_COST_FUNCTION(errors_to_use="XYZ") with self.assertRaises(ValueError): self.CHI2_COST_FUNCTION(errors_to_use="covariance")( self._data_chi2, np.ones(10), self._cov_mat_inv, None, None) with self.assertRaises(CostFunctionException): self.CHI2_COST_FUNCTION(errors_to_use="covariance", fallback_on_singular=False)( self._data_chi2, self._model_chi2, None, None, None) with self.assertRaises(CostFunctionException): self.CHI2_COST_FUNCTION(errors_to_use="pointwise", fallback_on_singular=False)( self._data_chi2, self._model_chi2, np.arange(len(self._pointwise_errors)), None, None) def test_nll_raise(self): with self.assertRaises(ValueError): self.NLL_COST_FUNCTION(data_point_distribution="yes") def test_inf_cost(self): self.assertEqual( np.inf, self.CHI2_COST_FUNCTION(errors_to_use="covariance")( self._data_chi2, np.nan * np.ones_like(self._model_chi2), self._cov_mat_inv, None, None) ) self.assertEqual( np.inf, self.CHI2_COST_FUNCTION(errors_to_use="pointwise")( self._data_chi2, np.nan * np.ones_like(self._model_chi2), self._pointwise_errors, None, None) ) self.assertEqual( np.inf, self.CHI2_COST_FUNCTION(errors_to_use=None)( self._data_chi2, np.nan * np.ones_like(self._model_chi2), None, None) ) self.assertEqual( np.inf, self.NLL_COST_FUNCTION("poisson", ratio=False)( self._data_poisson, -self._model_poisson, None, None) ) self.assertEqual( np.inf, self.NLL_COST_FUNCTION("poisson", ratio=True)( self._data_poisson, -self._model_poisson, None, None) ) self.assertEqual( np.inf, self.NLL_COST_FUNCTION("gaussian", ratio=False)( self._data_chi2, self._model_chi2, -self._pointwise_errors, None, None) ) self.assertEqual( np.inf, self.NLL_COST_FUNCTION("gaussian", ratio=True)( self._data_chi2, self._model_chi2, -self._pointwise_errors, None, None) )
class TestCostBase(unittest.TestCase): CHI2_COST_FUNCTION = CostFunctionBase_Chi2 NLL_COST_FUNCTION = CostFunctionBase_NegLogLikelihood NLLR_COST_FUNCTION = CostFunctionBase_NegLogLikelihoodRatio def setUp(self): self._tol = 1e-10 self._data = np.array([-0.5, 2.1, 8.9]) self._model = np.array([5.7, 8.4, -2.3]) self._data_poisson = np.array([0.0, 2.0, 9.0]) self._model_poisson = np.array([5.7, 8.4, 2.3]) self._res = self._data - self._model self._cov_mat = np.array([[1.0, 0.1, 0.2], [0.1, 2.0, 0.3], [0.2, 0.3, 3.0]]) self._cov_mat_inv = np.linalg.inv(self._cov_mat) self._pointwise_errors = np.sqrt(np.diag(self._cov_mat)) self._cost_chi2_cov_mat = self._res.dot(self._cov_mat_inv).dot( self._res) self._cost_chi2_pointwise = np.sum( (self._res / self._pointwise_errors)**2) # same as nllr_gaussian self._cost_chi2_no_errors = np.sum(self._res**2) self._cost_nll_gaussian = self._cost_chi2_pointwise + 2.0 * np.sum( np.log(np.sqrt((2.0 * np.pi)) * self._pointwise_errors)) #self._cost_nll_poisson = np.sum(np.log( # self._model ** self._data_rounded / (factorial(self._data_rounded) * np.exp(self._model)))) self._cost_nll_poisson = -2.0 * np.sum( np.log(self._model_poisson**self._data_poisson) - np.log(factorial(self._data_poisson)) - self._model_poisson) self._cost_nllr_poisson = self._cost_nll_poisson + 2.0 * np.sum( np.log(self._data_poisson**self._data_poisson) - np.log(factorial(self._data_poisson)) - self._data_poisson) self._par_vals = np.array([12.3, 0.001, -1.9]) self._simple_constraint = GaussianSimpleParameterConstraint( index=0, value=10.0, uncertainty=2.5) self._matrix_constraint = GaussianMatrixParameterConstraint( indices=(0, 1, 2), values=(1.0, 2.0, 3.0), matrix=[[1.5, 0.1, 0.1], [0.1, 2.2, 0.1], [0.1, 0.1, 0.3]]) self._par_constraints = [ self._simple_constraint, self._matrix_constraint ] self._par_cost = self._simple_constraint.cost( self._par_vals) + self._matrix_constraint.cost(self._par_vals) def test_chi2_no_errors(self): self.assertTrue( np.abs(self._cost_chi2_no_errors - self.CHI2_COST_FUNCTION(errors_to_use=None) (self._data, self._model, None, None)) < self._tol) self.assertTrue( np.abs(self._cost_chi2_no_errors + self._par_cost - self.CHI2_COST_FUNCTION(errors_to_use=None) (self._data, self._model, self._par_vals, self._par_constraints)) < self._tol) def test_chi2_pointwise(self): self.assertTrue( np.abs(self._cost_chi2_pointwise - self.CHI2_COST_FUNCTION(errors_to_use='pointwise') (self._data, self._model, self._pointwise_errors, None, None)) < self._tol) self.assertTrue( np.abs(self._cost_chi2_pointwise + self._par_cost - self.CHI2_COST_FUNCTION(errors_to_use='pointwise') (self._data, self._model, self._pointwise_errors, self._par_vals, self._par_constraints)) < self._tol) def test_chi2_cov_mat(self): self.assertTrue( np.abs(self._cost_chi2_cov_mat - self.CHI2_COST_FUNCTION(errors_to_use='covariance') (self._data, self._model, self._cov_mat_inv, None, None)) < self._tol) self.assertTrue( np.abs(self._cost_chi2_cov_mat + self._par_cost - self.CHI2_COST_FUNCTION(errors_to_use='covariance') (self._data, self._model, self._cov_mat_inv, self._par_vals, self._par_constraints)) < self._tol) def test_nll_gaussian(self): self.assertTrue( np.abs(self._cost_nll_gaussian - self.NLL_COST_FUNCTION(data_point_distribution='gaussian') (self._data, self._model, self._pointwise_errors, None, None)) < self._tol) self.assertTrue( np.abs(self._cost_nll_gaussian + self._par_cost - self.NLL_COST_FUNCTION(data_point_distribution='gaussian') (self._data, self._model, self._pointwise_errors, self._par_vals, self._par_constraints)) < self._tol) def test_nll_poisson(self): self.assertTrue( np.abs(self._cost_nll_poisson - self.NLL_COST_FUNCTION(data_point_distribution='poisson') (self._data_poisson, self._model_poisson, None, None)) < self._tol) self.assertTrue( np.abs(self._cost_nll_poisson + self._par_cost - self.NLL_COST_FUNCTION(data_point_distribution='poisson') (self._data_poisson, self._model_poisson, self._par_vals, self._par_constraints)) < self._tol) def test_nllr_gaussian(self): self.assertTrue( np.abs(self._cost_chi2_pointwise - self.NLLR_COST_FUNCTION(data_point_distribution='gaussian') (self._data, self._model, self._pointwise_errors, None, None)) < self._tol) self.assertTrue( np.abs(self._cost_chi2_pointwise + self._par_cost - self.NLLR_COST_FUNCTION(data_point_distribution='gaussian') (self._data, self._model, self._pointwise_errors, self._par_vals, self._par_constraints)) < self._tol) def test_nllr_poisson(self): self.assertTrue( np.abs(self._cost_nllr_poisson - self.NLLR_COST_FUNCTION(data_point_distribution='poisson') (self._data_poisson, self._model_poisson, None, None)) < self._tol) self.assertTrue( np.abs(self._cost_nllr_poisson + self._par_cost - self.NLLR_COST_FUNCTION(data_point_distribution='poisson') (self._data_poisson, self._model_poisson, self._par_vals, self._par_constraints)) < self._tol)