def testGenerate(self): exp = [33303, 49419, 24709, 12354, 38945, 52240, 58888, 29444, 14722] lfsr = LFSR(lfsr = 1070, bit_len = 16) for i in xrange(9): self.assertEquals(lfsr.generate(), exp[i]) exp = [0.612319946289, 0.80615234375, 0.903076171875, 0.951538085938, 0.975769042969, 0.987884521484, 0.993942260742, 0.496963500977, 0.248474121094] for i in xrange(9): res = lfsr.zero_to_one() self.assertLessEqual(res - exp[i], 0.00000000001) self.assertGreaterEqual(res - exp[i], -0.00000000001) exp = [3.92219712703, 1.96109856351, 4.12209399845, 5.20259171591, 2.60124792106, 1.30062396053, 0.650311980264, 3.46670070682, 1.73330241651] for i in xrange(9): res = lfsr.zero_to_2pi() self.assertLessEqual(res - exp[i], 0.00000000001) self.assertGreaterEqual(res - exp[i], -0.00000000001) exp = [-1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0] for i in xrange(9): self.assertEquals(lfsr.sign(), exp[i])
def testUniform(self): exp_q = ["Quaternion: -0.5105 + -0.7011i + 0.0180j + 0.4976k", "Quaternion: 0.1267 + -0.5028i + -0.7474j + -0.4153k", "Quaternion: 0.1504 + 0.0998i + -0.3025j + 0.9359k", "Quaternion: 0.6418 + -0.5843i + 0.2151j + -0.4476k", "Quaternion: 0.9726 + -0.0334i + 0.2176j + -0.0742k", "Quaternion: 0.0096 + 0.0015i + -0.0778j + 0.9969k", "Quaternion: -0.4398 + 0.5669i + -0.2332j + -0.6564k", "Quaternion: 0.2429 + 0.2133i + -0.3556j + 0.8769k", "Quaternion: -0.0521 + -0.3024i + -0.8972j + 0.3175k"] exp_angle = [-2.0702, 2.8876, 2.8396, 1.7478, 0.4689, 3.1225, -2.2309, 2.6510, -3.0374] exp_axis = ["Axis3: -0.8153, 0.0209, 0.5787", "Axis3: -0.5069, -0.7535, -0.4187", "Axis3: 0.1009, -0.3059, 0.9467", "Axis3: -0.7619, 0.2806, -0.5837", "Axis3: -0.1437, 0.9367, -0.3193", "Axis3: 0.0015, -0.0778, 0.9970", "Axis3: 0.6312, -0.2597, -0.7309", "Axis3: 0.2199, -0.3666, 0.9040", "Axis3: -0.3028, -0.8985, 0.3179"] rng = LFSR(lfsr = 1070, bit_len = 16) q = Quaternion() for i in xrange(9): q.uniform(rng) angle, axis = q.get_angle_axis() self.assertEquals(str(q), exp_q[i]) self.assertLessEqual(angle - exp_angle[i], 0.0001) self.assertGreaterEqual(angle - exp_angle[i], -0.0001) self.assertEquals(str(axis), exp_axis[i])
class GeneticAlgorithm: class Individual: def __init__(self, ttl_torsions = 0, \ lo_grid = Axis3(), hi_grid = Axis3(), \ rng = None): self.translation_gene = Axis3() self.rotation_gene = Quaternion() self.torsions_gene = [] self.random_translation(lo_grid, hi_grid, rng) self.random_rotation(rng) self.random_torsions(ttl_torsions, rng) def random_translation(self, lo_grid, hi_grid, rng): lo_x, lo_y, lo_z = lo_grid.xyz hi_x, hi_y, hi_z = hi_grid.xyz self.translation_gene.x = lo_x + (rng.zero_to_one() * (hi_x - lo_x)) self.translation_gene.y = lo_y + (rng.zero_to_one() * (hi_y - lo_y)) self.translation_gene.z = lo_z + (rng.zero_to_one() * (hi_z - lo_z)) def random_rotation(self, rng): self.rotation_gene.uniform(rng) def random_torsions(self, ttl_torsions, rng): self.torsions_gene = [] for i in xrange(ttl_torsions): self.torsions_gene.append(rng.neg_pi_to_pi()) class Population: def __init__(self): self.individuals = [] self.scores = GeneticAlgorithm.Scores() def __repr__(self): ret = "Individuals:\n" for individual in self.individuals: ret += "%s %s |" % (individual.translation_gene, \ individual.rotation_gene) for torsion in individual.torsions_gene: ret += " %5.2f" % torsion ret += "\n" return ret def create(self, size = 0, ttl_torsions = 0, \ lo_grid = Axis3(), hi_grid = Axis3(), \ rng = None): self.individuals = [] for i in xrange(size): individual = GeneticAlgorithm.Individual(ttl_torsions, \ lo_grid, hi_grid, \ rng) self.individuals.append(individual) def scoring(self, dock = None): self.scores = GeneticAlgorithm.Scores() for individual in self.individuals: if DEBUG: individual.translation_gene = Axis3(2.056477, 5.846611, -7.245407) individual.rotation_gene = Quaternion(0.532211, 0.379383, 0.612442, 0.444674) torsions_gene_degrees = [-122.13, -179.41, \ -141.59, 177.29, \ -179.46, -9.31, \ 132.37, -89.19, \ 78.43, 22.22, \ 71.37, 59.52] individual.torsions_gene = [] for torsions_gene_degree in torsions_gene_degrees: individual.torsions_gene.append((3.1415926535897931 / 180.0) * torsions_gene_degree) print individual.translation_gene print individual.rotation_gene print individual.torsions_gene if dock.reset_pose(individual.translation_gene, \ individual.rotation_gene, \ individual.torsions_gene): self.scores.append(dock.calc_energy()) else: self.scores.append(float("inf")) return self.scores def crossover(self, parents_idx, ttl_torsions, rng): return None def mutate(self, individual, mutation_chance, \ lo_grid, hi_grid, ttl_torsions, rng): return None class Settler(Population): def __init__(self): GeneticAlgorithm.Population.__init__(self) def crossover(self, parents_idx, ttl_torsions, rng): p1_idx = parents_idx[0] p2_idx = parents_idx[1] individual = deepcopy(self.individuals[p1_idx]) # Crossing over translation genes if rng.zero_to_one() > 0.5: individual.translation_gene = deepcopy(self.individuals[p2_idx].translation_gene) # Crossing over rotation genes if rng.zero_to_one() > 0.5: individual.rotation_gene = deepcopy(self.individuals[p2_idx].rotation_gene) # Crossing over torsion genes for i in xrange(ttl_torsions): if rng.zero_to_one() > 0.5: individual.torsions_gene[i] = self.individuals[p2_idx].torsions_gene[i] return individual def mutate(self, individual, mutation_chance, \ lo_grid, hi_grid, ttl_torsions, rng): if rng.zero_to_one() < mutation_chance: # Mutating translation genes if rng.zero_to_one() < 0.25: individual.random_translation(lo_grid, hi_grid, rng) # Mutating rotation genes if rng.zero_to_one() < 0.25: individual.random_rotation(rng) # Mutating torsion genes for i in xrange(ttl_torsions): if rng.zero_to_one() < 0.25: individual.torsions_gene[i] = rng.neg_pi_to_pi() return individual class Nomad(Population): def __init__(self): GeneticAlgorithm.Population.__init__(self) def crossover(self, parents_idx, ttl_torsions, rng): p1_idx = parents_idx[0] p2_idx = parents_idx[1] individual = deepcopy(self.individuals[p1_idx]) # Crossing over translation genes if rng.zero_to_one() > 0.5: individual.translation_gene.x = self.individuals[p2_idx].translation_gene.x if rng.zero_to_one() > 0.5: individual.translation_gene.y = self.individuals[p2_idx].translation_gene.y if rng.zero_to_one() > 0.5: individual.translation_gene.z = self.individuals[p2_idx].translation_gene.z # Crossing over rotation genes if rng.zero_to_one() > 0.5: individual.rotation_gene.a = self.individuals[p2_idx].rotation_gene.a if rng.zero_to_one() > 0.5: individual.rotation_gene.b = self.individuals[p2_idx].rotation_gene.b if rng.zero_to_one() > 0.5: individual.rotation_gene.c = self.individuals[p2_idx].rotation_gene.c if rng.zero_to_one() > 0.5: individual.rotation_gene.d = self.individuals[p2_idx].rotation_gene.d # Crossing over torsion genes for i in xrange(ttl_torsions): if rng.zero_to_one() > 0.5: individual.torsions_gene[i] = self.individuals[p2_idx].torsions_gene[i] return individual def mutate(self, individual, mutation_chance, \ lo_grid, hi_grid, ttl_torsions, rng): if rng.zero_to_one() < mutation_chance: # Mutating translation genes if rng.zero_to_one() < 0.75: individual.random_translation(lo_grid, hi_grid, rng) # Mutating rotation genes if rng.zero_to_one() < 0.75: individual.random_rotation(rng) # Mutating torsion genes for i in xrange(ttl_torsions): if rng.zero_to_one() < 0.75: individual.torsions_gene[i] = rng.neg_pi_to_pi() return individual class Scores(list): def __init__(self, *args): list.__init__(self, *args) def minimum(self): return min(self) # Normalized scores to the total ligand atoms def normalize(self, normalizer): normalized_scores = [] for score in self: normalized_scores.append(float(score) / normalizer) return normalized_scores def __init__(self, dock = None): self.dock = dock self.lo_grid = Axis3() self.hi_grid = Axis3() self.ttl_torsions = 0 self.ttl_ligand_atoms = 0 self.community_size = 0 # Community size self.population_size = 0 # Population size self.dna_size = 0 # Total genes in a DNA self.num_gen = 0 # Number of generations self.max_inherited_prob = 12 # Maximum inhereted probability self.rng = None self.mutation_chance = 0.0 # Create multiple population self.nomad = None self.settler = None def setup_rng(self): # Define random number generator self.rng = LFSR(lfsr = 1070, bit_len = 48) def setup(self): self.lo_grid = self.dock.grid.field.lo self.hi_grid = self.dock.grid.field.hi self.ttl_torsions = self.dock.get_total_torsions() self.mutation_chance = 1.0 / self.ttl_torsions self.ttl_ligand_atoms = len(self.dock.ligand.ori_atoms) self.setup_rng() def select(self, population): # Get individual scores scores = population.scoring(self.dock) # Create mating pool from the scores mating_pool = [] for idx, score in enumerate(scores.normalize(self.ttl_ligand_atoms)): # Use probabilistic method to select individual into mating pool if score < 0: chances = self.max_inherited_prob else: power = log(score) if power < self.max_inherited_prob: chances = int(self.max_inherited_prob - power) else: chances = 1 # Fill in the mating pool for i in xrange(chances): mating_pool.append(idx) return mating_pool def pick_parents(self, mating_pool): parents = [] for i in xrange(2): parents.append(mating_pool[int(self.rng.zero_to_one() * \ len(mating_pool))]) return parents def reproduce(self, mating_pool, population): new_population = deepcopy(population) new_population.individuals = [] for i in xrange(self.population_size): parents_idx = self.pick_parents(mating_pool) individual = population.crossover(parents_idx, self.ttl_torsions, self.rng) individual = population.mutate(individual, self.mutation_chance, \ self.lo_grid, self.hi_grid, \ self.ttl_torsions, self.rng) new_population.individuals.append(individual) return new_population def run(self): self.setup() # Define multiple population self.nomad = self.Nomad() self.settler = self.Settler() population_min_scores = [] for community_idx in xrange(self.community_size): tic = time() # Nomad portion nomad_min_score = float("inf") self.nomad.create(self.population_size, self.ttl_torsions, \ self.lo_grid, self.hi_grid, \ self.rng) if VERBOSE: print self.nomad for gen_idx in xrange(self.num_gen): mating_pool = self.select(self.nomad) self.nomad = self.reproduce(mating_pool, self.nomad) nomad_min_score = self.nomad.scores.minimum() # Settler portion settler_min_score = float("inf") self.settler.individuals = deepcopy(self.nomad.individuals) if VERBOSE: print self.settler for gen_idx in xrange(self.num_gen): mating_pool = self.select(self.settler) self.settler = self.reproduce(mating_pool, self.settler) if VERBOSE: print self.settler settler_min_score = self.settler.scores.minimum() population_min_scores.append([nomad_min_score, settler_min_score]) toc = time() print "Elapsed time community %4d: %10.2f - Minimum Scores: %12.3f, %12.3f" \ % (community_idx + 1, toc - tic, \ nomad_min_score, settler_min_score) print "Community Minimum Scores: %s" % population_min_scores
from LFSR import LFSR # choose primitive polynomial for maximum period, # max-period = (2**m)-1, where m is degree # LSFR.generate() takes 2 args, # intial states of registers [0 or 1] # required length of random bits, default = 256 # example 1 lfsr1 = LFSR("7 6 0") # exponents of polynomial prng1 = lfsr1.generate("1100101", 84) random_seq_1 = ''.join(prng1) print("Random sequence 1", random_seq_1) prng2 = lfsr1.generate("1100101", 256) random_seq_2 = ''.join(prng2) print("Random sequence 2", random_seq_2) # example 2 lfsr2 = LFSR("8 6 5 4 0") prng3 = lfsr2.generate("11001001", 128) random_seq_3 = ''.join(prng3) print("Random sequence 3", random_seq_3)
def setup_rng(self): # Define random number generator self.rng = LFSR(lfsr = 1070, bit_len = 48)