def testSetProfile(self): fc = self.fitcontribution profile = self.profile fc.setProfile(self.profile) # verify standard profile setup self.assertTrue(fc.profile is profile) self.assertTrue(fc.x.par is profile.xpar) self.assertTrue(fc.y.par is profile.ypar) self.assertTrue(fc.dy.par is profile.dypar) self.assertTrue(fc._eq is None) self.assertTrue(fc._reseq is None) # check type checking fc1 = FitContribution('test1') self.assertRaises(TypeError, fc1.setProfile, 'invalid') # check if residual equation is set up when possible fc2 = FitContribution('test2') fc2.setEquation('A * x') fc2.setProfile(profile) self.assertFalse(fc2._reseq is None) return
def testResidual(self): """Test the residual, which requires all other methods.""" fc = self.fitcontribution profile = self.profile gen = self.gen # Add the calculator and profile fc.setProfile(profile) self.assertTrue(fc.profile is profile) fc.addProfileGenerator(gen, "I") self.assertTrue(fc._eq._value is None) self.assertTrue(fc._reseq._value is None) self.assertEqual(1, len(fc._generators)) self.assertTrue(gen.name in fc._generators) # Let's create some data xobs = arange(0, 10, 0.5) yobs = xobs profile.setObservedProfile(xobs, yobs) # Check our fitting equation. self.assertTrue(array_equal(fc._eq(), gen(xobs))) # Now calculate the residual chiv = fc.residual() self.assertAlmostEqual(0, dot(chiv, chiv)) # Now change the equation fc.setEquation("2*I") self.assertTrue(fc._eq._value is None) self.assertTrue(fc._reseq._value is None) chiv = fc.residual() self.assertAlmostEqual(dot(yobs, yobs), dot(chiv, chiv)) # Try to add a parameter c = Parameter("c", 2) fc._addParameter(c) fc.setEquation("c*I") self.assertTrue(fc._eq._value is None) self.assertTrue(fc._reseq._value is None) chiv = fc.residual() self.assertAlmostEqual(dot(yobs, yobs), dot(chiv, chiv)) # Try something more complex c.setValue(3) fc.setEquation("c**2*sin(I)") self.assertTrue(fc._eq._value is None) self.assertTrue(fc._reseq._value is None) xobs = arange(0, 10, 0.5) yobs = 9 * sin(xobs) profile.setObservedProfile(xobs, yobs) self.assertTrue(fc._eq._value is None) self.assertTrue(fc._reseq._value is None) chiv = fc.residual() self.assertAlmostEqual(0, dot(chiv, chiv)) # Choose a new residual. fc.setEquation("2*I") fc.setResidualEquation("resv") chiv = fc.residual() self.assertAlmostEqual( sum((2 * xobs - yobs)**2) / sum(yobs**2), dot(chiv, chiv)) # Make a custom residual. fc.setResidualEquation("abs(eq-y)**0.5") chiv = fc.residual() self.assertAlmostEqual(sum(abs(2 * xobs - yobs)), dot(chiv, chiv)) # Test configuration checks fc1 = FitContribution('test1') self.assertRaises(SrFitError, fc1.setResidualEquation, 'chiv') fc1.setProfile(self.profile) self.assertRaises(SrFitError, fc1.setResidualEquation, 'chiv') fc1.setEquation('A * x') fc1.setResidualEquation('chiv') self.assertTrue(noObserversInGlobalBuilders()) return
class TestFitRecipe(unittest.TestCase): def setUp(self): self.recipe = FitRecipe("recipe") self.recipe.fithooks[0].verbose = 0 # Set up the Profile self.profile = Profile() x = linspace(0, pi, 10) y = sin(x) self.profile.setObservedProfile(x, y) # Set up the FitContribution self.fitcontribution = FitContribution("cont") self.fitcontribution.setProfile(self.profile) self.fitcontribution.setEquation("A*sin(k*x + c)") self.fitcontribution.A.setValue(1) self.fitcontribution.k.setValue(1) self.fitcontribution.c.setValue(0) self.recipe.addContribution(self.fitcontribution) return def testFixFree(self): recipe = self.recipe con = self.fitcontribution recipe.addVar(con.A, 2, tag="tagA") recipe.addVar(con.k, 1, tag="tagk") recipe.addVar(con.c, 0) recipe.newVar("B", 0) self.assertTrue(recipe.isFree(recipe.A)) recipe.fix("tagA") self.assertFalse(recipe.isFree(recipe.A)) recipe.free("tagA") self.assertTrue(recipe.isFree(recipe.A)) recipe.fix("A") self.assertFalse(recipe.isFree(recipe.A)) recipe.free("A") self.assertTrue(recipe.isFree(recipe.A)) recipe.fix(recipe.A) self.assertFalse(recipe.isFree(recipe.A)) recipe.free(recipe.A) self.assertTrue(recipe.isFree(recipe.A)) recipe.fix(recipe.A) self.assertFalse(recipe.isFree(recipe.A)) recipe.free("all") self.assertTrue(recipe.isFree(recipe.A)) self.assertTrue(recipe.isFree(recipe.k)) self.assertTrue(recipe.isFree(recipe.c)) self.assertTrue(recipe.isFree(recipe.B)) recipe.fix(recipe.A, "tagk", c=3) self.assertFalse(recipe.isFree(recipe.A)) self.assertFalse(recipe.isFree(recipe.k)) self.assertFalse(recipe.isFree(recipe.c)) self.assertTrue(recipe.isFree(recipe.B)) self.assertEquals(3, recipe.c.value) recipe.fix("all") self.assertFalse(recipe.isFree(recipe.A)) self.assertFalse(recipe.isFree(recipe.k)) self.assertFalse(recipe.isFree(recipe.c)) self.assertFalse(recipe.isFree(recipe.B)) self.assertRaises(ValueError, recipe.free, "junk") self.assertRaises(ValueError, recipe.fix, tagA=1) self.assertRaises(ValueError, recipe.fix, "junk") return def testVars(self): """Test to see if variables are added and removed properly.""" recipe = self.recipe con = self.fitcontribution recipe.addVar(con.A, 2) recipe.addVar(con.k, 1) recipe.addVar(con.c, 0) recipe.newVar("B", 0) names = recipe.getNames() self.assertEquals(names, ["A", "k", "c", "B"]) values = recipe.getValues() self.assertTrue((values == [2, 1, 0, 0]).all()) # Constrain a parameter to the B-variable to give it a value p = Parameter("Bpar", -1) recipe.constrain(recipe.B, p) values = recipe.getValues() self.assertTrue((values == [2, 1, 0]).all()) recipe.delVar(recipe.B) recipe.fix(recipe.k) names = recipe.getNames() self.assertEquals(names, ["A", "c"]) values = recipe.getValues() self.assertTrue((values == [2, 0]).all()) recipe.fix("all") names = recipe.getNames() self.assertEquals(names, []) values = recipe.getValues() self.assertTrue((values == []).all()) recipe.free("all") names = recipe.getNames() self.assertEquals(3, len(names)) self.assertTrue("A" in names) self.assertTrue("k" in names) self.assertTrue("c" in names) values = recipe.getValues() self.assertEquals(3, len(values)) self.assertTrue(0 in values) self.assertTrue(1 in values) self.assertTrue(2 in values) return def testResidual(self): """Test the residual and everything that can change it.""" # With thing set up as they are, the residual should be 0 res = self.recipe.residual() self.assertAlmostEquals(0, dot(res, res)) # Change the c value to 1 so that the equation evaluates as sin(x+1) x = self.profile.x y = sin(x + 1) self.recipe.cont.c.setValue(1) res = self.recipe.residual() self.assertTrue(array_equal(y - self.profile.y, res)) # Try some constraints # Make c = 2*A, A = Avar var = self.recipe.newVar("Avar") self.recipe.constrain(self.fitcontribution.c, "2*A", {"A": self.fitcontribution.A}) self.assertEquals(2, self.fitcontribution.c.value) self.recipe.constrain(self.fitcontribution.A, var) self.assertEquals(1, var.getValue()) self.assertEquals(self.recipe.cont.A.getValue(), var.getValue()) # c is constrained to a constrained parameter. self.assertEquals(2, self.fitcontribution.c.value) # The equation should evaluate to sin(x+2) x = self.profile.x y = sin(x + 2) res = self.recipe.residual() self.assertTrue(array_equal(y - self.profile.y, res)) # Now try some restraints. We want c to be exactly zero. It should give # a penalty of (c-0)**2, which is 4 in this case r1 = self.recipe.restrain(self.fitcontribution.c, 0, 0, 1) self.recipe._ready = False res = self.recipe.residual() chi2 = 4 + dot(y - self.profile.y, y - self.profile.y) self.assertAlmostEqual(chi2, dot(res, res)) # Clear the constraint and restore the value of c to 0. This should # give us chi2 = 0 again. self.recipe.unconstrain(self.fitcontribution.c) self.fitcontribution.c.setValue(0) res = self.recipe.residual([self.recipe.cont.A.getValue()]) chi2 = 0 self.assertAlmostEqual(chi2, dot(res, res)) # Remove the restraint and variable self.recipe.unrestrain(r1) self.recipe.delVar(self.recipe.Avar) self.recipe._ready = False res = self.recipe.residual() chi2 = 0 self.assertAlmostEqual(chi2, dot(res, res)) # Add constraints at the fitcontribution level. self.fitcontribution.constrain(self.fitcontribution.c, "2*A") # This should evaluate to sin(x+2) x = self.profile.x y = sin(x + 2) res = self.recipe.residual() self.assertTrue(array_equal(y - self.profile.y, res)) # Add a restraint at the fitcontribution level. r1 = self.fitcontribution.restrain(self.fitcontribution.c, 0, 0, 1) self.recipe._ready = False # The chi2 is the same as above, plus 4 res = self.recipe.residual() x = self.profile.x y = sin(x + 2) chi2 = 4 + dot(y - self.profile.y, y - self.profile.y) self.assertAlmostEqual(chi2, dot(res, res)) # Remove those self.fitcontribution.unrestrain(r1) self.recipe._ready = False self.fitcontribution.unconstrain(self.fitcontribution.c) self.fitcontribution.c.setValue(0) res = self.recipe.residual() chi2 = 0 self.assertAlmostEqual(chi2, dot(res, res)) # Now try to use the observed profile inside of the equation # Set the equation equal to the data self.fitcontribution.setEquation("y") res = self.recipe.residual() self.assertAlmostEquals(0, dot(res, res)) # Now add the uncertainty. This should give dy/dy = 1 for the residual self.fitcontribution.setEquation("y+dy") res = self.recipe.residual() self.assertAlmostEquals(len(res), dot(res, res)) return
class TestFitRecipe(unittest.TestCase): def setUp(self): self.recipe = FitRecipe("recipe") self.recipe.fithooks[0].verbose = 0 # Set up the Profile self.profile = Profile() x = linspace(0, pi, 10) y = sin(x) self.profile.setObservedProfile(x, y) # Set up the FitContribution self.fitcontribution = FitContribution("cont") self.fitcontribution.setProfile(self.profile) self.fitcontribution.setEquation("A*sin(k*x + c)") self.fitcontribution.A.setValue(1) self.fitcontribution.k.setValue(1) self.fitcontribution.c.setValue(0) self.recipe.addContribution(self.fitcontribution) return def testFixFree(self): recipe = self.recipe con = self.fitcontribution recipe.addVar(con.A, 2, tag = "tagA") recipe.addVar(con.k, 1, tag = "tagk") recipe.addVar(con.c, 0) recipe.newVar("B", 0) self.assertTrue(recipe.isFree(recipe.A)) recipe.fix("tagA") self.assertFalse(recipe.isFree(recipe.A)) recipe.free("tagA") self.assertTrue(recipe.isFree(recipe.A)) recipe.fix("A") self.assertFalse(recipe.isFree(recipe.A)) recipe.free("A") self.assertTrue(recipe.isFree(recipe.A)) recipe.fix(recipe.A) self.assertFalse(recipe.isFree(recipe.A)) recipe.free(recipe.A) self.assertTrue(recipe.isFree(recipe.A)) recipe.fix(recipe.A) self.assertFalse(recipe.isFree(recipe.A)) recipe.free("all") self.assertTrue(recipe.isFree(recipe.A)) self.assertTrue(recipe.isFree(recipe.k)) self.assertTrue(recipe.isFree(recipe.c)) self.assertTrue(recipe.isFree(recipe.B)) recipe.fix(recipe.A, "tagk", c = 3) self.assertFalse(recipe.isFree(recipe.A)) self.assertFalse(recipe.isFree(recipe.k)) self.assertFalse(recipe.isFree(recipe.c)) self.assertTrue(recipe.isFree(recipe.B)) self.assertEqual(3, recipe.c.value) recipe.fix("all") self.assertFalse(recipe.isFree(recipe.A)) self.assertFalse(recipe.isFree(recipe.k)) self.assertFalse(recipe.isFree(recipe.c)) self.assertFalse(recipe.isFree(recipe.B)) self.assertRaises(ValueError, recipe.free, "junk") self.assertRaises(ValueError, recipe.fix, tagA = 1) self.assertRaises(ValueError, recipe.fix, "junk") return def testVars(self): """Test to see if variables are added and removed properly.""" recipe = self.recipe con = self.fitcontribution recipe.addVar(con.A, 2) recipe.addVar(con.k, 1) recipe.addVar(con.c, 0) recipe.newVar("B", 0) names = recipe.getNames() self.assertEqual(names, ["A", "k", "c", "B"]) values = recipe.getValues() self.assertTrue((values == [2, 1, 0, 0]).all()) # Constrain a parameter to the B-variable to give it a value p = Parameter("Bpar", -1) recipe.constrain(recipe.B, p) values = recipe.getValues() self.assertTrue((values == [2, 1, 0]).all()) recipe.delVar(recipe.B) recipe.fix(recipe.k) names = recipe.getNames() self.assertEqual(names, ["A", "c"]) values = recipe.getValues() self.assertTrue((values == [2, 0]).all()) recipe.fix("all") names = recipe.getNames() self.assertEqual(names, []) values = recipe.getValues() self.assertTrue((values == []).all()) recipe.free("all") names = recipe.getNames() self.assertEqual(3, len(names)) self.assertTrue("A" in names) self.assertTrue("k" in names) self.assertTrue("c" in names) values = recipe.getValues() self.assertEqual(3, len(values)) self.assertTrue(0 in values) self.assertTrue(1 in values) self.assertTrue(2 in values) return def testResidual(self): """Test the residual and everything that can change it.""" # With thing set up as they are, the residual should be 0 res = self.recipe.residual() self.assertAlmostEqual(0, dot(res, res)) # Change the c value to 1 so that the equation evaluates as sin(x+1) x = self.profile.x y = sin(x+1) self.recipe.cont.c.setValue(1) res = self.recipe.residual() self.assertTrue( array_equal(y-self.profile.y, res) ) # Try some constraints # Make c = 2*A, A = Avar var = self.recipe.newVar("Avar") self.recipe.constrain(self.fitcontribution.c, "2*A", {"A" : self.fitcontribution.A}) self.assertEqual(2, self.fitcontribution.c.value) self.recipe.constrain(self.fitcontribution.A, var) self.assertEqual(1, var.getValue()) self.assertEqual(self.recipe.cont.A.getValue(), var.getValue()) # c is constrained to a constrained parameter. self.assertEqual(2, self.fitcontribution.c.value) # The equation should evaluate to sin(x+2) x = self.profile.x y = sin(x+2) res = self.recipe.residual() self.assertTrue( array_equal(y-self.profile.y, res) ) # Now try some restraints. We want c to be exactly zero. It should give # a penalty of (c-0)**2, which is 4 in this case r1 = self.recipe.restrain(self.fitcontribution.c, 0, 0, 1) self.recipe._ready = False res = self.recipe.residual() chi2 = 4 + dot(y - self.profile.y, y - self.profile.y) self.assertAlmostEqual(chi2, dot(res, res) ) # Clear the constraint and restore the value of c to 0. This should # give us chi2 = 0 again. self.recipe.unconstrain(self.fitcontribution.c) self.fitcontribution.c.setValue(0) res = self.recipe.residual([self.recipe.cont.A.getValue()]) chi2 = 0 self.assertAlmostEqual(chi2, dot(res, res) ) # Remove the restraint and variable self.recipe.unrestrain(r1) self.recipe.delVar(self.recipe.Avar) self.recipe._ready = False res = self.recipe.residual() chi2 = 0 self.assertAlmostEqual(chi2, dot(res, res) ) # Add constraints at the fitcontribution level. self.fitcontribution.constrain(self.fitcontribution.c, "2*A") # This should evaluate to sin(x+2) x = self.profile.x y = sin(x+2) res = self.recipe.residual() self.assertTrue( array_equal(y-self.profile.y, res) ) # Add a restraint at the fitcontribution level. r1 = self.fitcontribution.restrain(self.fitcontribution.c, 0, 0, 1) self.recipe._ready = False # The chi2 is the same as above, plus 4 res = self.recipe.residual() x = self.profile.x y = sin(x+2) chi2 = 4 + dot(y - self.profile.y, y - self.profile.y) self.assertAlmostEqual(chi2, dot(res, res) ) # Remove those self.fitcontribution.unrestrain(r1) self.recipe._ready = False self.fitcontribution.unconstrain(self.fitcontribution.c) self.fitcontribution.c.setValue(0) res = self.recipe.residual() chi2 = 0 self.assertAlmostEqual(chi2, dot(res, res) ) # Now try to use the observed profile inside of the equation # Set the equation equal to the data self.fitcontribution.setEquation("y") res = self.recipe.residual() self.assertAlmostEqual(0, dot(res, res)) # Now add the uncertainty. This should give dy/dy = 1 for the residual self.fitcontribution.setEquation("y+dy") res = self.recipe.residual() self.assertAlmostEqual(len(res), dot(res, res)) return def testPrintFitHook(self): "check output from default PrintFitHook." self.recipe.addVar(self.fitcontribution.c) self.recipe.restrain('c', lb=5) pfh, = self.recipe.getFitHooks() out = capturestdout(self.recipe.scalarResidual) self.assertEqual('', out) pfh.verbose = 1 out = capturestdout(self.recipe.scalarResidual) self.assertTrue(out.strip().isdigit()) self.assertFalse('\nRestraints:' in out) pfh.verbose = 2 out = capturestdout(self.recipe.scalarResidual) self.assertTrue('\nResidual:' in out) self.assertTrue('\nRestraints:' in out) self.assertFalse('\nVariables' in out) pfh.verbose = 3 out = capturestdout(self.recipe.scalarResidual) self.assertTrue('\nVariables' in out) self.assertTrue('c = ' in out) return
def testResidual(self): """Test the residual, which requires all other methods.""" fc = self.fitcontribution profile = self.profile gen = self.gen # Add the calculator and profile fc.setProfile(profile) self.assertTrue(fc.profile is profile) fc.addProfileGenerator(gen, "I") self.assertTrue(fc._eq._value is None) self.assertTrue(fc._reseq._value is None) self.assertEqual(1, len(fc._generators)) self.assertTrue(gen.name in fc._generators) # Let's create some data xobs = arange(0, 10, 0.5) yobs = xobs profile.setObservedProfile(xobs, yobs) # Check our fitting equation. self.assertTrue(array_equal(fc._eq(), gen(xobs))) # Now calculate the residual chiv = fc.residual() self.assertAlmostEqual(0, dot(chiv, chiv)) # Now change the equation fc.setEquation("2*I") self.assertTrue(fc._eq._value is None) self.assertTrue(fc._reseq._value is None) chiv = fc.residual() self.assertAlmostEqual(dot(yobs, yobs), dot(chiv, chiv)) # Try to add a parameter c = Parameter("c", 2) fc._addParameter(c) fc.setEquation("c*I") self.assertTrue(fc._eq._value is None) self.assertTrue(fc._reseq._value is None) chiv = fc.residual() self.assertAlmostEqual(dot(yobs, yobs), dot(chiv, chiv)) # Try something more complex c.setValue(3) fc.setEquation("c**2*sin(I)") self.assertTrue(fc._eq._value is None) self.assertTrue(fc._reseq._value is None) xobs = arange(0, 10, 0.5) yobs = 9*sin(xobs) profile.setObservedProfile(xobs, yobs) self.assertTrue(fc._eq._value is None) self.assertTrue(fc._reseq._value is None) chiv = fc.residual() self.assertAlmostEqual(0, dot(chiv, chiv)) # Choose a new residual. fc.setEquation("2*I") fc.setResidualEquation("resv") chiv = fc.residual() self.assertAlmostEqual(sum((2*xobs-yobs)**2)/sum(yobs**2), dot(chiv, chiv)) # Make a custom residual. fc.setResidualEquation("abs(eq-y)**0.5") chiv = fc.residual() self.assertAlmostEqual(sum(abs(2*xobs-yobs)), dot(chiv, chiv)) # Test configuration checks fc1 = FitContribution('test1') self.assertRaises(SrFitError, fc1.setResidualEquation, 'chiv') fc1.setProfile(self.profile) self.assertRaises(SrFitError, fc1.setResidualEquation, 'chiv') fc1.setEquation('A * x') fc1.setResidualEquation('chiv') self.assertTrue(noObserversInGlobalBuilders()) return