Package park :: Package optim :: Module fitutil

Source Code for Module park.optim.fitutil

 1  # This program is public domain 
 2  """ 
 3  Helper functions for fitting. 
 4  """ 
 5  __all__ = ['populate'] 
 6  import numpy 
 7   
8 -def populate(size, pars, radius=100, elitism=True):
9 """ 10 Generate a population within a parameter space. 11 12 The population will be centered on the initial value, with the 13 given radius. Radius is a percentage of the total space, or a 14 percentage of the initial value if the space is unbounded. 15 If radius is given as a vector, the radius is the length of the 16 selection box in each dimension of the problem space. This is 17 clipped to the bounds of the problem. 18 19 Note that the term radius is a bit misleading since the volume 20 used is rectilinear rather than ellipsoidal, but it captures the 21 notion of whether values should be clustered tightly in the 22 available search space, or ranged broadly. 23 """ 24 # Find initial value and bounds 25 x0 = numpy.array([p.value for p in pars]) 26 bounds = numpy.array([p.range for p in pars]).T 27 lo,hi = bounds 28 29 # Convert bounds into step size based on radius 30 # Convert unbounded steps to a portion of the initial value, or to 1 31 # if the initial value is zero 32 if numpy.isscalar(radius): 33 step = radius*0.01*(hi-lo) 34 idx = numpy.isinf(step) 35 step[idx] = abs(x0[idx])*radius*0.01 36 step[step==0] = 1 37 else: 38 step = radius 39 if numpy.isinf(step).any(): 40 raise ValueError('individual radii must be finite') 41 42 43 # Create a box centered on the initial value and clipped to the range 44 boxlo,boxhi = x0-step,x0+step 45 boxlo = boxlo.clip(lo, max(boxlo)) 46 boxhi = boxhi.clip(min(boxhi), hi) 47 delta = boxhi-boxlo 48 49 # Generate a random population within that box, including the initial 50 # value if elitism is true 51 P = numpy.random.rand(size,len(pars))*delta+boxlo 52 if elitism: 53 P[0] = x0 54 55 return P
56
57 -def test():
58 inf = numpy.inf 59 class P: 60 def __init__(self, value, range): 61 self.value,self.range = value,range
62 def __repr__(self): 63 return "P(%s in [%s, %s])"%(self.value, self.range[0], self.range[1]) 64 # Bounded tests 65 pop = populate(10, [P(1,[0,3]),P(2,[0,3]),P(3,[2,4])]) 66 #print pop 67 assert (2 <= pop[:,2]).all() and (pop[:,2] <= 4).all() 68 assert pop.shape[0] == 10 and pop.shape[1] == 3 69 assert pop[0,2] == 3 # elitism 70 # Unbounded tests 71 pop = populate(10, [P(2,[-inf, 3]), P(5,[3,inf]), 72 P(2,[-inf, inf]), P(-2,[-inf,inf]), 73 P(0,[-inf,inf])]) 74 #print pop 75 assert (0 <= pop[:,0]).all() and (pop[:,0] <= 3).all() 76 assert (3 <= pop[:,1]).all() and (pop[:,1] <= 10).all() 77 assert (0 <= pop[:,2]).all() and (pop[:,2] <= 4).all() 78 assert (-4 <= pop[:,3]).all() and (pop[:,3] <= 0).all() 79 assert (-1 <= pop[:,4]).all() and (pop[:,4] <= 1).all() 80 81 82 if __name__ == "__main__": test() 83