dan mackinlay committed 4337939

bulk-interrogate trials now

Comments (0)

Files changed (1)

     'n_branches': 100,
-def sweep_branched_experiment(sweepables=None, base_params=DEFAULT_TRIAL_PARAMS, oversample=1, start_seed=10000):
+def swept_experiment(sweepables=None, base_params=DEFAULT_TRIAL_PARAMS, oversample=1, start_seed=10000, n_pairs=10):
     sweepables = sweepables or {} #cast to empty dict
     swept_names = sweepables.keys()
     swept_iterables = [sweepables[name] for name in swept_names]
-    trials = []
+    estimates = []
     seed = start_seed
     for swept_values in itertools.product(*swept_iterables):
         these_params = base_params.copy()
         these_params.update(zip(swept_names, swept_values))
         for sample_i in xrange(oversample):
-            trials.append(branched_flocking_experiment(these_params, seed=seed))
+            trial = branched_trial(
+                these_params,
+                seed=seed
+            )
+            estimates.append((
+                trial[0].params,
+                analyse_branched_trial(
+                    trial,
+                    n_pairs=n_pairs
+                )
+            ))
             seed = abs(hash(str(5))) #start seed in very different places next time
-    return trials
+    return estimates
-def branched_flocking_experiment(base_params=DEFAULT_TRIAL_PARAMS, seed=1):
+def branched_trial(base_params=DEFAULT_TRIAL_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(base_params), steps=base_params['discard_steps'], seed=seed)
+    base_simstate = do_sim(basic_flock_factory(base_params), steps=base_params['discard_steps'], seed=seed)
     #the sim might decorate the params dict with additional stuff. mostly the seed, i suppose.
     base_params = base_simstate.params
     #since we are branching, we store the original seed in 'base_seed' and keep 'seed' for most recent seed
     # should seeds have a separate data structure for clarity?
     base_params['base_seed'] = seed
     return [
-        do_flocking_sim(base_simstate, steps=base_params['branch_steps'], seed=seed+i+1)
+        do_sim(base_simstate, steps=base_params['branch_steps'], seed=seed+i+1)
         for i in xrange(base_params['n_branches'])
-def do_flocking_sim(simstate, steps=100, seed=1):
+def do_sim(simstate, steps=100, seed=1):
     Starting from the state in *simstate*, iterate the simulation *steps* times with different seeds.
     params = simstate.params
     #update seed to reflect the most recent seed used. I suppose that's kind of variable overloading.
+    #some cleaner method would be wise.
     params['seed'] = seed
     locs = simstate.locs
     vels = simstate.vels
         vels = normalise_lengths(sp_neighbours * vels)
         #Step 2: perturb, normalise:
         vels = normalise_lengths(vels * (1-params['noise']) + random_unit_vectors(params) * params['noise'])
         #boundary conditions?
         locs = fract(locs + params['dt'] * vels)
     simstate.locs = locs
     simstate.vels = vels
     return simstate        
-def analyse_branched_experiment(branches, n_pairs=10):
-    """Take a list of stacked trials and analyse them."""
-    #I'm punting I can ignore most of the state vector. Anyway, they'll be fiddly.
+def analyse_branched_trial(branches, n_pairs=10):
+    """Take a list of trials and analyse them."""
+    #I'm punting I can ignore most of the state vector, e.g. locs.
     # stacked_vels = np.dstack([b.vels for b in branches])
-    #In fact, do we really need multiple axes of info? Nah.
+    #In fact, do we really need multiple axes of info for vels? Nah.
     stacked_vels = np.vstack([b.vels[:,0] for b in branches])
     n_agents = stacked_vels.shape[0]
     # Now, we estimate distributions of projected velocity in order to, in turn, estimate mean
 class SimState(object):
     """A holder for some simulation state.
-    TODO: ensure that params is always copied by value."""
+    Copy using the clone method to avoid that damn mutable state dictionary giving you problems."""
     params = None
     statevars = ['vels', 'locs']
     def __init__(self, params):
         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 so that branching thing works without trampling state."""
+        but with params dict copied so that branching thing works without trampling state."""
         clone = self.__class__(self.params.copy())
         for name in self.statevars:
             setattr(clone, name, getattr(self, name))