Commits

dan mackinlay committed 3ab5478

branched simulations go

  • Participants
  • Parent commits 5c2d15a

Comments (0)

Files changed (1)

 """
 flock.py
 
-Created by dan mackinlay on 2010-10-18.
-Copyright (c) 2010 __MyCompanyName__. All rights reserved.
+Created by dan mackinlay on 2012-09-12.
 
->>> simstate = do_flocking_sim(basic_flock_factory(DEFAULT_PARAMS))
+TODO:
+consider calculating MI between relative axial positions of pairs of particles, which also might work.
+(As we have no reason to suppose that MI is "concentrated" in one part of the state vector,
+and avial positions are quicker to calculate, AND don't have as much additional noise)
+
 """
 from __future__ import division
 
     'dt': 0.01,
     'noise': 0.2,
     'radius': 0.05,
+    'discard_steps': 100,
+    'branch_steps': 1,
+    'num_branches': 100,
 }
 
 class SimState(object):
-    "A holder for some simulation state."
+    """A holder for some simulation state.
+    TODO: ensure that params is always copied by value."""
     params = None
+    statevars = ['vels', 'locs']
     def __init__(self, params):
-        self.params = params.copy()
+        self.params = params.copy()        
+    def clone(self):
+        """make a new copy of me with arrays pointing to the same memory locations
+        but with params dict cloned."""
+        clone = self.__class__(self.params.copy())
+        for name in self.statevars:
+            setattr(clone, name, getattr(self, name))
+        return clone
 
 def basic_flock_factory(params):
+    """Initialise a sim with basic random state."""
     sim = SimState(params=params)
     sim.locs = np.random.uniform(size=(params['num_agents'], 2))
     sim.vels = random_unit_vectors(params)
     return sim    
 
-def do_flocking_sim(simstate, steps=100, seed=None):
-    simstate = copy(simstate)
+def do_flocking_sim(simstate, steps=100, seed=1):
+    """
+    Starting from the state in *simstate*, iterate the simulation *steps* times.
+    """
+    simstate = simstate.clone()
     params = simstate.params
+    np.random.seed(seed)
+    #update seed to reflect the most recent seed used. I suppose that's kind of variable overloading.
+    params['seed'] = seed
     locs = simstate.locs
     vels = simstate.vels
     for step in xrange(steps):
     simstate.vels = vels
     return simstate        
 
+def branched_flocking_experiment(params=DEFAULT_PARAMS, seed=1):
+    """
+    Run a sim, stop it after a number of iterations.
+    Then run alternate versions with a given seed, keeping the results.
+    """
+    base_simstate = do_flocking_sim(basic_flock_factory(params), steps=params['discard_steps'], seed=seed)
+    base_simstate.params['base_seed'] = seed
+    return [
+        do_flocking_sim(base_simstate, steps=params['branch_steps'], seed=seed+i)
+        for i in xrange(params['num_branches'])
+    ]
+
 def normalise_lengths(row_vectors):
     """normalise the lengths of some stacked row vectors.
     """