privateer / privateer_pyevolve / PrivateerCrossovers.py

from __future__ import division
import random
import math

MANTISSA_BITS = 53 #max python 64 bit mantissa size
MANTISSA_DENOM = 2<<MANTISSA_BITS

def G1DListCrossoverMean(genome, **args):
    """Ultra-stupid crossover taking the mean of both parents. Not very useful -
    AFAICT it results in pressure to converge to the population mean rather than
    to the solution."""

    sister = None
    brother = None
    gMom = args["mom"]
    gDad = args["dad"]

    sister = gMom.clone()
    brother = gDad.clone()
    sister.resetStats()
    brother.resetStats()

    for i in xrange(len(gMom)):
      sister[i] = brother[i] = (gMom[i]+gDad[i])/2.0
        
    return (sister, brother)

def bitcross(i1, i2, mask):
    """return a new int, containing its chosen from i1 or i2 depending on whther the mask string is 1 or 0"""
    return (i1 & mask) | (i2 & ~mask)
    
def G1DListCrossoverBitwise(genome, **args):
    """bitwise uniform crossover for floats. Warning, potentially breaks range
    constraints."""
    sister = None
    brother = None
    gMom = args["mom"]
    gDad = args["dad"]

    sister = gMom.clone()
    brother = gDad.clone()
    sister.resetStats()
    brother.resetStats()
    
    for i in xrange(len(gMom)):
        mask = random.getrandbits(MANTISSA_BITS) 
        mantissaDad, expDad = math.frexp(gDad[i])
        mantissaMom, expMom = math.frexp(gMom[i])
        mantissaDad = int(MANTISSA_DENOM*mantissaDad)
        mantissaMom = int(MANTISSA_DENOM*mantissaMom)
        
        #Not quite sure why i seem to need the -1 in here, but it makes me
        #distrust the function
        sister[i] = bitcross(mantissaDad, mantissaMom, mask) *\
          2.**(expDad-MANTISSA_BITS-1)
        brother[i] = bitcross(mantissaMom, mantissaDad, mask) *\
          2.**(expMom-MANTISSA_BITS-1)
        # if abs(sister[i])>20 or abs(brother[i])>20:
        #     import pdb; pdb.set_trace()
        sister[i] = clip(sister[i],
          gMom.getParam('rangemin'),
          gMom.getParam('rangemax'))
        brother[i] = clip(brother[i],
          gMom.getParam('rangemin'),
          gMom.getParam('rangemax'))
    return (sister, brother)


########
def test_mantissa_mathematics():
    """does all my mantisssa maths work? well, if this is stable it does"""
    def rndtrip(f): return int((2<<53)*f)/float(2<<53)
    f=1.0/3.0
    for i in range(100):
       print f.hex()
       f=rndtrip(f)

def clip(f, lbound, ubound):
    return min(max(f, lbound), ubound)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.