def __init__(self, name="fit", conclass=FitContribution): """Initialization.""" FitRecipe.__init__(self, name) self.fithooks[0].verbose = 3 contribution = conclass("contribution") self.profile = Profile() contribution.setProfile(self.profile) self.addContribution(contribution) self.results = FitResults(self, update=False) # Adopt all the FitContribution methods public = [ aname for aname in dir(contribution) if aname not in dir(self) and not aname.startswith("_") ] for mname in public: method = getattr(contribution, mname) setattr(self, mname, method) return
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 setUp(self): self.recipe = recipe = FitRecipe("recipe") recipe.newVar("A", 0) recipe.newVar("sig", 0) recipe.newVar("x0", 0) self.filename = datafile("results.res") self.Aval = 5.77619823e-01 self.sigval = -9.22758690e-01 self.x0val = 6.12422115e+00 return
def testConstrainSpaceGroup(self): """Make sure that all Parameters are constrained properly. This tests constrainSpaceGroup from diffpy.srfit.structure.sgconstraints, which is performed automatically when an ObjCrystCrystalParSet is created. """ pi = numpy.pi occryst = makeLaMnO3() stru = ObjCrystCrystalParSet(occryst.GetName(), occryst) # Make sure we actually create the constraints stru._constrainSpaceGroup() # Make the space group parameters individually stru.sgpars.latpars stru.sgpars.xyzpars stru.sgpars.adppars # Check the orthorhombic lattice l = stru.getLattice() self.assertTrue( l.alpha.const ) self.assertTrue( l.beta.const ) self.assertTrue( l.gamma.const ) self.assertEquals(pi/2, l.alpha.getValue()) self.assertEquals(pi/2, l.beta.getValue()) self.assertEquals(pi/2, l.gamma.getValue()) self.assertFalse( l.a.const ) self.assertFalse( l.b.const ) self.assertFalse( l.c.const ) self.assertEquals(0, len(l._constraints)) # Now make sure the scatterers are constrained properly scatterers = stru.getScatterers() la = scatterers[0] self.assertFalse(la.x.const) self.assertFalse(la.y.const) self.assertTrue(la.z.const) self.assertEquals(0, len(la._constraints)) mn = scatterers[1] self.assertTrue(mn.x.const) self.assertTrue(mn.y.const) self.assertTrue(mn.z.const) self.assertEquals(0, len(mn._constraints)) o1 = scatterers[2] self.assertFalse(o1.x.const) self.assertFalse(o1.y.const) self.assertTrue(o1.z.const) self.assertEquals(0, len(o1._constraints)) o2 = scatterers[3] self.assertFalse(o2.x.const) self.assertFalse(o2.y.const) self.assertFalse(o2.z.const) self.assertEquals(0, len(o2._constraints)) # Make sure we can't constrain these self.assertRaises(ValueError, mn.constrain, mn.x, "y") self.assertRaises(ValueError, mn.constrain, mn.y, "z") self.assertRaises(ValueError, mn.constrain, mn.z, "x") # Nor can we make them into variables from diffpy.srfit.fitbase.fitrecipe import FitRecipe f = FitRecipe() self.assertRaises(ValueError, f.addVar, mn.x) 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