[Scipy-svn] r3269 - trunk/scipy/sandbox/ga

scipy-svn@scip... scipy-svn@scip...
Mon Aug 27 17:18:03 CDT 2007


Author: rkern
Date: 2007-08-27 17:18:00 -0500 (Mon, 27 Aug 2007)
New Revision: 3269

Added:
   trunk/scipy/sandbox/ga/prng.py
Modified:
   trunk/scipy/sandbox/ga/algorithm.py
   trunk/scipy/sandbox/ga/examples.py
   trunk/scipy/sandbox/ga/ga_gnm.py
   trunk/scipy/sandbox/ga/ga_list.py
   trunk/scipy/sandbox/ga/ga_util.py
   trunk/scipy/sandbox/ga/gene.py
   trunk/scipy/sandbox/ga/genome.py
   trunk/scipy/sandbox/ga/info_ga.py
   trunk/scipy/sandbox/ga/language.py
   trunk/scipy/sandbox/ga/parallel_pop.py
   trunk/scipy/sandbox/ga/population.py
   trunk/scipy/sandbox/ga/scaling.py
   trunk/scipy/sandbox/ga/selection.py
   trunk/scipy/sandbox/ga/tree.py
   trunk/scipy/sandbox/ga/tree_opt.py
Log:
Updated most of the things in the GA package that looked like they needed to be updated. It has not been tested, so it probably doesn't all work, yet. If anyone wants to bang on it, please do so.

Modified: trunk/scipy/sandbox/ga/algorithm.py
===================================================================
--- trunk/scipy/sandbox/ga/algorithm.py	2007-08-27 20:12:57 UTC (rev 3268)
+++ trunk/scipy/sandbox/ga/algorithm.py	2007-08-27 22:18:00 UTC (rev 3269)
@@ -1,74 +1,84 @@
-from ga_util import *
-import scipy.stats as stats
-rv = stats
-#import scipy.io.dumb_shelve
-import string
-import os, sys
-import time, pprint, types,copy
+import copy
 import dumbdbm
-#import thread, sync
+import pprint
+import sys
+import time
+
+from ga_util import flip_coin, my_mean, my_std
+from prng import prng
+
+
 if sys.platform != 'win32':
-    import fcntl
     timer = time.clock      #clock behaves differently work on linux
 else:
     timer = time.time
 
 dberror = dumbdbm.error
 
-def max_score(pop): return max(map(lambda x: x.score(),pop))
+def max_score(pop):
+    """ Find the maximum score in a population.
+    """
+    return max([x.score() for x in pop])
 
-class galg:
-    """A basic genetic algorithm.  The genetic algorithm is responsible
-       for evolving a population of genomes.  While the population and
-       the genomes are in charge of defining most of the genetic operators
-       such as selection, scaling, mutation, and crossover, it is the
-       genetic algorithm class that orchestrates the evolution and calls
-       the operators in the correct order.  Most of the work is done
-       in the **step()** method.
+class galg(object):
+    """ A basic genetic algorithm.
+
+    The genetic algorithm is responsible for evolving a population of genomes.
+    While the population and the genomes are in charge of defining most of the
+    genetic operators such as selection, scaling, mutation, and crossover, it is
+    the genetic algorithm class that orchestrates the evolution and calls the
+    operators in the correct order.  Most of the work is done in the **step()**
+    method.
     """
-    valid_settings = ['pop_size','p_replace',
-                            'p_cross', 'p_mutate','p_deviation',
-                            'gens','rand_seed','rand_alg','dbase','update_rate']
-    output_settings = ['crossover','selector', 'scaler','genome_type']
-    default_settings = {'pop_size':150,'p_replace':.8,
-                            'p_cross': .8, 'p_mutate':'gene',
-                            'p_deviation': 0.,'gens':35,
-                            'rand_seed':0,'rand_alg':'CMRG',
-                            'update_rate': 10000,'dbase':''}
+    valid_settings = ['pop_size', 'p_replace', 'p_cross', 'p_mutate',
+        'p_deviation', 'gens', 'rand_seed', 'dbase', 'update_rate']
+    output_settings = ['crossover', 'selector', 'scaler', 'genome_type']
+    default_settings = dict(
+        pop_size = 150,
+        p_replace = .8,
+        p_cross = .8,
+        p_mutate = 'gene',
+        p_deviation = 0.,
+        gens = 35,
+        rand_seed = 0,
+        update_rate = 10000,
+        dbase = '',
+    )
     default_verbose = 1
 
-    def __init__(self,pop):
+    def __init__(self, pop):
         self.verbose = self.default_verbose
         self.settings = copy.copy(galg.default_settings)
         self.pop = pop
-    def test_settings(self,settings):
+
+    def test_settings(self, settings):
+        """ Check that a settings dictionary is consistent with the settings
+        that we can accept.
+        """
         for key in settings.keys():
-            try:
-                self.output_settings.index(key)
+            if key in self.output_settings:
                 print 'Warning: The key "%s" in settings is readonly.' % key
-            except ValueError:
-                try: self.valid_settings.index(key)
-                except ValueError:
-                    print 'Warning: The key "%s" in not a valid setting.' % key
-                    print 'The valid settings are %s' % self.valid_settings
+            elif key not in self.valid_settings:
+                print 'Warning: The key "%s" in not a valid setting.' % key
+                print 'The valid settings are %s' % self.valid_settings
 
-    def initialize(self,reseed = 1):
+    def initialize(self, reseed=True):
         b = timer()
         self.test_settings(self.settings)
         self.gen = 0
-        sd = self.settings['rand_seed']; alg = self.settings['rand_alg']
-        if reseed: rv.initialize(seed = sd, algorithm = alg)
-        self.settings['seed_used'] = rv.initial_seed()
+        sd = self.settings['rand_seed']
+        if reseed:
+            prng.seed(sd)
+        self.settings['seed_used'] = sd
         self._print('initializing... seed = %d' % self.settings['seed_used'])
         self.crossover = self.pop.model_genome.crossover # get the crossover op from the first genome
         self.pop.settings = self.settings #should these be shared?
         self.size_pop(self.settings['pop_size'])
 
-        self.settings['crossover'] = string.split(str(self.crossover))[0][1:]
-        self.settings['selector'] = string.split(str(self.pop.selector))[0][1:]
-        self.settings['scaler'] = string.split(str(self.pop.scaler))[0][1:]
-        self.settings['genome_type'] = string.split(str(self.pop.model_genome))[0][1:]
-#               self._print(self.settings)
+        self.settings['crossover'] = str(self.crossover).split()[0][1:]
+        self.settings['selector'] = str(self.pop.selector).split()[0][1:]
+        self.settings['scaler'] = str(self.pop.scaler).split()[0][1:]
+        self.settings['genome_type'] = str(self.pop.model_genome).split()[0][1:]
 
         self.pop.initialize(self.settings);
         self.stats = {'selections':0,'crossovers':0,'mutations':0,
@@ -76,11 +86,16 @@
         self.stats.update(self.pop.stats)
         self.step_time = timer() - b
         self.init_dbase()
-    def size_pop(self,s):
+
+    def size_pop(self, s):
+        """ Set the size of the population.
+        """
         self.settings['pop_size'] = s
         self.pop._size(s)
 
-    def step(self,steps=1):
+    def step(self, steps=1):
+        """ Perform a number of steps.
+        """
         sz = len(self.pop)
         replace = int(self.settings['p_replace'] * len(self.pop))
         p_crossover = self.settings['p_cross']
@@ -139,6 +154,7 @@
         self.post_evolve()
         self.db_entry['run_time'] = timer() - b
         self.write_dbase()
+
     def iteration_output(self):
         output = ( 'gen: ' + `self.gen` + ' '
                  + 'max: ' + `self.stats['current']['max']`  + ' '
@@ -164,7 +180,7 @@
         self.db_entry['best_scores'] = [self.stats['current']['max']]
         self.db_entry['stats'] = [copy.deepcopy(self.stats)]
         self.db_entry['step_time'] = [self.step_time]
-        self.db_entry['optimization_type'] = string.split(str(self.__class__))[0][1:]
+        self.db_entry['optimization_type'] = str(self.__class__).split()[0][1:]
 
     def update_dbase(self):
 #               self.db_entry['best_scores'].append(self.pop.best().score())
@@ -178,50 +194,56 @@
            On NT, hopefully we're using the gdbm module which does automatic
            file locking.
         """
-        if(self.settings['dbase'] != ''):
-            fname= self.settings['dbase']
-            try:
-                if sys.platform == 'win32': pass
-                else:
-                    f = open(fname +'.lock','a')
-                    fcntl.flock(f.fileno(),fcntl.LOCK_EX)
-                try:
-                    try: db = my_shelve.open(fname,'w')
-                    except dberror: db = my_shelve.open(fname,'c')
-                    keys = db.keys()
-                    if(len(keys) == 0): self.dbkey = `1`
-                    else:
-                        gkeys=[]
-                        for k in keys:
-                            try: gkeys.append(string.atoi(k))
-                            except ValueError: pass
-                        self.dbkey = `max(gkeys)+1`
-                    print 'DB NAME: ', self.settings['dbase'], 'KEY: ', self.dbkey
-                    db[self.dbkey] = self.db_entry
-                    db.close()
-                except: pass #if an error occured, we still need to unlock the db
-                if sys.platform == 'win32': pass
-                else:
-                    fcntl.flock(f.fileno(),fcntl.LOCK_UN)
-                    f.close()
-            except:
-                if sys.platform == 'win32': pass
-                else:
-                    f = open('error.lock','a')
-                    f.write(os.environ['HOST'])
-                    f.close()
+        # XXX: broken. No my_shelve. Rewrite.
+        raise NotImplementedError
+#        if(self.settings['dbase'] != ''):
+#            fname= self.settings['dbase']
+#            try:
+#                if sys.platform == 'win32': pass
+#                else:
+#                    f = open(fname +'.lock','a')
+#                    fcntl.flock(f.fileno(),fcntl.LOCK_EX)
+#                try:
+#                    try: db = my_shelve.open(fname,'w')
+#                    except dberror: db = my_shelve.open(fname,'c')
+#                    keys = db.keys()
+#                    if(len(keys) == 0): self.dbkey = `1`
+#                    else:
+#                        gkeys=[]
+#                        for k in keys:
+#                            try: gkeys.append(string.atoi(k))
+#                            except ValueError: pass
+#                        self.dbkey = `max(gkeys)+1`
+#                    print 'DB NAME: ', self.settings['dbase'], 'KEY: ', self.dbkey
+#                    db[self.dbkey] = self.db_entry
+#                    db.close()
+#                except: pass #if an error occured, we still need to unlock the db
+#                if sys.platform == 'win32': pass
+#                else:
+#                    fcntl.flock(f.fileno(),fcntl.LOCK_UN)
+#                    f.close()
+#            except:
+#                if sys.platform == 'win32': pass
+#                else:
+#                    f = open('error.lock','a')
+#                    f.write(os.environ['HOST'])
+#                    f.close()
+#
+#        else:   "no dbase specified"
 
-        else:   "no dbase specified"
-
-    def _print(self,val, level = 1):
+    def _print(self, val, level=1):
         if(self.verbose >= level):
-            if type(val) == types.StringType: print val
+            if isinstance(val, basestring):
+                print val
             else:
                 pp = pprint.PrettyPrinter(indent=4)
                 pp.pprint(val)
 
 
     ALL = -1
+
+
+
 class m_galg(galg):
     valid_settings = galg.valid_settings + ['num_pops', 'migrants']
     default_settings = galg.default_settings
@@ -229,19 +251,21 @@
     default_settings['migrants'] = 2
 
     verbose = 1
+
     def __init__(self,pop):
         galg.__init__(self,pop)
 #               self.GAs = self.GAs + [galg(pop.clone())]
         self.settings = copy.copy(self.default_settings)
 
-    def initialize(self, mode = 'serial'):
+    def initialize(self, mode='serial', reseed=True):
         b = timer()
         #same as galg
         self.test_settings(self.settings)
         self.gen = 0
-        sd = self.settings['rand_seed']; alg = self.settings['rand_alg']
-        rv.initialize(seed = sd, algorithm = alg)
-        self.settings['seed_used'] = rv.initial_seed()
+        sd = self.settings['rand_seed']
+        if reseed:
+            prng.seed(sd)
+        self.settings['seed_used'] = sd
         self._print('initializing... seed = %d' % self.settings['seed_used'])
         self.crossover = self.pop[0].crossover # get the crossover op from the first genome
         self.pop.settings = self.settings
@@ -262,13 +286,14 @@
             self.GAs.append(galg(self.pop.clone()))
             self.GAs[i].settings = sub_ga_settings.copy()
 
-        self.settings['crossover'] = string.split(str(self.crossover))[0][1:]
-        self.settings['selector'] = string.split(str(self.pop.selector))[0][1:]
-        self.settings['scaler'] = string.split(str(self.pop.scaler))[0][1:]
-        self.settings['genome_type'] = string.split(str(self.pop.model_genome))[0][1:]
+        self.settings['crossover'] = str(self.crossover).split()[0][1:]
+        self.settings['selector'] = str(self.pop.selector).split()[0][1:]
+        self.settings['scaler'] = str(self.pop.scaler).split()[0][1:]
+        self.settings['genome_type'] = str(self.pop.model_genome).split()[0][1:]
         self._print(self.settings)
 
         if mode[0] == 'p' or mode[0] == 'P':
+            # XXX: what?
             """
                 sys.setcheckinterval(1000)
                 finished = sync.event()
@@ -279,7 +304,7 @@
                 sys.setcheckinterval(10)
                 """
         else:
-            for ga in self.GAs: ga.initialize(reseed = 0)
+            for ga in self.GAs: ga.initialize(reseed = False)
         cnt = 0
         for ga in self.GAs:
             self.pop[cnt] = ga.pop.best()
@@ -318,7 +343,7 @@
         try: self.pop.stats['overall']['min'] = min(self.pop.stats['overall']['min'],
                                                             self.pop.stats['current']['min'])
         except KeyError: self.pop.stats['overall']['min'] = self.pop.stats['current']['min']
-        self.pop.stats
+        self.pop.stats  # XXX: Is this a no-op?
         self.pop.stats['pop_evals'] = self.GAs[0].stats['pop_evals']
         self.stats.update(self.pop.stats)
 
@@ -417,7 +442,7 @@
 
 def GA_initializer(bar,finished,GA):
         t1 = timer()
-        GA.initialize(reseed = 0)
+        GA.initialize(reseed = False)
         t2 = timer()
         print 'thread ' + `thread.get_ident()` + 'time ' + `t2-t1` + ' sec.'
         bar.enter()

Modified: trunk/scipy/sandbox/ga/examples.py
===================================================================
--- trunk/scipy/sandbox/ga/examples.py	2007-08-27 20:12:57 UTC (rev 3268)
+++ trunk/scipy/sandbox/ga/examples.py	2007-08-27 22:18:00 UTC (rev 3269)
@@ -54,8 +54,15 @@
     #
     galg = ga.algorithm.galg(pop)
     # change a few settings
-    settings = {'pop_size':250,'p_replace':.8,'p_cross': .8, 'p_mutate':'gene',
-                'p_deviation': 0.,'gens':35,'rand_seed':0,'rand_alg':'CMRG'}
+    settings = dict(
+        pop_size = 250,
+        p_replace = .8,
+        p_cross = .8,
+        p_mutate = 'gene',
+        p_deviation = 0.,
+        gens = 35,
+        rand_seed = 0,
+    )
     galg.settings.update(settings)
     galg.evolve()
     print galg.pop.best()

Modified: trunk/scipy/sandbox/ga/ga_gnm.py
===================================================================
--- trunk/scipy/sandbox/ga/ga_gnm.py	2007-08-27 20:12:57 UTC (rev 3268)
+++ trunk/scipy/sandbox/ga/ga_gnm.py	2007-08-27 22:18:00 UTC (rev 3269)
@@ -1,115 +1,62 @@
 """
-
 This module adds gradient optimization capabilities to the
-
 standard genomes.  Basically this means that any problem set up
-
 for a GA is automatically able to be gradient optimized...
 
-
-
 For purity sake, the grad and genome
-
 modules have been left totally separate.  It might have
-
 been just as easy to derive genomes directly from
-
 grad.grad - and maybe that will happen in the future.
 
-
-
 Caveats:
+    This has only be set up for list_genomes made up of floating point genes.
+    The tree_genomes just need to be recoded here translating the pick_numbers
+    functions from tree_opt.
 
-        This has only be set up for list_genomes made up of
-
-        floating point genes.  The tree_genomes just need to
-
-        be recoded here translating the pick_numbers functions
-
-        from tree_opt.
-
-
-
-        genomes of discrete variable genes should be able to work also.
-
+    Genomes of discrete variable genes should be able to work also.
 """
 
-
-
 import grad
-
 import genome
 
-
-
 class list_genome(genome.list_genome,grad.grad):
+    """ So far, grad_min, and grad_max only work for float_genes.
 
-    """ So far, grad_min, and grad_max only
-
-            work for float_genes.
-
             Test:
-
             #Test gradient optimization
-
             >>> import ga_gnm, gene
-
             >>> g = gene.float_gene((-1,1))
-
             >>> class simple_genome(ga_gnm.list_genome):
-
             ...             def performance(self):
-
             ...                     s = 0
-
             ...                     for i in self: s = s+ i
-
             ...                     return s
-
             >>> a = simple_genome(g.replicate(10))
-
             >>> a.initialize()
-
             >>> a.grad_opt(5)
-
             33
-
             >>> a
-
             [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
-
     """
 
     def grad_params(self):
-
         return self.get_values() # calls list__genome   get_values()
 
     def set_grad_params(self,x):
-
         self.set_values(x) # calls list__genome set_values()
 
     #do we really need this?
-
     def grad_len(self):
-
         return len(self)
 
     def grad_min(self):
-
         gmin = []
-
         for flt_gene in self:
-
             gmin.append(flt_gene.bounds[0])
-
         return gmin
 
     def grad_max(self):
-
         gmax = []
-
         for flt_gene in self:
-
             gmax.append(flt_gene.bounds[1])
-
         return gmax

Modified: trunk/scipy/sandbox/ga/ga_list.py
===================================================================
--- trunk/scipy/sandbox/ga/ga_list.py	2007-08-27 20:12:57 UTC (rev 3268)
+++ trunk/scipy/sandbox/ga/ga_list.py	2007-08-27 22:18:00 UTC (rev 3269)
@@ -1,6 +1,5 @@
-from ga_util import *
+from ga_util import shallow_clone
 import UserList
-import copy
 
 class ga_list(UserList.UserList):
     def data_clone(self):

Modified: trunk/scipy/sandbox/ga/ga_util.py
===================================================================
--- trunk/scipy/sandbox/ga/ga_util.py	2007-08-27 20:12:57 UTC (rev 3268)
+++ trunk/scipy/sandbox/ga/ga_util.py	2007-08-27 22:18:00 UTC (rev 3269)
@@ -1,61 +1,61 @@
-#base definitions for genetic algorithms
-import scipy.stats as rv
-stats = rv
+""" Basic utilities for the GA package.
+"""
 
-GAError = 'GA Error'
+from numpy import mean, std
 
-def nop(x): return x
-def flip_coin(p): return (rv.random() < p)
+from prng import prng
 
-import random
 
-def flip_coin2(p): return (random.random() < p)
-class empty_class: pass
+class GAError(Exception):
+    """ Error from the GA code.
+    """
 
+def nop(x):
+    """ Basic 'no-op' stub useful for interfaces which require a function.
+    """
+    return x
+
+def flip_coin(p):
+    """ Return True with probability p.
+    """
+    return (prng.random() < p)
+
+class empty_class:
+    """ Dummy class for cloning objects.
+    """
+    pass
+
 def shallow_clone(item):
+    """ Make a simple clone of an object.
+
+    The attributes are not copied, just referenced.
+    """
     new = empty_class()
     new.__class__ = item.__class__
     new.__dict__.update(item.__dict__)
     return new
-#these are exacly correct, but htey prevent problems with -Inf and Inf
+
+def remove_NaN(z):
+    """ Return an array with only finite (non-NaN, non-inf) values.
+    """
+    from numpy import isfinite
+    return z[isfinite(z)]
+
 def my_std(s):
-#       try:
+    """ Standard deviation robust to NaNs and infs.
+    """
     a = remove_NaN(s)
-    if len(a) > 1: return stats.std(a)
-    else: return 0.
-#       except:
-#               import pdb
-#               pdb.set_trace()
+    if len(a) > 1:
+        return std(a)
+    else:
+        return 0.
+
 def my_mean(s):
+    """ Mean robust to NaNs and infs.
+    """
     a = remove_NaN(s)
-    if len(a) > 1: return stats.mean(a)
-    else: return 0.
+    if len(a) > 0:
+        return mean(a)
+    else:
+        return 0.
 
-def testflip():
-
-    import time
-    b = time.clock()
-    for i in range(10000): a = flip_coin(.5)
-    e = time.clock()
-    print 'rv_flip',e-b
-    b = time.clock()
-    for i in range(10000): a = flip_coin2(.5)
-    e = time.clock()
-    print 'wh_flip',e-b
-    from rv import random
-    b = time.clock()
-    for i in range(10000):
-        a = random() < .5
-    e = time.clock()
-    print 'rv',e-b
-    from random import random
-    b = time.clock()
-    for i in range(10000):
-        a = random() < .5
-    e = time.clock()
-    print 'wh',e-b
-
-
-def remove_NaN(z):
-    from numpy import isnan, isinf, compress, logical_not
-    return compress(logical_not( isnan(z)+isinf(z)),z,axis=-1)

Modified: trunk/scipy/sandbox/ga/gene.py
===================================================================
--- trunk/scipy/sandbox/ga/gene.py	2007-08-27 20:12:57 UTC (rev 3268)
+++ trunk/scipy/sandbox/ga/gene.py	2007-08-27 22:18:00 UTC (rev 3269)
@@ -12,14 +12,15 @@
 12/31/98 documentation added ej
 """
 
-from ga_util import *
-import scipy.stats as rv
-from random import random
-from numpy import *
-import copy
-from scipy.ga.tree import tree_node
+from numpy import array, log10
 
-class gene:
+from tree import tree_node
+from ga_util import GAError, nop, shallow_clone
+from prng import prng
+
+
+
+class gene(object):
     """
     Genes are the most basic building block in this genetic algorithm library.
     A gene represents a particular trait of an individual solution.  The gene class
@@ -61,20 +62,27 @@
     mutator = None
     initializer = None
     is_gene = 1
+
     def clone(self):
-        """Makes a shallow copy of the object.  override if you need more specialized behavior
+        """ Makes a shallow copy of the object.
+        
+        Override if you need more specialized behavior.
         """
         return shallow_clone(self)
-    def replicate(self,cnt):
-        """Returns a list with cnt copies of this object in it
+
+    def replicate(self, count):
+        """ Returns a list with count copies of this object in it.
         """
-        return map(lambda x: x.clone(),[self]*cnt)
+        return map(lambda x: x.clone(),[self]*count)
+
     def initialize(self):
-        """Calls the initializer objects evaluate() function to initialize the gene
+        """ Calls the initializer objects evaluate() function to initialize the
+        gene.
         """
         self._value = self.initializer.evaluate(self)
         return self.value()
-    def set_mutation(self,mrate):
+
+    def set_mutation(self, mrate):
         """
         Set the mutation rate of the gene.
 
@@ -90,7 +98,7 @@
             try: del self.mutation_rate #remove local mrates and use gene classes mrate
             except AttributeError: pass
         elif(mrate=='adapt'):
-            self.mutation_rate = rv.uniform(self.mr_bounds[0],self.mr_bounds[1])[0]
+            self.mutation_rate = prng.uniform(self.mr_bounds[0], self.mr_bounds[1])
         else:
             self.__class__.mutation_rate = mrate
 
@@ -102,7 +110,7 @@
             mutation_rate of the time. Otherwise, it does nothing.
         """
         #inlined 'flip_coin' for speed
-        if random() < self.mutation_rate:
+        if prng.random() < self.mutation_rate:
             self._value = self.mutator.evaluate(self)
             return 1
         return 0
@@ -152,15 +160,16 @@
         except AttributeError: v2 = other
         return cmp(v1,v2)
 
-class list_gene_uniform_mutator:
+class list_gene_uniform_mutator(object):
     """
     This class randomly chooses a new gene value from the allele set
     in a list_gene.  It is also useful as an initializer for list_gene.
     """
     def evaluate(self,gene):
         """ return a randomly chosen value from the genes allele set """
-        return rv.choice(gene.allele_set)
-class list_gene_gaussian_mutator:
+        return prng.choice(gene.allele_set)
+
+class list_gene_gaussian_mutator(object):
     """
     This class chooses a new gene value from the allele set
     in a list_gene.  The new value is chosen from a gaussian
@@ -195,12 +204,12 @@
         old = gene.index()
         new = -1; f = -1
         while not (0 <= new < size):
-            f = rv.norm.rvs(old,w)[0]
+            f = prng.normal(old,w)
             new = round(f)
             if(old == new and f > new): new = new + 1
             if(old == new and f < new): new = new - 1
         return gene.allele_set[int(new)]
-class list_gene_walk_mutator:
+class list_gene_walk_mutator(object):
     """
       This class chooses a new gene value from the allele set
       in a list_gene.  The newly chosen value is +/-1 element
@@ -209,7 +218,7 @@
     """
     def evaluate(self,gene):
         old = gene.index()
-        move = rv.choice((-1,1))
+        move = prng.choice((-1,1))
         return gene.allele_set[old + move]
 
 class list_gene(gene):
@@ -243,17 +252,19 @@
     and resistor values during evaluation
     """
     func = nop
-    def value(self): return func(self._value)
-    def __repr__(self): return `self._value` #???
+    def value(self): 
+        return self.func(self._value)
+    def __repr__(self):
+        return repr(self._value) #???
 
-class float_gene_uniform_mutator:
+class float_gene_uniform_mutator(object):
     """ randomly choose a value within the float_gene's bounds"""
     def evaluate(self,gene):
         bounds=gene.bounds
-        new =rv.uniform(bounds[0], bounds[1]-bounds[0] ).rvs()[0]
+        new = prng.uniform(bounds[0], bounds[1]-bounds[0])
         return new
 
-class float_gene_gaussian_mutator:
+class float_gene_gaussian_mutator(object):
     """
     chooses a new value for a float_gene with gaussian
     shaped distribution around the current value.
@@ -271,10 +282,10 @@
         dev = (gene.bounds[1]-gene.bounds[0]) * self.dev_width
         new = gene.bounds[1]
 #       while not (gene.bounds[0] <= new < gene.bounds[1]):
-#           new = rv.norm.rvs(gene.value(),dev)[0]
-#       new = rv.norm(gene.value(),dev)[0]
+#           new = prng.normal(gene.value(),dev)
+#       new = prng.normal(gene.value(),dev)
         #get the _value explicitly so mutator will work for log_float also
-        new = rv.norm.rvs(gene._value,dev)[0]
+        new = prng.normal(gene._value,dev)
         if new > gene.bounds[1]: new = gene.bounds[1]
         if new < gene.bounds[0]: new = gene.bounds[0]
         return new
@@ -313,7 +324,7 @@
         try: return 10.**(self._value)
         except AttributeError: raise GAError, 'gene not initialized'
 
-class frozen:
+class frozen(object):
     """frozen is a gene that always maintains the same value.
     """
     def __init__(self,val): self._value = val
@@ -370,7 +381,7 @@
             try: del self.mutation_rate #remove local mrates and use gene classes mrate
             except AttributeError: pass
         elif(mrate=='adapt'):
-            self.mutation_rate = rv.uniform(self.mr_bounds[0],self.mr_bounds[1])[0]
+            self.mutation_rate = prng.uniform(self.mr_bounds[0],self.mr_bounds[1])
         else:
             self.__class__.mutation_rate = mrate
         for child in self._children: child.set_mutation(mrate)

Modified: trunk/scipy/sandbox/ga/genome.py
===================================================================
--- trunk/scipy/sandbox/ga/genome.py	2007-08-27 20:12:57 UTC (rev 3268)
+++ trunk/scipy/sandbox/ga/genome.py	2007-08-27 22:18:00 UTC (rev 3269)
@@ -14,18 +14,20 @@
 it an evaluator class and you are in business.
 """
 
-from ga_util import *
-import scipy.stats as rv
-import Numeric, copy
-import tree
+from numpy import array
 
-class default_evaluator:
+from ga_util import GAError, shallow_clone
+import language
+from prng import prng
+
+
+class default_evaluator(object):
     """ This default evaluator class just reminds you to define your own. """
     def evaluate(self,genome):
         return genome.performance() #if a performance() method is available, use it!
         #raise GAError, 'objective must be specified'
 
-class genome:
+class genome(object):
     """
     The class genome is used as the base class for genome classes that you
     use in your program.  It should not be used directly.  In particular, the **clone()**
@@ -140,7 +142,7 @@
         """
         return 1
 
-class list_genome_default_initializer:
+class list_genome_default_initializer(object):
     """ The evaluate() function for this class simply calls the **initialize()**
         function for each gene in the **list_genome**.
     """
@@ -148,7 +150,7 @@
         for gene in genome: gene.initialize()
     def __call__(self,genome): return self.evaluate(genome)
 
-class list_genome_default_mutator:
+class list_genome_default_mutator(object):
     """ The evaluate() function for this class simply calls the **mutate()**
         function for each gene in the **list_genome**. It returns 1 if
         any of the genes were mutated
@@ -159,14 +161,14 @@
         return mutated
     def __call__(self,genome): return self.evaluate(genome)
 
-class list_genome_singlepoint_crossover:
+class list_genome_singlepoint_crossover(object):
     def evaluate(self,parents):
         #assume mom and dad are the same length
         mom = parents[0]; dad = parents[1]
         if(len(mom) > 1):
-            crosspoint = rv.randint(1,len(mom)-1).rvs()[0]
+            crosspoint = prng.randint(1,len(mom)-1).rvs()
         else:
-            crosspoint = rv.randint(0,len(mom)).rvs()[0]
+            crosspoint = prng.randint(0,len(mom)).rvs()
         brother = (mom[:crosspoint] + dad[crosspoint:]).clone()
         sister = (dad[:crosspoint] + mom[crosspoint:]).clone()
         return brother, sister
@@ -224,7 +226,7 @@
         """Most of the time, the genes in this genome specify numeric parameters.
            This method returns the values of the genes in an array (NumPy)
         """
-        return Numeric.array(self.get_values())
+        return array(self.get_values())
     def set_values(self,x):
         """ Set the values of the genes
         """
@@ -248,7 +250,7 @@
 def dict_choice(dict):
     tot = 0
     for key in dict.keys(): tot = tot + len(dict[key])
-    index = rv.choice(xrange(0,tot))
+    index = prng.choice(xrange(0,tot))
     for key in dict.keys():
         if index >= len(dict[key]):
             index = index - len(dict[key])
@@ -265,7 +267,7 @@
 
 SymbolError = 'SymbolError'
 NoneError = 'NoneError'
-class tree_crossover:
+class tree_crossover(object):
     cross_rejects = ['ST']
     def __init__(self):
         self.cross_point = {}
@@ -320,7 +322,7 @@
                 msg = "chosen symbol not found in dad (%s tries)" % `tries`
                 raise SymbolError, msg
             else: tried_sym.append(sym)
-        node_b = rv.choice(bro.symbol_table[sym])
+        node_b = prng.choice(bro.symbol_table[sym])
         idx = 0
         try:
             for child in node_a.get_parent().children():
@@ -346,12 +348,11 @@
         return sib1,sib2
     def __call__(self,genome): return self.evaluate(genome)
 
-import language
-class tree_genome_default_initializer:
+class tree_genome_default_initializer(object):
     def evaluate(self,genome): genome.generate()
     def __call__(self,genome): return self.evaluate(genome)
 
-class tree_genome_default_mutator:
+class tree_genome_default_mutator(object):
     def evaluate(self,genome): return genome.root.mutate()
     def __call__(self,genome): return self.evaluate(genome)
 
@@ -372,7 +373,9 @@
     def initialize(self,settings = None):
         genome.initialize(self,settings)
         if settings and settings.has_key('p_mutate'):
-            g.root.set_mutation(settings['p_mutate'])
+            raise NotImplementedError
+            # XXX: what is g?
+            #g.root.set_mutation(settings['p_mutate'])
     def defaultize(self):
         """ set the nodes to their default values"""
         if self.root is None:

Modified: trunk/scipy/sandbox/ga/info_ga.py
===================================================================
--- trunk/scipy/sandbox/ga/info_ga.py	2007-08-27 20:12:57 UTC (rev 3268)
+++ trunk/scipy/sandbox/ga/info_ga.py	2007-08-27 22:18:00 UTC (rev 3269)
@@ -4,4 +4,3 @@
 
 """
 
-postpone_import = 1

Modified: trunk/scipy/sandbox/ga/language.py
===================================================================
--- trunk/scipy/sandbox/ga/language.py	2007-08-27 20:12:57 UTC (rev 3268)
+++ trunk/scipy/sandbox/ga/language.py	2007-08-27 22:18:00 UTC (rev 3269)
@@ -1,13 +1,21 @@
 import types
-import  time
-from random import *
-SymbolError = 'Symbol Error'
-DepthError = 'Depth Error'
 
+from prng import prng
 
-class language:
+
+class SymbolError(Exception):
+    """ Error finding a symbol.
+    """
+
+class DepthError(Exception):
+    """ Tree tried to grow beyond the configured maximum depth.
+    """
+
+
+class language(object):
     max_depth = 20
     dont_cross = ['ST']  # dont perform crossovers at the start symbol node
+
     def __init__(self,lang):
         self.lang = lang
         self.dsc = 0
@@ -30,7 +38,7 @@
         new_active_node = active_node
         if type(cur_sym) == types.StringType:
             if self.lang.has_key(cur_sym):
-                rule = choice(self.lang[cur_sym])
+                rule = prng.choice(self.lang[cur_sym])
                 for sym in rule:
                     new_active_node = self._gen(sym,new_active_node,depth)
             else:

Modified: trunk/scipy/sandbox/ga/parallel_pop.py
===================================================================
--- trunk/scipy/sandbox/ga/parallel_pop.py	2007-08-27 20:12:57 UTC (rev 3268)
+++ trunk/scipy/sandbox/ga/parallel_pop.py	2007-08-27 22:18:00 UTC (rev 3269)
@@ -1,641 +1,334 @@
-from Numeric import *
 
-import sys, thread, sync
+import sync
+import sys
+import thread
+import time
 
+from numpy import arange, shape, zeros
 
-
 import remote_exec
-
 import population
 
 
-
-"""
-
 ######
-
-#I've got to lean up evaluate and initial in population so that
-
+#I've got to clean up evaluate and initial in population so that
 #the incorporation of the parallel stuff is smoother.
-
 ######
 
-"""
 
-import sys, thread, sync
-
-
-
 def array_round(x):
-
     y = zeros(shape(x))
-
     for i in range(len(x.flat)):
-
         y[i] = int(round(x[i]))
 
     return y
 
-
-
 def divide_list(l,sections):
-
     Ntot = len(l)
-
     Nsec = float(sections)
-
     Neach = Ntot/Nsec
-
     div_points = array_round(arange(0,Ntot,Neach)).tolist()
-
     if div_points[-1] != Ntot: div_points.append(Ntot)
-
     sub_pops = []
-
     st = div_points[0]
-
     for end in div_points[1:]:
-
         sub_pops.append(l[st:end])
-
         st = end
-
     return sub_pops
 
-
-
 class parallel_pop_initializer:
-
     def evaluate(self,pop,settings = None):
-
     #only send the individuals out that need evaluation
-
         if len(pop):
-
             Nserv = len(pop.server_list)
-
             groups = divide_list(pop,Nserv)
-
             sys.setcheckinterval(10)
-
             finished = sync.event()
-
             bar = sync.barrier(Nserv)
-
             print '************',len(groups), len(pop.server_list), len(pop)
-
             for i in range(len(groups)):
-
                 inputs = {'sub_pop':groups[i],'settings':settings, 'initializer':pop.initializer}
-
                 returns = ('sub_pop',)
-
                 code = 'initializer.evaluate(sub_pop,settings)'
-
                 data_pack = (inputs,returns,code)
-
                 server = pop.server_list[i]
-
                 thread.start_new_thread(remote_thread_init,(bar,finished,server,data_pack))
-
             finished.wait()
-
             sys.setcheckinterval(10)
 
 #what is this?                  for ind in pop: ind.evaluate(force)
 
 
-
 import cPickle
 
 def plen(obj): return len(cPickle.dumps(obj,1))
 
 
-
 class parallel_pop_evaluator:
-
     def evaluate(self,pop,force = 0):
-
-        import tree
-
+        #import tree
         #print '1',tree.ref()
-
         #only send the individuals out that need evaluation
-
         if force:
-
             _eval_list = pop.data
-
         else:
-
             _eval_list = filter(lambda x: not x.evaluated,pop)
-
         #print '2',tree.ref()
-
         eval_list = pop.clone()
-
         #print '3',tree.ref()
-
         eval_list.data = _eval_list
-
         if len(eval_list):
-
             Nserv = len(pop.server_list)
-
             groups = divide_list(eval_list,Nserv)
-
             #print '4',tree.ref()
-
             sys.setcheckinterval(10)
-
             finished = sync.event()
-
             bar = sync.barrier(Nserv)
-
             #print "EVAL LENGTH!!!", plen(pop.evaluator)
-
             gr = groups[0]
-
             print "GROUP LENGTH!!!", plen(groups[0]), len(gr),
-
             #print "IND!!!", plen(gr[0]),plen(gr[0].root)
-
             #print '4.5',tree.ref()
-
             for i in range(len(groups)):
-
                 inputs = {'sub_pop':groups[i], 'evaluator':pop.evaluator, 'force':force}
-
                 returns = ('sub_pop',)
-
                 code = 'evaluator.evaluate(sub_pop,force)'
-
                 data_pack = (inputs,returns,code)
-
                 server = pop.server_list[i]
-
                 thread.start_new_thread(remote_thread_eval,(bar,finished,server,data_pack))
-
             #print '7',tree.ref()
-
             finished.wait()
-
             sys.setcheckinterval(10)
-
 #what is this?                  for ind in pop: ind.evaluate(force)
-
     """
-
     def evaluate(self,pop,force = 0):
-
             #only send the individuals out that need evaluation
-
             _eval_list = filter(lambda x: not x.evaluated,pop)
-
             eval_list = pop.clone()
-
             eval_list.data = _eval_list
-
             if len(eval_list):
-
                     #finest grain possible
-
                     groups = divide_list(eval_list,len(eval_list))
-
                     finished = sync.event()
-
                     bar = sync.barrier(groups)
 
-
-
                     sys.setcheckinterval(10)
-
                     Nserv = len(pop.server_list)
-
                     idx = 0
-
                     while idx < len(groups):
-
                             inputs = {'sub_pop':groups[idx], 'evaluator':pop.evaluator}
-
                             returns = ('sub_pop',)
-
                             code = 'evaluator.evaluate(sub_pop)'
-
                             data_pack = (inputs,returns,code)
-
                             server = pop.server_list[i]
-
                             thread.start_new_thread(remote_thread_eval,(bar,finished,server,data_pack))
-
                     #for i in range(len(groups)):
-
                     #       inputs = {'sub_pop':groups[i], 'evaluator':pop.evaluator}
-
                     #       returns = ('sub_pop',)
-
                     #       code = 'evaluator.evaluate(sub_pop)'
-
                     #       data_pack = (inputs,returns,code)
-
                     #       server = pop.server_list[i]
-
                     #       thread.start_new_thread(remote_thread,(bar,finished,server,data_pack))
-
                     finished.wait()
-
                     sys.setcheckinterval(10)
-
 #what is this?                  for ind in pop: ind.evaluate(force)
-
     """
 
-
-
 def remote_thread_init(bar,finished,server,data_pack):
-
     try:
-
         remote = remote_exec.remote_exec(server[0],server[1],0,1)
-
         results = remote.run(data_pack)
-
         #assign the results from the returned data to the local individuals
-
         inputs = data_pack[0]
-
         old = inputs['sub_pop']
-
         new = results['sub_pop']
-
         for i in range(len(old)):
-
             old[i].__dict__.update(new[i].__dict__)
-
     except IndexError:
-
         print 'error in %s,%d' %  server
-
     bar.enter()
-
     finished.post()
 
-
-
 def remote_thread_eval(bar,finished,server,data_pack):
-
-    import tree
-
+    #import tree
     try:
-
         #print '5',tree.ref()
-
         remote = remote_exec.remote_exec(server[0],server[1],0,1)
-
         results = remote.run(data_pack)
-
         #print '6',tree.ref()
-
         #assign the results from the returned data to the local individuals
-
         inputs = data_pack[0]
-
         old = inputs['sub_pop']
-
         new = results['sub_pop']
-
         for gnm in new:
-
             gnm.root.delete_circulars()
-
             del gnm.root
-
         #print '6.25',tree.ref()
-
         for i in range(len(old)):
-
             old[i].__dict__.update(new[i].__dict__)
 
-
-
         #print '6.5',tree.ref()
-
     except IndexError:
-
         print 'error in %s,%d' %  server
-
     """
-
     import sys
-
     #r = new[0].root
-
     #print 'ref count',sys.getrefcount(r)
-
     #print '6.75',tree.ref()
-
     #Huh??? Why do I need to delete the new genomes
-
     #individually here?  Why aren't they garbage collected?
-
     indices = range(len(new))
-
     indices.reverse()
-
     for i in indices:
-
             del new[i]
-
     #print 'ref count',sys.getrefcount(r)
-
     #print '6.8',tree.ref()
-
     #r.delete_circulars()
-
     #print 'ref count',sys.getrefcount(r)
-
     #print '6.9',tree.ref()
-
     #del r
-
     #print '6.95',tree.ref()
-
     """
-
     bar.enter()
-
     finished.post()
 
-
-
 class ga_parallel_pop(population.population):
-
     parallel_evaluator = parallel_pop_evaluator()
-
     parallel_initializer = parallel_pop_initializer()
-
     def __init__(self,genome,size=1,server_list=None):
-
         """Arguments:
 
-
-
            genome -- a genome object.
-
            size -- number.  The population size.  The genome will be
-
                    replicated size times to fill the population.
-
            server_list -- a list of tuple pairs with machine names and
-
                           ports listed for the available servers
-
                           ex: [(ee.duke.edu,8000),('elsie.ee.duke.edu',8000)]
-
         """
-
         population.population.__init__(self,genome,size)
-
         assert(server_list)
-
         self.server_list = server_list
-
     def initialize(self,settings = None):
-
         """This method **must** be called before a genetic algorithm
-
            begins evolving the population.  It takes care of initializing
-
            the individual genomes, evaluating them, and scaling the population.
-
            It also clears and intializes the statistics for the population.
 
-
-
            Arguments:
 
-
-
            settings -- dictionary of genetic algorithm parameters.  These
-
                        are passed on to the genomes for initialization.
-
         """
-
         self.stats = {'current':{},'initial':{},'overall':{}}
-
         self.stats['ind_evals'] = 0
 
-
-
         print "beigninning genome generation"
-
         b = time.clock()
-
         self.parallel_initializer.evaluate(self,settings)
-
         e = time.clock()
-
         print "finished generation: ", e-b
-
         self.touch();
-
         b = time.clock()
-
         self.evaluate()
-
         e = time.clock()
-
         print "evaluation time: ", e-b
-
         self.scale()
-
         self.update_stats()
-
         self.stats['initial']['avg'] = self.stats['current']['avg']
-
         self.stats['initial']['max'] = self.stats['current']['max']
-
         self.stats['initial']['min'] = self.stats['current']['min']
-
         self.stats['initial']['dev'] = self.stats['current']['dev']
 
-
-
     def evaluate(self, force = 0):
-
         """ call the parallel_evaluator instead of the evaluator directly
-
         """
-
         self.selector.clear()
-
         self.parallel_evaluator.evaluate(self,force)
-
         #self.post_evaluate()
-
         #all of the remaining should be put in post eval...
-
         self.sort()
-
         #this is a cluge to get eval count to work correctly
-
         preval = self.stats['ind_evals']
-
         for ind in self:
-
             self.stats['ind_evals'] = self.stats['ind_evals'] + ind.evals
-
             ind.evals = 0
-
         print 'evals: ', self.stats['ind_evals'] - preval
-
         self.touch()
-
         self.evaluated = 1
 
-
-
 ########################## test stuff ############################
-
-import genome
-
-import gene
-
-import time
-
-
-
-import socket
-
-
-
-class objective:
-
-    def __init__(self,wait=.01):
-
-        self.wait = wait
-
-    def evaluate(self,genome):
-
-        time.sleep(self.wait)
-
-        return sum(genome.array(),axis=0)
-
-
-
-def test_pop(server_list,size=100,wait=.01):
-
-    obj = objective(wait)
-
-    the_gene = gene.float_gene((0,2.5))
-
-    genome = genome.list_genome(the_gene.replicate(5))
-
-    genome.evaluator = obj
-
-    pop = ga_parallel_pop(genome,size,server_list)
-
-    print  '########### awaiting evaluation#############'
-
-    pop.initialize()
-
-    print ' evaluation done!'
-
-    print 'best:', pop.best()
-
-    print 'worst',pop.worst()
-
-
-
-def gen_pop():
-
-    genome.list_genome.evaluator = objective()
-
-    gene = gene.float_gene((0,2.5))
-
-    genome = genome.list_genome(gene.replicate(5))
-
-    pop = ga_parallel_pop(genome,100,[(host,port),])
-
-    return pop
-
-
-
-    import parallel_pop,beowulf,os
-
-
-
-def test_pop2(server_list,size=100,wait=.01):
-
-    import hmm_gnm,os
-
-    genome = hmm_gnm.make_genome()
-
-    #pop = ga_parallel_pop(genome,4,server_list)
-
-    global galg
-
-    #genome.target = targets[0]
-
-    pop = ga_parallel_pop(genome,1,server_list)
-
-    galg = hmm_gnm.class_ga(pop)
-
-    galg.settings.update({ 'pop_size':6,'gens':2,'p_mutate':.03,
-
-                                'dbase':os.environ['HOME'] + '/all_lift3', 'p_cross':0.9, 'p_replace':.6,
-
-                                'p_deviation': -.001})
-
-    galg.evolve()
-
-
-
-    print  '########### awaiting evaluation#############'
-
-    pop.initialize()
-
-    print ' evaluation done!'
-
-    print 'best:', pop.best()
-
-    print 'worst',pop.worst()
-
-
-
-import thread
-
-def test():
-
-    host = socket.gethostname()
-
-    port = 8000
-
-    server_list = [(host,port),(host,port+1)]
-
-    for server in server_list:
-
-        host,port = server
-
-        thread.start_new_thread(remote_exec.server,(host,port))
-
-    thread.start_new_thread(test_pop2,(server_list,))
-
-
-
-def test2(machines=32,size=100,wait=.01):
-
-    import time
-
-    t1 = time.time()
-
-    #requires that servers are started on beowulf 1 and 2.
-
-    import beowulf
-
-    server_list = beowulf.beowulf.servers[:machines]
-
-    thread.start_new_thread(test_pop,(server_list,size,wait))
-
-    print 'total time:', time.time()-t1
+#import genome
+#import gene
+#import time
+#
+#import socket
+#
+#class objective:
+#    def __init__(self,wait=.01):
+#        self.wait = wait
+#    def evaluate(self,genome):
+#        time.sleep(self.wait)
+#        return sum(genome.array(),axis=0)
+#
+#def test_pop(server_list,size=100,wait=.01):
+#    obj = objective(wait)
+#    the_gene = gene.float_gene((0,2.5))
+#    genome_ = genome.list_genome(the_gene.replicate(5))
+#    genome_.evaluator = obj
+#    pop = ga_parallel_pop(genome_,size,server_list)
+#    print  '########### awaiting evaluation#############'
+#    pop.initialize()
+#    print ' evaluation done!'
+#    print 'best:', pop.best()
+#    print 'worst',pop.worst()
+#
+#
+#def gen_pop():
+#    genome.list_genome.evaluator = objective()
+#    gene = gene.float_gene((0,2.5))
+#    genome_ = genome.list_genome(gene.replicate(5))
+#    pop = ga_parallel_pop(genome_,100,[(host,port),])
+#    return pop
+#
+#import os
+#
+#import parallel_pop
+#
+#
+#def test_pop2(server_list,size=100,wait=.01):
+#    import hmm_gnm,os
+#    genome = hmm_gnm.make_genome()
+#    #pop = ga_parallel_pop(genome,4,server_list)
+#    global galg
+#    #genome.target = targets[0]
+#    pop = ga_parallel_pop(genome,1,server_list)
+#    galg = hmm_gnm.class_ga(pop)
+#    galg.settings.update({ 'pop_size':6,'gens':2,'p_mutate':.03,
+#                                'dbase':os.environ['HOME'] + '/all_lift3', 'p_cross':0.9, 'p_replace':.6,
+#                                'p_deviation': -.001})
+#    galg.evolve()
+#
+#    print  '########### awaiting evaluation#############'
+#    pop.initialize()
+#    print ' evaluation done!'
+#    print 'best:', pop.best()
+#    print 'worst',pop.worst()
+#
+#import thread
+#def test():
+#    host = socket.gethostname()
+#    port = 8000
+#    server_list = [(host,port),(host,port+1)]
+#    for server in server_list:
+#        host,port = server
+#        thread.start_new_thread(remote_exec.server,(host,port))
+#    thread.start_new_thread(test_pop2,(server_list,))
+#
+#def test2(machines=32,size=100,wait=.01):
+#    import time
+#    t1 = time.time()
+#    #requires that servers are started on beowulf 1 and 2.
+#    import beowulf
+#    server_list = beowulf.beowulf.servers[:machines]
+#    thread.start_new_thread(test_pop,(server_list,size,wait))
+#    print 'total time:', time.time()-t1

Modified: trunk/scipy/sandbox/ga/population.py
===================================================================
--- trunk/scipy/sandbox/ga/population.py	2007-08-27 20:12:57 UTC (rev 3268)
+++ trunk/scipy/sandbox/ga/population.py	2007-08-27 22:18:00 UTC (rev 3269)
@@ -1,30 +1,35 @@
 #genetic algorithm population
 #based on galib.
+import re
 import time
+
+from numpy import array
+
 import ga_list
-import re, copy
 import scaling
 import selection
-import Numeric
-import scipy.stats as stats
-from ga_util import *
-import pdb
+from ga_util import GAError, my_mean, my_std
 
+
 def ftn_minimize(x,y):
     """Minimization comparator for fitness (scaled score)."""
     return cmp(x.fitness(),y.fitness())
+
 def ftn_maximize(x,y):
     """Maximization comparator for fitness (scaled score)."""
     return cmp(y.fitness(),x.fitness())
+
 def sc_minimize(x,y):
     """Minimization comparator for raw score."""
 #       return cmp(x.score(),y.score())
     #removed one function call
     return cmp(x.evaluate(),y.evaluate())
+
 def sc_maximize(x,y):
     """Maximization comparator for raw score."""
 #       return cmp(y.score(),x.score())
     return cmp(y.evaluate(),x.evaluate())
+
 class default_pop_evaluator:
     """The **evaluate()** method simply calls the **evaluate()**
        method for all the genomes in the population
@@ -33,18 +38,21 @@
         try:
             evals = 0
             if not pop.evaluated or force:
-                for ind in pop: ind.evaluate(force)
+                for ind in pop:
+                    ind.evaluate(force)
         except:
             #this makes where a pop evaluator can simply evaluate a list
             #of genomes - might be useful to simplify remote evaluation
-            for ind in pop: ind.evaluate(force)
+            for ind in pop:
+                ind.evaluate(force)
 
 class default_pop_initializer:
-    """The **evaluate()** method simply calls the **evaluate()**
-       method for all the genomes in the population
+    """ The **evaluate()** method simply calls the **evaluate()** method for all
+    the genomes in the population
     """
     def evaluate(self,pop,settings):
-        for i in pop: i.initialize(settings)
+        for i in pop:
+            i.initialize(settings)
 
 class population(ga_list.ga_list):
     """A population of genomes.  The population is constructed by cloning a
@@ -106,6 +114,7 @@
         self._size(size)
         self.selector = population.default_selector() #why'd I do this?
         self.stats={}
+
     def initialize(self,settings = None):
         """This method **must** be called before a genetic algorithm
            begins evolving the population.  It takes care of initializing
@@ -136,6 +145,7 @@
         self.stats['initial']['max'] = self.stats['current']['max']
         self.stats['initial']['min'] = self.stats['current']['min']
         self.stats['initial']['dev'] = self.stats['current']['dev']
+
     def clone(self):
         """Returns a population that has a shallow copy the all the
            attributes and clone of all the genomes in the original
@@ -145,15 +155,22 @@
         new.stats = {}
         new.stats.update(self.stats)
         return new
+
     def touch(self):
         """Reset all the flags for the population."""
-        self.evaluated = 0; self.scaled = 0; self.sorted = 0; self.select_ready = 0
+        self.evaluated = 0
+        self.scaled = 0
+        self.sorted = 0
+        self.select_ready = 0
         self.stated = 0
+
     def _size(self, l):
         """Resize the population."""
         del self[l:len(self)]
-        for i in range(len(self),l): self.append(self.model_genome.clone())
+        for i in range(len(self),l):
+            self.append(self.model_genome.clone())
         return len(self)
+
     def evaluate(self, force = 0):
         """Call the **evaluator.evaluate()** method to evaluate
            the population.  The population is also sorted so that
@@ -180,9 +197,11 @@
         self.evaluated = 1
         e4 = time.clock()
         #print 'eval:',e1-b, 'sort:',e2-e1, 'stats:',e3-e2, 'touch:',e4-e3
+
     def mutate(self):
         mutations = 0
-        for ind in self: mutations  =  mutations + ind.mutate()
+        for ind in self:
+            mutations  =  mutations + ind.mutate()
         return mutations
 
     def sort(self,type = 'raw', force = 0):
@@ -199,10 +218,14 @@
            force -- forces the sort even if sorted = 1
         """
 #               if not self.sorted or force:
-        if(type == 'scaled'): self.data.sort(self.ftn_comparator)
-        elif(type == 'raw'): self.data.sort(self.sc_comparator)
-        else: raise GAError, 'sort type must be "scaled" or "raw"'
+        if type == 'scaled':
+            self.data.sort(self.ftn_comparator)
+        elif type == 'raw':
+            self.data.sort(self.sc_comparator)
+        else:
+            raise GAError('sort type must be "scaled" or "raw"')
         self.sorted = 1
+
     def select(self, cnt = 1):
         """Calls the selector and returns *cnt* individuals.
 
@@ -214,6 +237,7 @@
             self.selector.update(self)
             self.select_ready = 1
         return self.selector.select(self,cnt)
+
     def scale(self, force = 0):
         """Calls the **scaler.scale()** method and updates
            the fitness of each individual.
@@ -225,16 +249,19 @@
         if not (self.scaled or force):
             self.scaler.scale(self)
         self.scaled = 1
+
     def fitnesses(self):
-        """Returns the fitness (scaled score) of all the
-           individuals in a population as a Numeric array.
+        """ Returns the fitness (scaled score) of all the individuals in
+        a population as an array.
         """
-        return Numeric.array(map(lambda x: x.fitness(),self))
+        return array([x.fitness() for x in self])
+
     def scores(self):
-        """Returns the scores (raw) of all the
-           individuals in a population as a Numeric array.
+        """ Returns the scores (raw) of all the individuals in a population as
+        an array.
         """
-        return Numeric.array(map(lambda x: x.score(),self))
+        return array([x.score() for x in self])
+
     def best(self, ith_best = 1):
         """Returns the best individual in the population.
            *It assumes the population has been sorted.*
@@ -245,6 +272,7 @@
                        best individual in the population.
         """
         return self[ith_best - 1]
+
     def worst(self,ith_worst = 1):
         """Returns the worst individual in the population.
            *It assumes the population has been sorted.*
@@ -255,6 +283,7 @@
                        worst individual in the population.
         """
         return self[-ith_worst]
+
     def min_or_max(self,*which_one):
         """Returns or set 'min' or 'max' indicating whether the
            population is to be minimized or maximized.
@@ -274,20 +303,30 @@
             elif (re.match('max.*',which_one[0],re.I)):
                 self.ftn_comparator = ftn_maximize
                 self.sc_comparator = sc_maximize
-            else:   raise GaError, "min_or_max expects 'min' or 'max'"
-        if self.ftn_comparator == ftn_minimize: return 'min'
-        elif self.ftn_comparator == ftn_maximize: return 'max'
+            else:
+                raise GAError("min_or_max expects 'min' or 'max'")
+        if self.ftn_comparator == ftn_minimize:
+            return 'min'
+        elif self.ftn_comparator == ftn_maximize:
+            return 'max'
+
     def update_stats(self):
         """Update the statistics for the population."""
         s = self.scores()
         self.stats['current']['max'] = max(s)
         self.stats['current']['avg'] = my_mean(s)
         self.stats['current']['min'] = min(s)
-        if len(s) > 1: self.stats['current']['dev'] = my_std(s)
-        else: self.stats['current']['dev'] = 0
-        try: self.stats['overall']['max'] = max(self.stats['overall']['max'],
-                                                            self.stats['current']['max'])
-        except KeyError: self.stats['overall']['max'] = self.stats['current']['max']
-        try: self.stats['overall']['min'] = min(self.stats['overall']['min'],
-                                                            self.stats['current']['min'])
-        except KeyError: self.stats['overall']['min'] = self.stats['current']['min']
+        if len(s) > 1:
+            self.stats['current']['dev'] = my_std(s)
+        else:
+            self.stats['current']['dev'] = 0
+        try:
+            self.stats['overall']['max'] = max(self.stats['overall']['max'],
+                                               self.stats['current']['max'])
+        except KeyError:
+            self.stats['overall']['max'] = self.stats['current']['max']
+        try:
+            self.stats['overall']['min'] = min(self.stats['overall']['min'],
+                                               self.stats['current']['min'])
+        except KeyError:
+            self.stats['overall']['min'] = self.stats['current']['min']

Added: trunk/scipy/sandbox/ga/prng.py
===================================================================
--- trunk/scipy/sandbox/ga/prng.py	2007-08-27 20:12:57 UTC (rev 3268)
+++ trunk/scipy/sandbox/ga/prng.py	2007-08-27 22:18:00 UTC (rev 3269)
@@ -0,0 +1,36 @@
+""" Package-global pseudo-random number generator.
+
+This global is a transitional hack from the old code. Ideally, each run of a GA
+should control its own in order to allow multiple concurrent runs. However, we
+are transitioning from an older implementation that used a really global PRNG.
+"""
+
+from numpy.random import RandomState
+
+
+class GAPRNG(RandomState):
+    """ PRNG for the GA package.
+
+    In addition to all of the functionality derived from RandomState, we also
+    store the seed values that were used.
+    """
+
+    def seed(self, seed=None):
+        """ Seed the generator.
+
+        seed can be an integer, an array (or other sequence) of integers of any
+        length, or None. If seed is None, then RandomState will try to read data
+        from /dev/urandom (or the Windows analogue) if available or seed from
+        the clock otherwise.
+        """
+        RandomState.seed(self, seed)
+        self.initial_seed = seed
+
+    def choice(self, seq):
+        """ Randomly and uniformly select an item from a sequence.
+        """
+        i = self.randint(len(seq))
+        return seq[i]
+
+
+prng = GAPRNG()


Property changes on: trunk/scipy/sandbox/ga/prng.py
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/scipy/sandbox/ga/scaling.py
===================================================================
--- trunk/scipy/sandbox/ga/scaling.py	2007-08-27 20:12:57 UTC (rev 3268)
+++ trunk/scipy/sandbox/ga/scaling.py	2007-08-27 22:18:00 UTC (rev 3269)
@@ -1,39 +1,46 @@
 #genetic algorithm scaling routines
 #based on galib.
-#
-from ga_util import *
-import scipy.stats as stats
-from numpy import *
+
+from numpy import clip, inf
+from ga_util import GAError, my_mean, my_std
+
+
 # if a score is less the 2 standard deviations below, the average, its score
 # is arbitrarily set to zero
-class sigma_truncation_scaling:
-    def __init__(self,scaling = 2):
+class sigma_truncation_scaling(object):
+    def __init__(self, scaling = 2):
         self.scaling = scaling
-    def scale(self,pop):
+
+    def scale(self, pop):
         sc = pop.scores()
         avg = my_mean(sc)
-        if len(sc) > 1: dev = my_std(sc)
-        else: dev = 0
-        f = sc - avg + self.scaling * dev
-        f=choose(less_equal(f,0.),(f,0.))
-        for i in range(len(pop)): pop[i].fitness(f[i])
+        if len(sc) > 1:
+            dev = my_std(sc)
+        else:
+            dev = 0
+        f = clip(sc - avg + self.scaling * dev, 0, inf)
+        for i in range(len(pop)):
+            pop[i].fitness(f[i])
         return pop
 
-class no_scaling:
+class no_scaling(object):
     def scale(self,pop):
-        for ind in pop: ind.fitness(ind.score())
+        for ind in pop:
+            ind.fitness(ind.score())
         return pop
 
-class linear_scaling:
+class linear_scaling(object):
     def __init__(self,mult = 1.2):
         self.mult = mult
+
     def scale(self,pop):
         sc = pop.scores()
         pmin = min(sc)
-        if pmin < 0: raise GAError, 'linear scaling does not work with objective scores < 0'
+        if pmin < 0:
+            raise GAError('linear scaling does not work with objective scores < 0')
         pmax = max(sc)
         pavg = my_mean(sc)
-        if(pavg == pmax):
+        if pavg == pmax:
             a = 1.
             b = 0.
         elif pmin > (self.mult * pavg - pmax)/(self.mult - 1.):
@@ -44,6 +51,6 @@
             delta = pavg - pmin
             a = pavg / delta
             b = -pmin * pavg / delta
-        f = sc * a + b
-        f=choose(less_equal(f,0.),(f,0.))
-        for i in range(len(pop)): pop[i].fitness(f[i])
+        f = clip(sc * a + b, 0, inf)
+        for i in range(len(pop)):
+            pop[i].fitness(f[i])

Modified: trunk/scipy/sandbox/ga/selection.py
===================================================================
--- trunk/scipy/sandbox/ga/selection.py	2007-08-27 20:12:57 UTC (rev 3268)
+++ trunk/scipy/sandbox/ga/selection.py	2007-08-27 22:18:00 UTC (rev 3269)
@@ -1,93 +1,120 @@
 #genetic algorithm selection routines
 #based on galib.
 #exception - these classes only work on the scaled fitness
-from ga_util import *
-import scipy.stats as rv
-stats = rv
-import pdb
-from numpy import *
 
-class selector:
-    def update(self,pop): pass
-    def select(self,pop): raise GAError, 'selector.select() must be overridden'
-    def clear(self): pass
+import numpy as np
+
+from ga_util import GAError
+from prng import prng
+
+class selector(object):
+    def update(self,pop):
+        pass
+    def select(self,pop):
+        raise GAError('selector.select() must be overridden')
+    def clear(self):
+        pass
+
 class uniform_selector(selector):
     def select(self,pop,cnt = 1):
-        if cnt == 1: return rv.choice(pop)
+        if cnt == 1:
+            return prng.choice(pop)
         res = []
-        for i in range(cnt): res.append(rv.choice(pop))
+        for i in range(cnt):
+            res.append(prng.choice(pop))
         return res
 
-class rank_selector(selector):
-    def select(self,pop,cnt = 1):
-        pop.sort()
-        studliest = pop[0].fitness()
-        tied_for_first = filter(lambda x,y=studliest: x.fitness()==y,pop)
-        if cnt == 1: return rv.choice(tied_for_first)
-        res = []
-        for i in range(cnt): res.append(rv.choice(tied_for_first))
-        return res
+#class rank_selector(selector):
+#    def select(self,pop,cnt = 1):
+#        pop.sort()
+#        studliest = pop[0].fitness()
+#        # XXX: y?
+#        tied_for_first = [x for x in pop if x.fitness() == y]
+#        if cnt == 1:
+#            return prng.choice(tied_for_first)
+#        res = []
+#        for i in range(cnt):
+#            res.append(prng.choice(tied_for_first))
+#        return res
 
 #scores must all be positive
 class roulette_selector(selector):
     def update(self,pop):
         self.pop = pop[:]
         sz = len(pop)
-        if not sz: raise GAError, 'srs_selector - the pop size is 0!'
+        if not sz:
+            raise GAError('srs_selector - the pop size is 0!')
         f =self.pop.fitnesses()
         f_max = max(f); f_min = min(f)
         if not ( (f_max >= 0 and f_min >= 0) or
                    (f_max <= 0 and f_min <= 0)):
-            raise GAError, 'srs_selector requires all fitnesses values to be either strictly positive or strictly negative'
-        if f_max == f_min: f = ones(shape(f),typecode = Float32)
-        self.dart_board = add.accumulate(f / sum(f,axis=0))
+            raise GAError('srs_selector requires all fitnesses values to be either strictly positive or strictly negative')
+        if f_max == f_min:
+            f = np.ones_like(f)
+        self.dart_board = np.add.accumulate(f / sum(f,axis=0))
+
     def select(self,pop,cnt = 1):
         returns = []
         for i in range(cnt):
-            dart = rv.random()
+            dart = prng.random()
             idx = 0
             #binary search would be faster
-            while dart > self.dart_board[idx]: idx = idx + 1
+            while dart > self.dart_board[idx]:
+                idx = idx + 1
             returns.append(self.pop[idx])
-        if cnt == 1: return returns[0]
-        else: return returns
+        if cnt == 1:
+            return returns[0]
+        else:
+            return returns
+
     def clear(self):
         del self.pop
+
 #scores must all be positive
 class srs_selector(selector):
     def update(self,pop):
         sz = len(pop)
-        if not sz: raise GAError, 'srs_selector - the pop size is 0!'
+        if not sz:
+            raise GAError('srs_selector - the pop size is 0!')
         f =pop.fitnesses()
         f_max = max(f); f_min = min(f)
         if not ( (f_max >= 0. and f_min >= 0.) or
                    (f_max <= 0. and f_min <= 0.)):
-            raise GAError, 'srs_selector requires all fitnesses values to be either strictly positive or strictly negative - min %f, max %f' %(f_min,f_max)
+            raise GAError('srs_selector requires all fitnesses values to be either strictly positive or strictly negative - min %f, max %f' %(f_min,f_max))
         f_avg = sum(f,axis=0)/sz
-        if f_avg == 0.: e = ones(shape(f),typecode = Float32)
+        if f_avg == 0.:
+            e = np.ones_like(f)
         else:
-            if pop.min_or_max() == 'max': e = f/f_avg
-            else: e = (-f+f_max+f_min)/f_avg
+            if pop.min_or_max() == 'max':
+                e = f/f_avg
+            else:
+                e = (-f+f_max+f_min)/f_avg
         self.expected_value = e
         garauntee,chance = divmod(e,1.)
 #               garauntee = floor(e)
 #               chance = remainder(e,1)
         choices = []
-        for i in xrange(sz): choices = choices + [pop[i]] * int(garauntee[i])
+        for i in xrange(sz):
+            choices = choices + [pop[i]] * int(garauntee[i])
         #now deal with the remainder
-        dart_board = add.accumulate(chance / sum(chance,axis=0))
+        dart_board = np.add.accumulate(chance / sum(chance,axis=0))
         for i in range(len(choices),sz):
-            dart = rv.random()
+            dart = prng.random()
             idx = 0
-            while dart > dart_board[idx]: idx = idx + 1
+            while dart > dart_board[idx]:
+                idx = idx + 1
             choices.append(pop[idx])
         self.choices = choices
+
     def select(self,pop,cnt = 1): #ignore the past in pop
         res = []
-        for i in range(cnt): res.append(rv.choice(self.choices))
+        for i in range(cnt):
+            res.append(prng.choice(self.choices))
 #               for chosen in res: self.choices.remove(chosen)
-        if cnt == 1: return res[0]
+        if cnt == 1:
+            return res[0]
         return res
+
     def clear(self):
         if hasattr(self,'choices'):
             del self.choices

Modified: trunk/scipy/sandbox/ga/tree.py
===================================================================
--- trunk/scipy/sandbox/ga/tree.py	2007-08-27 20:12:57 UTC (rev 3268)
+++ trunk/scipy/sandbox/ga/tree.py	2007-08-27 22:18:00 UTC (rev 3269)
@@ -1,21 +1,17 @@
-from ga_util import *
-#import regress
-AddError = 'AddError'
-import pprint
 import sys
 
-#if sys.platform == 'win32':
-#       import pywin.debugger
-#       pdb = pywin.debugger
-#else:
-#       import pdb
+from ga_util import shallow_clone
 
-#pp = ejpprint.PrettyPrinter(indent = 4)
-pp = pprint.PrettyPrinter(indent = 4)
 
-ParentError = 'ParentError'
+class AddError(Exception):
+    """ Cannot add to the tree.
+    """
 
-class base_tree_node:
+class ParentError(Exception):
+    """ Parent is incorrect.
+    """
+
+class base_tree_node(object):
     objects_ever = 0
     objects = 0
     circular = 0
@@ -23,19 +19,22 @@
     def inc(self):
         base_tree_node.objects = base_tree_node.objects + 1
         base_tree_node.objects_ever = base_tree_node.objects_ever + 1
+
     def dec(self):
         base_tree_node.objects = base_tree_node.objects - 1
 
     def __init__(self,child_count,node_type='',derive_type='', parent=None):
 #               print 'trenode init',type(parent)
         self.inc()
-        if parent is None: self.symbol_table = {}
+        if parent is None:
+            self.symbol_table = {}
         self.node_type = node_type
         self.derive_type = derive_type
         self.child_count = child_count
         self._children = []
         self.set_parent(parent)
         self.label = node_type
+
     #so that we don't overwrite the general creation function in a derived class
     #and screw up clone
     def _create(self,parent = None):
@@ -49,29 +48,34 @@
         #new._children = []
         #if parent is None: new.symbol_table = {}
         return new
+
     def create(self,parent = None):
         new = self._create(parent)
         new._children = []
-        if parent is None: new.symbol_table = {}
+        if parent is None:
+            new.symbol_table = {}
         return new
+
     def clone(self,parent = None):
         """
         make lean and mean cause its called a ton
         """
         new = self._create(parent)
-        new._children = map(lambda x,par=new:
-                                x.clone(par),
-                                self._children)
+        new._children = [x.clone(parent) for x in self._children]
+        if parent is None:
+            new.generate_symbol_table()
+        return new
 
-        if parent is None: new.generate_symbol_table()
-        return new
     def set_parent(self,parent):
         self.parent = parent
+
     def get_parent(self):
         return self.parent
+
     def generate_symbol_table(self):
         self.symbol_table = {}
         self._generate_symbol_table(self.symbol_table)
+
     def _generate_symbol_table(self,symbol_table):
         """
         Return:
@@ -86,6 +90,7 @@
         if symbol_table.has_key(self.derive_type):
             symbol_table[self.derive_type].append(self)
         else:   symbol_table[self.derive_type] = [self]
+
     def parent_test(self):
         for child in self._children:
             child.parent_test()
@@ -93,6 +98,7 @@
             if not child.get_parent() is self:
                 #pdb.set_trace()
                 raise ParentError
+
     def node_count(self,type=None):
         cnt = 0
         for child in self._children:
@@ -110,9 +116,12 @@
         if len(self._children) < self.child_count:
             node.set_parent(self)
             self._children.append(node)
-        else:   raise AddError, 'to many children'
+        else:
+            raise AddError('too many children')
+
     def filled(self):
         return len(self._children) >= self.child_count
+
     def children(self):
         return self._children
 
@@ -124,20 +133,26 @@
             for child in self._children:
                 leaves = leaves + child.leaves()
         return leaves
+
     def depth(self):
-        if self.child_count == 0: return 1
+        if self.child_count == 0:
+            return 1
         else:
             return max(map(tree_node.depth,self._children)) + 1
+
     def ancestors(self):
         if self.get_parent(): return self.get_parent().ancestors() + 1
         return 1
+
     def root(self):
         if self.get_parent(): return self.get_parent().root()
         return self
+
     # I needed this to output string chromosomes for antennas
     # rethink this later
     def file_output(self,file):
         for child in self._children: child.file_output(file)
+
     def __repr__(self):
         res = '%s %s' % (self.label, self.derive_type)
         if len(self._children):
@@ -145,11 +160,11 @@
             res =  res + '\n' + '\t'*self.ancestors()
             res = res + '%s' % self._children
         return res
+
     def delete_circulars(self):
         #if hasattr(self,'parent'):
         #       if self.parent is None: print 'deleting root ciculars'
         base_tree_node.circular = base_tree_node.circular + 1
-        import sys
         self.symbol_table = None
         for child in self._children:
             if len(child._children):
@@ -166,60 +181,53 @@
 #               print 'tree_node killed:',tree_node.objects
         self.dec()
         #base_tree_node.objects = base_tree_node.objects - 1
+
     def __cmp__(self,other):
         #like ga_list compare...
-        try: return cmp(self.__dict__,other.__dict__)
-        except AttributeError: return 1
-        """
-        equal = 0
         try:
-                equal = (self.node_type == other.node_type and
-                           self.derive_type == other.derive_type and
-                           self.child_count == other.child_count and
-                           self._children == other._children)
-        except AttributeError: pass
-        return not equal
-        """
+            return cmp(self.__dict__,other.__dict__)
+        except AttributeError:
+            return 1
+
     def __setstate__(self,state):
         for key in state.keys():
             setattr(self, key, state[key])
         self.inc()
-"""
-#core dumps on linux
-import weakdict
-class weak_tree_node(base_tree_node,weakdict.WeakValue):
-        def __init__(self,child_count,node_type='',derive_type='', parent=None):
-                weakdict.WeakValue.__init__(self)
-                base_tree_node.__init__(self,child_count,node_type,derive_type, parent)
-        def set_parent(self,parent):
-                print 'in set'
-                if not hasattr(self,'parent'):
-                        self.parent = weakdict.WeakDict()
-                if parent: self.parent[0] = parent
-                elif self.parent.has_key(0): del self.parent[0]
-                print 'out set'
-        def get_parent(self):
-                print 'in get'
-                if self.parent.has_key(0): p =  self.parent[0]
-                else: p = None
-                print 'out get'
-                return p
-        def delete_circulars(self):
-                pass
-"""
-"""
-import mxProxy
-class proxy_tree_node(base_tree_node):
-        passobj = 2 #could be anything
-        def set_parent(self,parent):
-                self.parent = mxProxy.WeakProxy(parent,None,self.passobj)
-        def get_parent(self):
-                if self.parent: return self.parent.proxy_object(self.passobj)
-                return None
-        def delete_circulars(self):
-                pass
-"""
 
+
+##core dumps on linux
+#import weakdict
+#class weak_tree_node(base_tree_node,weakdict.WeakValue):
+#        def __init__(self,child_count,node_type='',derive_type='', parent=None):
+#                weakdict.WeakValue.__init__(self)
+#                base_tree_node.__init__(self,child_count,node_type,derive_type, parent)
+#        def set_parent(self,parent):
+#                print 'in set'
+#                if not hasattr(self,'parent'):
+#                        self.parent = weakdict.WeakDict()
+#                if parent: self.parent[0] = parent
+#                elif self.parent.has_key(0): del self.parent[0]
+#                print 'out set'
+#        def get_parent(self):
+#                print 'in get'
+#                if self.parent.has_key(0): p =  self.parent[0]
+#                else: p = None
+#                print 'out get'
+#                return p
+#        def delete_circulars(self):
+#                pass
+
+#import mxProxy
+#class proxy_tree_node(base_tree_node):
+#        passobj = 2 #could be anything
+#        def set_parent(self,parent):
+#                self.parent = mxProxy.WeakProxy(parent,None,self.passobj)
+#        def get_parent(self):
+#                if self.parent: return self.parent.proxy_object(self.passobj)
+#                return None
+#        def delete_circulars(self):
+#                pass
+
 tree_node = base_tree_node
 #tree_node = weak_tree_node
 #tree_node = proxy_tree_node
@@ -228,6 +236,7 @@
     print 'current', base_tree_node.objects
     print 'ever', base_tree_node.objects_ever
     print 'circular deletes', base_tree_node.circular
+
 def test_treenode():
     a = tree_node(2,'root')
     a.add_child(tree_node(0,'kid1'))

Modified: trunk/scipy/sandbox/ga/tree_opt.py
===================================================================
--- trunk/scipy/sandbox/ga/tree_opt.py	2007-08-27 20:12:57 UTC (rev 3268)
+++ trunk/scipy/sandbox/ga/tree_opt.py	2007-08-27 22:18:00 UTC (rev 3269)
@@ -5,29 +5,29 @@
     list_range nodes to exchange places.
 """
 
+from numpy import log10
+
 import tree
 import gene
 
 
-"""
-import weakdict
-class opt_object(tree.tree_node,weakdict.WeakValue):
-        opt_dict = weakdict.WeakDict()
-        def __init__(self,node_type, sub_nodes):
-                tree.tree_node.__init__(self,sub_nodes,node_type=node_type)
-                weakdict.WeakValue.__init__(self)
-                opt_object.opt_dict[id(self)] = self
-        def _create(self,parent = None):
-                new = tree.tree_node._create(self,parent)
-                weakdict.WeakValue.__init__(new)
-                self._WeakValue__cid = None #force a reset of the __cid value
-                weakdict.WeakValue.__init__(new) #now get a new value for it
-                opt_object.opt_dict[id(new)] = new
-                return new
-        def __del__(self):
-                tree.tree_node.__del__(self)
-                weakdict.WeakValue.__del__(self)
-"""
+#import weakdict
+#class opt_object(tree.tree_node,weakdict.WeakValue):
+#        opt_dict = weakdict.WeakDict()
+#        def __init__(self,node_type, sub_nodes):
+#                tree.tree_node.__init__(self,sub_nodes,node_type=node_type)
+#                weakdict.WeakValue.__init__(self)
+#                opt_object.opt_dict[id(self)] = self
+#        def _create(self,parent = None):
+#                new = tree.tree_node._create(self,parent)
+#                weakdict.WeakValue.__init__(new)
+#                self._WeakValue__cid = None #force a reset of the __cid value
+#                weakdict.WeakValue.__init__(new) #now get a new value for it
+#                opt_object.opt_dict[id(new)] = new
+#                return new
+#        def __del__(self):
+#                tree.tree_node.__del__(self)
+#                weakdict.WeakValue.__del__(self)
 
 class opt_object(tree.tree_node):
     def __init__(self,node_type, sub_nodes):
@@ -43,139 +43,176 @@
         else: self.default = (bounds[0] + bounds[1])/2.
         self._value = self.default
         print self._value
-    def clone(self,parent = None):return tree.tree_node.clone(self,parent)
-    """
-    def mutate(self):
-            m = gene.float_gene.mutate(self)
-            if(m and self.parent): self.parent.recalc(force_parent=1)
-            return m
-    """
+
+    def clone(self, parent=None):
+        return tree.tree_node.clone(self,parent)
+
+#    def mutate(self):
+#            m = gene.float_gene.mutate(self)
+#            if(m and self.parent): self.parent.recalc(force_parent=1)
+#            return m
+
     def scale(self,sc):
         self.bounds = (self.bounds[0]*sc,self.bounds[1]*sc)
         self.default = self.default*sc
         self._value = self._value*sc
+
     def defaultize(self):
         self._value = self.default
-        for child in self._children: child.defaultize()
-    def create(self,parent):
+        for child in self._children:
+            child.defaultize()
+
+    def create(self, parent):
         new = tree.tree_node.create(self,parent)
         new.initialize()
         gene.float_gene.initialize(new)
         return new
+
     def __del__(self):
 #               gene.float_gene.__del__(self)
         opt_object.__del__(self)
+
     def __repr__(self):
         try:
             val = self.value()
-            if( val < .01 or val > 1000): v = "%4.3e" % self.value()
-            else: v = "%4.3f" % self.value()
-        except gene.GAError: v = 'not initialized'
+            if val < .01 or val > 1000:
+                v = "%4.3e" % self.value()
+            else:
+                v = "%4.3f" % self.value()
+        except gene.GAError:
+            v = 'not initialized'
         self.label = '%s = %s' % (self.node_type, v)
         return tree.tree_node.__repr__(self)
-import math
+
 class log_float_range(gene.log_float_gene,opt_object):
     optimize = 1
+
     def __init__(self,bounds,node_type='log_float_range', sub_nodes = 0):
         gene.log_float_gene.__init__(self,bounds[:2])
         opt_object.__init__(self,node_type,sub_nodes)
-        if(len(bounds) == 3): self.default = bounds[2]
-        else: self.default = (bounds[0] + bounds[1])/2.
-        self._value = math.log10(self.default)
-    def clone(self,parent = None):return tree.tree_node.clone(self,parent)
-    """
+        if len(bounds) == 3:
+            self.default = bounds[2]
+        else:
+            self.default = (bounds[0] + bounds[1])/2.
+        self._value = log10(self.default)
+
+    def clone(self, parent=None):
+        return tree.tree_node.clone(self,parent)
+
     def mutate(self):
             m=gene.log_float_gene.mutate(self)
-            if(m and self.parent): self.parent.recalc(force_parent=1)
+            if m and self.parent:
+                self.parent.recalc(force_parent=1)
             return m
-    """
+
     def scale(self,sc):
         self.default = self.default*sc
         sc = log10(sc)
         self.bounds = (self.bounds[0]*sc,self.bounds[1]*sc)
         self._value = self._value*sc
+
     def defaultize(self):
         self._value = self.default
-        for child in self._children: child.defaultize()
+        for child in self._children:
+            child.defaultize()
+
     def create(self,parent):
         new = tree.tree_node.create(self,parent)
         new.initialize()
         gene.log_float_gene.initialize(new)
         return new
+
     def __del__(self):
 #               gene.log_float_gene.__del__(self)
         opt_object.__del__(self)
+
     def __repr__(self):
         try:
             val = self.value()
-            if( val < .01 or val > 1000): v = "%4.3e" % self.value()
-            else: v = "%4.3f" % self.value()
-        except gene.GAError: v = 'not initialized'
+            if val < .01 or val > 1000:
+                v = "%4.3e" % self.value()
+            else:
+                v = "%4.3f" % self.value()
+        except gene.GAError:
+            v = 'not initialized'
         self.label = '%s = %s' % (self.node_type, v)
         return tree.tree_node.__repr__(self)
 
 class list_range(gene.list_gene,opt_object):
     optimize = 1
-    def __init__(self,allele_set,node_type='list_range', default=None, sub_nodes = 0):
+
+    def __init__(self, allele_set, node_type='list_range', default=None, sub_nodes = 0):
         gene.list_gene.__init__(self,allele_set)
         opt_object.__init__(self,node_type,sub_nodes)
         gene.list_gene.initialize(self) # prevents trouble in tree generation
-        if(default): self.default = default
-        else: self.default = allele_set[int(len(allele_set)/2.)] #the center item
+        if default:
+            self.default = default
+        else:
+            self.default = allele_set[int(len(allele_set)/2.)] #the center item
         self._value = self.default
-    """
-    def mutate(self):
-            m=gene.list_gene.mutate(self)
-            if(m and self.parent): self.parent.recalc(force_parent=1)
-            return m
-    """
-    def clone(self,parent = None):return tree.tree_node.clone(self,parent)
+
+    def clone(self, parent=None):
+        return tree.tree_node.clone(self,parent)
+
     def scale(self,sc):
         for i in range(len(self.allele_set)):
             self.allele_set[i] = self.allele_set[i] *sc
         self.default = self.default*sc
         self._value = self._value*sc
+
     def defaultize(self):
         self._value = self.default
-        for child in self._children: child.defaultize()
+        for child in self._children:
+            child.defaultize()
+
     def create(self,parent):
         new = tree.tree_node.create(self,parent)
         new.initialize()
         gene.list_gene.initialize(new)
         return new
+
     def __del__(self):
 #               gene.list_gene.__del__(self)
         opt_object.__del__(self)
+
     def __repr__(self):
         self.label = '%s = %s' % (self.node_type, self.value())
         return tree.tree_node.__repr__(self)
 
 class val(gene.frozen,opt_object):
     optimize = 0
-    def __init__(self,val,node_type='val',sub_nodes=0):
+
+    def __init__(self, val, node_type='val', sub_nodes=0):
         gene.frozen.__init__(self,val)
         opt_object.__init__(self,node_type,sub_nodes)
-    def clone(self,parent = None):return tree.tree_node.clone(self,parent)
-    def scale(self,sc): self._value = self._value*sc
-    def defaultize(self): pass
+
+    def clone(self,parent = None):
+        return tree.tree_node.clone(self,parent)
+
+    def scale(self,sc):
+        self._value = self._value*sc
+
+    def defaultize(self):
+        pass
+
     def create(self,parent):
         new = tree.tree_node.create(self,parent)
         new.initialize()
         return new
+
     def __del__(self):
 #               gene.frozen.__del__(self)
         opt_object.__del__(self)
+
     def __repr__(self):
         self.label = '%s = %s' % (self.node_type, self.value())
         return tree.tree_node.__repr__(self)
 
 
-"""
-These two routines are useful for picking off or replacing the nodes in a
-tree that should be that should be numerically optimized.  They are helpful if
-your interested in using a gradient method to optimize some of the paramters
-of the array
-"""
+# These two routines are useful for picking off or replacing the nodes in a tree
+# that should be that should be numerically optimized.  They are helpful if your
+# interested in using a gradient method to optimize some of the paramters of the
+# array
 
 def pick_numbers(node):
     start = []; lower = []; upper =[];
@@ -203,10 +240,8 @@
         index = index + 1
     return index
 
-"""
-Grab the numerical nodes that need to be optimized so that you can directly
-manipulate them
-"""
+# Grab the numerical nodes that need to be optimized so that you can directly
+# manipulate them
 def pick_optimize_nodes(node):
     nodes = [];
     for child in node.children():



More information about the Scipy-svn mailing list