Content¶
Getting Started¶
Installation¶
Glyph is a python 3.5+ only package.
You can install the latest stable version from PyPI with pip
pip install pyglyph
or get the bleeding edge
pip install git+git://github.com/ambrosys/glyph.git#egg=glyph
Concepts¶
Glyph has several abstraction layers. Not all of them are required to use.
Individual & genetic operators¶
This wraps around the backend, which is currently deap. In contrast to deap, the individual class has to be associated with a primitive set. This makes checkpointing and later evaluation of results easier.
This abstraction layer also allows for an interchangeable representation. We plan to support graphs and stacks in the future.
Genetric operators mutation and crossover operators.
Currently, we also rely on deaps sorting algorithms.
Creating an individual class is as simple as:
from glyph.gp.individual import AExpressionTree, numpy_primitive_set
pset = numpy_primitive_set(1)
class Individual(AExpressionTree):
pset = pset
Here, we use the convinience function numpy_primitive_set
to create a primitive set based on categeories.
Algorithm¶
This encapsulates selecting parents and breeding offspring.
Glyph comes with the following algorithms:
- AgeFitness Pareto Optimization
- SPEA2
- NSGA2
- and the “unique” counterparts of all of the above.
Algorithms need the genetic operators. The chose to implement them as classes. You can change the default parameters by simply overwriting the corresponding attribute. All algorithms only expose a single method evolve(population)
. This assumes all individuals in the population have a valid fitness. evolve(population)
will first select the parents and then produce offspring. Both, parents and offspring will be returned by the method. By doing so, so can re-evaluate the parent generation if desired (e.g. to account for different operating conditions of an experiment).
from functools import partial
import deap
from glyph import gp
mate = deap.gp.cxOnePoint
expr_mut = partial(deap.gp.genFull, min_=0, max_=2)
mutate = partial(deap.gp.mutUniform, expr=expr_mut, pset=Individual.pset)
algorithm = gp.NSGA2(mate, mutate)
AssessmentRunner¶
The AssesmentRunner is a callable which takes a list of Individuals and assigns a fitness to them. This can be as simple as:
def meassure(ind):
g = lambda x: x**2 - 1.1
points = np.linspace(-1, 1, 100, endpoint=True)
y = g(points)
f = gp.individual.numpy_phenotype(ind)
yhat = f(points)
if np.isscalar(yhat):
yhat = np.ones_like(y) * yhat
return nrmse(y, yhat), len(ind)
def update_fitness(population, map=map):
invalid = [p for p in population if not p.fitness.valid]
fitnesses = map(meassure, invalid)
for ind, fit in zip(invalid, fitnesses):
ind.fitness.values = fit
return population
update_fitness
is taken directly from the deap library. You can interface your symbolic regression problem by providing a different map
function. The recommenced solution is scoop. Why this does not work in most cases see Parallel. Which can be a bit cumbersome to write for more complex problems.
The glyph.assessment submodule has many out of the box solutions for boilerplate/utility code, constant optimization and integration multiprocessing/distributed frameworks.
The code above with constant optimization simply becomes:
class AssessmentRunner(AAssessmentRunner):
def setup(self):
self.points = np.linspace(-1, 1, 100, endpoint=True)
self.g = lambda x: x**2 - 1.1
self.y = self.g(self.points)
def measure(self, ind):
popt, error = const_opt_scalar(self.error, ind)
ind.popt = popt
return error, len(ind)
def error(self, ind, *consts):
f = numpy_phenotype(ind)
yhat = f(self.points, *consts)
return nrmse(self.y, yhat)
Algorithm and assessment runner already make up a program:
runner = AssessmentRunner()
pop = Individual.create_population(lambda_)
runner(pop)
for i in range(generations):
pop = runner(algorithm(pop))
GPRunner¶
The GPRunner lets you conveniently steps cycle through the evolutionary algrithm whilst taken care for statistics and a hall of fame.
It’s mostly syntatic sugar:
gp_runner = GPRunner(Individual, lambda: algorithm, AssessmentRunner())
gp_runner.init()
for i in range(generations):
gp_runner.step()
Application¶
If you want a command line interface for all your hyper-parameters, checkpointing, ensuring random state handling on resume, as well as breaking conditions, the glyph.application submodule has you covered.
The module provides several facory classes which can dynamically expand an existing argparse.ArgumentParser
. As a starting point, you can use the default_console_app
to create an app. You will only need a primitive set and an assessment runner as explained above.
parser = argparse.ArgumentParser(program_description)
app, args = application.default_console_app(Individual, AssessmentRunner, parser)
app.run()
For more involved applications you can inherit from the Application class. (see /../../glyph/cli/glyph_remote.py
).
We recommence having a look at the /../../examples/control/minimal_example.py
as well as the /../../examples/control/lorenz.py
example to see these concepts in action.
Glyph remote¶
glyph-remote is shipped together with the glyph package. After
installation, the glyph-remote
command is available at the command
line.
Concept¶
With glyph-remote the separation between optimization method and optimization task is made easy. glyph-remote runs multi IO symbolic regression and sends candidate solution via ZeroMQ to an experiment controller for assessment. Every hyper-parameter used is assessable and fully configurable.
Overview¶
To the right the optimization method is represented. The GP program can be seen as a black box which is only accessible by the specified interface. To the left a single experiment plus an event handler is depicted. The latter glues optimization method and task together and needs to understand the communication protocol defined in

Currently we use client server sockets for glyph remote. The user needs to implement the zmq.REP socket.
Communication protocol¶
The communication is encoded in json. A message is a json object with two members:
{
"action": "value",
"payload": "value",
}
The possible action values are:
Action name | Payload | Expected return Value |
---|---|---|
CONFIG | – | config settings |
EXPERIMENT | list of expressions | list of fitness value(s) |
METADATA | – | any |
SHUTDOWN | – | – |
The config action is performed prior to the evolutionary loop. Entering the loop, for every discovered solution an experiment action will be requested. Since most experiments have an intermediate compiling step, expressions will come in chunks. You can configure optional caching for re-discovered solutions. The shutdown action will let the experiment program know that the gp loop is finished and you can safely stop the hardware.
Config¶
See Configuration section.
Experiment¶
The experiment request expects a fitness value for each expression:
{
"fitness": ["value0", "value1", ...],
}
Shutdown¶
You can properly shut down the experiment hardware.
Configuration¶
For a full list of configuration options and their default values type
glyph-remote --help
.
All hyper-parameters and algorithms used have default values. You have three options to set parameters:
- use the command line interface
- read from file (using
--cfile myfile.yaml
) - request from event handler (using
--remote
)
At cli, options are specified using --key value
. The configuration
file has to be written in yaml, i.e.
key: value
The event handler should send back a similar json array
{
"key": "value",
}
It is mandatory to provide a information about the primitives you want to use. The value of the “primitives” key is again a json/yaml list specifying name: arity pairs. Arities greater one are functions, equal to one are variables and -1 is reserved for symbolic constants.
{
"primitives":
{
"add": 2,
"x": 0,
},
}
GUI¶
Install¶
Glyph comes with an optional GUI to use the glyph-remote
script with more convenience.
The GUI uses the package wxPython
. The installation manual can be found here
and Website.
Manual Gooey installtion
Since up-to-date (28.08.2018) the necessary changes to the used graphic library Gooey are not part of the master branch, it might be necessary to install Gooey by hand from this fork:
pip install -e "git+git@github.com:Magnati/Gooey.git#egg=gooey"
Installation with pip installtion
To install glyph including the gui option use the following command:
To start the script with the gui just use the --gui
parameter:
Usage¶
Within the GUI there is a tab for each group of parameters. If all parameters are set, click the start-button to start the experiment.
Pretesting & Constraints¶
In glyph-remote, genetic operations can be constrained. A genetic operation (i.e. every operation that create or modifies the genotype of an individual). If a constraint is violated, the genetic operation is rejected. If out of time, the last candidate is used.
Currently, two different types of constraints are implemented: - algebraic constraints using sympy - pretesting constraints
Algebraic constraints¶
Sympy is used to check whether expressions are:
- zero
- constant
- infinite
The three options can be individually activated.
Pretesting¶
You can invoke file-based pretesting with the --constraints_pretest filename.py
flag.
The flag --constraints_pretest_function
lets you pass the function name which will be invoked to pretest individuals.
The function is expected to return a boolean, depending on the individual is rejected (False) or accepted (True).
An example file could look like this:
import time
def chi(ind):
time.sleep(1)
print(f"Hello World, this is {ind}")
return True
Publications using glyph¶
If you use glyph please consider citing glyph:
@article{quade2019,
author = {Quade, Markus and Gout, Julien and Abel, Markus},
title = {{Glyph: {Symbolic} Regression Tools}},
journal = {J Open Res Softw},
year = {2019},
month = jun,
doi = {10.5334/jors.192},
volume = {19},
issue = {7(1)},
}
@misc{glyph,
author = {Quade, Markus and Gout, Julien and Abel, Markus},
title = {{glyph} - Symbolic Regression Tools},
month = jan,
year = {2018},
doi = {10.5281/zenodo.1156654},
url = {https://github.com/Ambrosys/glyph},
note = {Version 0.3.5},
}
Experiments¶
- El Sayed M, Y., Oswald, P., Sattler, S., Kumar, P., Radespiel, R., Behr, C., … & Abel, M. (2018). Open-and closed-loop control investigations of unsteady Coanda actuation on a high-lift configuration. In 2018 Flow Control Conference (p. 3684).
Simulations¶
- Gout, J., Quade, M., Shafi, K., Niven, R. K., & Abel, M. (2018). Synchronization control of oscillator networks using symbolic regression. Nonlinear Dynamics, 91(2), 1001-1021.
About glyph¶
glyph has been deleveloped by (alphabetical order):
- Markus Abel
- Julien Gout
- Markus Quade
at Ambrosys GmbH.
Funding Acknowledgements¶
The development of glyph was supported by the following:
- MQ was supported by a fellowship within the FITweltweit program of the German Academic Exchange Service (DAAD)
- German Science Foundation via SFB 880
- German Ministry for economy via ZIM projekt, Nr. KF2768302
Tutorials¶
Parallel¶
Pickling problems¶
Most parallelization frameworks rely on the built-in pickle module which has limited functionality regarding lambda expressions. Deap relies heavily on those functionalities and thus most parallelization frameworks do not work well with deap.
Dill can handle everything we need and can be monkey patched to replace pickle.
Labview Tutorial¶
Contributed by P. Oswald.
Install Python¶
- Install Miniconda (Python 3.5 or higher).
- Open a command window as administrator:
- cd to Miniconda3 directory
- run
conda update conda
Install Glyph¶
- If you have git installed, run
pip install –e git+https://github.com/Ambrosys/glyph.git#egg=glyph
. Go to step 5. - Download the latest version from Github.
- Unzip / move to somewhere useful
- Upen a cmd window, navigate the the glyph-master folder
- Run
pip install –e .
(don’t forget the period at the end) - Test the installation by running
glyph-remote --help
.
Install ZeroMQ¶
- Download ZeroMQ bindings for LabView from http://labview-zmq.sourceforge.net/
- The download is a VI-Package (*.vip-file)
- Double clicking the *.vip-file opens it in the VI Package Manager (further info http://www.ni.com/tutorial/12397/en/)
- Use the VI Package Manager to install the package
Use ZeroMQ¶
- After successful installation you can find examples on the usage of ZeroMQ either
- through the VI Package Manager by double clicking on the entry “ZeroMQ Socket Library” and then on the button “Show Examples”
- in your LabView installation folder in the subdirectory /examples/zeromq/examples/
- online (e.g. the basic examples at http://labview-zmq.sourceforge.net/)
- For communication with glyph-remote one has to implement a server that listens for requests from glyph and sends the apropriate responses
- The ZeroMQ programming blocks can be accessed by right clicking on the block diagram and navigating to the section “Add-ons”
- The block “Unflatten from JSON” can be used to convert the JSON encoded strings sent by glyph to LabView clusters
Matlab Tutorial¶
Contributed by B. Strom.
Note
This was performed on Windows 7 and using MATLAB R2016b (2016b or later is needed for jasondecode()
and jasonencode()
commands)
Install Python¶
- Install Miniconda (Python 3.5 or higher).
- Open a command window as administrator:
- cd to Miniconda3 directory
- run
conda update conda
Install Glyph¶
- If you have git installed, run
pip install –e git+https://github.com/Ambrosys/glyph.git#egg=glyph
. Go to step 5. - Download the latest version from Github.
- Unzip / move to somewhere useful
- Upen a cmd window, navigate the the glyph-master folder
- Run
pip install –e .
(don’t forget the period at the end) - Test the installation by running
glyph-remote --help
.
Install jeroMQ (java implementation of zeroMQ)¶
This will be used for zeroMQ in MATLAB.
- If you don’t have it, install the Java developer kit.
- Set the JAVA_HOME environment variable
- Right click My Computer and select properties
- On the Advanced tab, select Environment Variables, and then edit or create the system variable JAVA_HOME to point to where the JDK software is located, for example,
C:\Program Files\Java\jdk1.8.0_131
- Install Maven.
- Add the bin directory of the created directory apache-maven-3.5.0 to the PATH environment variable (same steps as the setting the
JAVA_HOME
variable, but this is a user variable instead of a system variable)- Confirm installation with
mvn -v
in a command window
- Download the latest stable release of jeroMQ.
- Unpack the zip file
- In a command window, navigate to the resulting jeroMQ folder
- Run the command
mvn package
- This will take a while, but you should see “Build Success” when it is finished
- This will have created a “target” directory in the jeroMQ folder. The Jar file we need is in here, something like
…/target/jeromq-0.4.1-SNAPSHOT.jar
- Add the path to this Jar file to MATLAB’s static Java path
- Run the command
prefdir
in MATLAB. Navigate to that folder and check for a file namedjavaclasspath.txt
.- Open this file in a text editor or create anASCII text file named
javaclasspath.txt
.- On its own line, add the full path to the jar file, including the file name. You can move it or rename it first if you wish.
- Restart MATLAB
- To test that MATLAB can access jeroMQ, run
import org.zeromq.ZMQ
in at the MATLAB command prompt. If no error, it was successful.
Test a basic example¶
Development:¶
Know what you’re looking for & just need API details? View our auto-generated API documentation:
glyph¶
glyph package¶
Subpackages¶
-
class
Communicator
(ip, port)[source]¶ Bases:
object
Holds the socket for 0mq communication.
Parameters: - ip – ip of the client
- port – port of the client
-
class
EvalQueue
(com, result_queue, expect)[source]¶ Bases:
queue.Queue
-
class
ExperimentProtocol
[source]¶ Bases:
enum.EnumMeta
Communication Protocol with remote experiments.
-
CONFIG
= 'CONFIG'¶
-
EXPERIMENT
= 'EXPERIMENT'¶
-
METADATA
= 'METADATA'¶
-
SHUTDOWN
= 'SHUTDOWN'¶
-
-
class
Individual
(content)[source]¶ Bases:
glyph.gp.individual.AExpressionTree
Abstract base class for the genotype.
Derived classes need to specify a primitive set from which the expression tree can be build, as well as a phenotype method.
-
class
NDTree
(trees)[source]¶ Bases:
glyph.gp.individual.ANDimTree
-
base
¶ alias of
Individual
-
-
class
RemoteApp
(config, gp_runner, checkpoint_file=None, callbacks=(<function make_checkpoint>, <function log>))[source]¶ Bases:
glyph.application.Application
An application based on
GPRunner
.Controls execution of the runner and adds checkpointing and logging functionality; also defines a set of available command line options and their default values.
To create a full console application one can use the factory function default_console_app().
Parameters: - config (dict or argparse.Namespace) – Container holding all configs
- gp_runner – Instance of
GPRunner
- checkpoint_file – Path to checkpoint_file
- callbacks –
-
class
RemoteAssessmentRunner
(com, complexity_measure=None, multi_objective=False, method='Nelder-Mead', options={'smart_options': {'use': False}}, caching=True, persistent_caching=None, simplify=False, chunk_size=30, send_symbolic=False, reevaluate=False)[source]¶ Bases:
object
Contains assessment logic. Uses zmq connection to request evaluation.
-
recv
¶ Backwards compatibility
-
send
¶ Backwards compatibility
-
-
build_pset_gp
(primitives, structural_constants=False, cmin=-1, cmax=1)[source]¶ Build a primitive set used in remote evaluation.
Locally, all primitives correspond to the id() function.
-
class
NSGA2
(mate_func, mutate_func)[source]¶ Bases:
glyph.gp.algorithms.MOGP
Implementation of the NSGA-II algorithm as described in Essentials of Metaheuristics
-
class
SPEA2
(mate_func, mutate_func)[source]¶ Bases:
glyph.gp.algorithms.MOGP
Implementation of the SPEA2 algorithm as described in Essentials of Metaheuristics
-
class
DeapEaSimple
(mate_func, mutate_func)[source]¶ Bases:
object
Basically a copy of
deap.algorithms.eaSimple
algorithm.
-
class
AgeFitness
(mate_func, mutate_func, select, create_func)[source]¶ Bases:
glyph.gp.algorithms.MOGP
AgeFitness algorithm as described in Schmidt & Lipson. DOI: 10.1007/978-1-4419-7747-2_8
-
class
UNSGA2
(mate_func, mutate_func)¶ Bases:
glyph.gp.algorithms.NSGA2
-
evlolve
(population)¶
-
-
class
USPEA2
(mate_func, mutate_func)¶ Bases:
glyph.gp.algorithms.SPEA2
-
evlolve
(population)¶
-
-
class
UDeapEaSimple
(mate_func, mutate_func)¶ Bases:
glyph.gp.algorithms.DeapEaSimple
-
evlolve
(population)¶
-
-
class
UAgeFitness
(mate_func, mutate_func, select, create_func)¶ Bases:
glyph.gp.algorithms.AgeFitness
-
evlolve
(population)¶
-
-
class
NonFiniteExpression
(zero=True, infty=True, constant=False)[source]¶ Bases:
glyph.gp.constraints.Constraint
Use sympy to check for finite expressions.
Parameters: - zero – flag to check for zero expressions
- infty – flag to check for infinite expressions
- constant – flag to check for constant expressions
-
class
PreTest
(fn, fun='chi')[source]¶ Bases:
glyph.gp.constraints.Constraint
Apply pre-testing to check for constraint violation.
The python script needs to provide a callable fun(ind).
Parameters: - fn – filename of the python script.
- fun – name of the function in fn.
-
class
PreTestService
(assessment_runner)[source]¶ Bases:
glyph.gp.constraints.Constraint
-
com
¶
-
make_str
¶
-
Provide Individual class for gp.
-
class
AExpressionTree
(content)[source]¶ Bases:
deap.gp.PrimitiveTree
Abstract base class for the genotype.
Derived classes need to specify a primitive set from which the expression tree can be build, as well as a phenotype method.
-
const_opt
¶
-
classmethod
create_population
(size, gen_method=<function genHalfAndHalf>, min=1, max=4)[source]¶ Create a list of individuals of class Individual.
-
classmethod
from_string
(string)[source]¶ Try to convert a string expression into a PrimitiveTree given a PrimitiveSet pset. The primitive set needs to contain every primitive present in the expression.
Parameters: - string – String representation of a Python expression.
- pset – Primitive set from which primitives are selected.
Returns: PrimitiveTree populated with the deserialized primitives.
-
hasher
¶ alias of
builtins.str
-
pset
¶
-
terminals
¶ Return terminals that occur in the expression tree.
-
-
class
ANDimTree
(trees)[source]¶ Bases:
list
A naive tree class representing a vector-valued expression.
Each dimension is encoded as a expression tree.
-
base
¶
-
height
¶
-
pset
¶
-
terminals
¶ Return terminals that occur in the expression tree.
-
-
class
Individual
(pset, name='MyIndividual', **kwargs)[source]¶ Bases:
type
Construct a new expression tree type.
Parameters: - pset –
deap.gp.PrimitiveSet
- name – name of the expression tree class
- kwargs – additional attributes
Returns: expression tree class
-
static
__new__
(mcs, pset, name='MyIndividual', **kwargs)[source]¶ Construct a new expression tree type.
Parameters: - pset –
deap.gp.PrimitiveSet
- name – name of the expression tree class
- kwargs – additional attributes
Returns: expression tree class
- pset –
- pset –
-
class
Measure
(values=())[source]¶ Bases:
deap.base.Fitness
This is basically a wrapper around deap.base.Fitness.
It provides the following enhancements over the base class: - more adequate naming - copy constructable - no weight attribute
-
values
¶
-
weights
= repeat(-1)¶
-
-
class
NDIndividual
(base, name='MyNDIndividual', **kwargs)[source]¶ Bases:
type
Construct a new n-dimensional expression tree type.
Parameters: - base (Individual) – one dimensional base class
- name – name of the n-dimensional expression tree class
- **kwargs – addtional attributes
Returns: n-dimensional expression tree class
-
class
StructConst
(func, arity=2)[source]¶ Bases:
deap.gp.Primitive
Parameters: func – evaluate left and right subtree and assign a constant.
-
add_sc
(pset, func)[source]¶ Adds a structural constant to a given primitive set.
Parameters: - func –
callable(x, y) -> float
where x and y are the expressions of the left and right subtree - pset (
deap.gp.PrimitiveSet
) – You may want to usesympy_primitive_set
ornumpy_primitive_set
without symbolic constants.
- func –
-
child_trees
(ind)[source]¶ Yield all child tree which are used as arguments for the head node of ind.
-
convert_inverse_prim
(prim, args)[source]¶ Convert inverse prims according to: [Dd]iv(a,b) -> Mul[a, 1/b] [Ss]ub(a,b) -> Add[a, -b]
We achieve this by overwriting the corresponding format method of the sub and div prim.
-
nd_phenotype
(nd_tree, backend=<function sympy_phenotype>)[source]¶ Parameters: - nd_tree (ANDimTree) –
- backend – sympy_phenotype or numpy_phenotype
Returns: lambda function
-
numpy_phenotype
(individual)[source]¶ Lambdify the individual
Parameters: individual ( glyph.gp.individual.AExpressionTree
) –Returns: lambda function Note: In constrast to sympy_phenotype the callable will have a variable number of keyword arguments depending on the number of symbolic constants in the individual.
Example: >>> pset = numpy_primitive_set(1) >>> MyIndividual = Individual(pset=pset) >>> ind = MyIndividual.from_string("Add(x_0, Symc)") >>> f = numpy_phenotype(ind) >>> f(1, 1) 2
-
numpy_primitive_set
(arity, categories=('algebraic', 'trigonometric', 'exponential', 'symc'))[source]¶ Create a primitive set based on numpys vectorized functions.
Parameters: - arity – Number of variables in the primitive set
- categories –
Returns: Note
All functions will be closed, that is non-defined values will be mapped to 1. 1/0 = 1!
-
pretty_print
(expr, constants, consts_values, count=0)[source]¶ Replace symbolic constants in the str representation of an individual by their numeric values.
- This checks for
- c followed by “)” or “,”
- c followed by infix operators
- c
-
sc_mmqout
(x, y, cmin=-1, cmax=1)[source]¶ SC is the minimum-maximum quotient of the number of nodes of both child-trees x and y mapped into the constant interval [cmin, cmax]
-
sc_qout
(x, y)[source]¶ SC is the quotient of the number of nodes of its left and right child-trees x and y
-
sympy_phenotype
(individual)[source]¶ Compile python function from individual.
Uses sympy’s lambdify function. Terminals from the primitive set will be used as parameters to the constructed lambda function; primitives (like sympy.exp) will be converted into numpy expressions (eg. numpy.exp).
Parameters: individual ( glyph.gp.individual.AExpressionTree
) –Returns: lambda function
-
sympy_primitive_set
(categories=('algebraic', 'trigonometric', 'exponential'), arguments=['y_0'], constants=[])[source]¶ Create a primitive set with sympy primitves.
Parameters: - arguments – variables to use in primitive set
- constants – symbolic constants to use in primitive set
- categories –
- an optional list of function categories for the primitive set. The following are available
- ’algebraic’, ‘neg’, ‘trigonometric’, ‘exponential’, ‘exponential’, ‘logarithm’, ‘sqrt’.
return: deap.gp.PrimitiveSet
Collection of helper functions for arparse.
-
class
SoftTimeOut
(ttl)[source]¶ Bases:
object
Break condition based on a soft time out.
Start a new generation as long as there is some time left.
Parameters: ttl – time to live in seconds -
alive
¶
-
now
¶
-
-
break_condition
(target=0, error_index=0, ttl=0, max_iter=inf)[source]¶ Combined breaking condition based on time to live, minimum target and maximum number of iterations.
Parameters: - target – value of desired error metric
- error_index – index in fitness tuple
- ttl – time to live in seconds
- max_iter – maximum number of iterations
-
load_config
(config_file, placeholders=None, level=20)[source]¶ Load logging configuration from .yaml file.
-
class
SlowConversionTerminator
(method, step_size=10, min_stat=10, threshold=25)[source]¶ Bases:
object
Decorate a minimize method used in
scipy.optimize.minimize
to cancel non promising constant optimizations.The stopping criteria is based on the improvement rate :math:`rac{Delta f}[Delta fev}`.
If the improvement rate is below thequantile for a given number of function evaluations, optimization is stopped. :params method: see
scipy.optimize.minimize
method :params step_size: number of function evaluations betweem iterations :params min_stat: minimum sample size before stopping :params threshold: quantile
-
hill_climb
(fun, x0, args, precision=5, maxfev=100, directions=5, target=0, rng=<module 'numpy.random' from '/home/docs/checkouts/readthedocs.org/user_builds/glyph/envs/stable/lib/python3.6/site-packages/numpy/random/__init__.py'>, **kwargs)[source]¶ Stochastic hill climber for constant optimization. Try self.directions different solutions per iteration to select a new best individual.
Parameters: - fun – function to optimize
- x0 – initial guess
- args – additional arguments to pass to fun
- precision – maximum precision of x0
- maxfev – maximum number of function calls before stopping
- directions – number of directions to explore before doing a hill climb step
- target – stop if fun(x) <= target
- rng – (seeded) random number generator
Returns:
-
class
Memoize
(fn)[source]¶ Bases:
object
Memoize(fn) - an instance which acts like fn but memoizes its arguments
Will only work on functions with non-mutable arguments http://code.activestate.com/recipes/52201/
-
partition
(pred, iterable)[source]¶ Use a predicate to partition entries into false entries and true entries.
>>> is_odd = lambda x: x % 2 >>> odd, even = partition(is_odd, range(10)) >>> list(odd) [0, 2, 4, 6, 8]
-
random_state
(obj, rng=<module 'random' from '/home/docs/checkouts/readthedocs.org/user_builds/glyph/envs/stable/lib/python3.6/random.py'>)[source]¶ Do work inside this contextmanager with a random state defined by obj.
Looks for _prev_state to seed the rng. On exit, it will write the current state of the rng as _tmp_state to the obj.
Params obj: Any object. Params rng: Instance of a random number generator.
Submodules¶
glyph.application module¶
Convenience classes and functions that allow you to quickly build gp apps.
-
class
AlgorithmFactory
[source]¶ Bases:
glyph.application.AFactory
Factory class for gp algorithms.
-
class
Application
(config, gp_runner, checkpoint_file=None, callbacks=(<function make_checkpoint>, <function log>))[source]¶ Bases:
object
An application based on
GPRunner
.Controls execution of the runner and adds checkpointing and logging functionality; also defines a set of available command line options and their default values.
To create a full console application one can use the factory function default_console_app().
Parameters: - config (dict or argparse.Namespace) – Container holding all configs
- gp_runner – Instance of
GPRunner
- checkpoint_file – Path to checkpoint_file
- callbacks –
-
assessment_runner
¶
-
logbook
¶
-
run
(break_condition=None)[source]¶ Run gp app.
Parameters: break_condition (callable(application)) – is called after every evolutionary step. Returns: number of iterations executed during run.
-
workdir
¶
-
class
ConstraintsFactory
[source]¶ Bases:
glyph.application.AFactory
-
class
CreateFactory
[source]¶ Bases:
glyph.application.AFactory
Factory class for creation
-
class
GPRunner
(IndividualClass, algorithm_factory, assessment_runner, callbacks=(<function update_pareto_front>, <function update_logbook_record>))[source]¶ Bases:
object
Runner for gp problem sets.
Takes care of propper initialization, execution, and accounting of a gp run (i.e. population creation, random state, generation count, hall of fame, and logbook). The method init() has to be called once before stepping through the evolution process with method step(); init() and step() invoke the assessment runner.
Parameters: - IndividualClass – Class inherited from gp.AExpressionTree.
- algorithm_factory – callable() -> gp algorithm, as defined in gp.algorithms.
- assessment_runner – callable(population) -> None, updates fitness values of each invalid individual in population.
-
class
MateFactory
[source]¶ Bases:
glyph.application.AFactory
Factory class for gp mating functions.
-
class
MutateFactory
[source]¶ Bases:
glyph.application.AFactory
Factory class for gp mutation functions.
-
class
ParallelizationFactory
[source]¶ Bases:
glyph.application.AFactory
Factory class for parallel execution schemes.
-
class
SelectFactory
[source]¶ Bases:
glyph.application.AFactory
Factory class for selection
-
default_console_app
(IndividualClass, AssessmentRunnerClass, parser=ArgumentParser(prog='sphinx-build', usage=None, description=None, formatter_class=<class 'argparse.HelpFormatter'>, conflict_handler='error', add_help=True), callbacks=(<function make_checkpoint>, <function log>))[source]¶ Factory function for a console application.
-
default_gprunner
(Individual, assessment_runner, callbacks=(<function update_pareto_front>, <function update_logbook_record>), **kwargs)[source]¶ Create a default GPRunner instance.
For config options see
MateFactory
,MutateFactory
,AlgorithmFactory
.
glyph.assessment module¶
Some usefull classes/functions for the fitness assessment part in gp problems.
-
class
AAssessmentRunner
(parallel_factory=<glyph.assessment.SingleProcessFactory object>)[source]¶ Bases:
object
Abstract runner for the (parallel) assessment of individuals in a population.
Child classes have to at least override the measure() method, which might be executed in a different process or even on a remote machine depending on the parallelization scheme. Child classes may override the setup() method, which is executed once on object instantiation. Child classes may override the assign_fitness() method, which is executed in the main process. This can be usefull if you want to locally post-process the results of measure(), when collected from remote processes.
Parameters: parallel_factory – callable() -> obj, obj has to implement some kind of (parallel) map() method. -
__call__
(population)[source]¶ Update the fitness of each individual in population that has an invalid fitness.
Parameters: population – a squence of individuals.
-
__getstate__
()[source]¶ Modify pickling behavior for the class.
All the attributes except ‘parallel’ can be pickled.
-
-
const_opt
(measure, individual, lsq=False, default_constants=<function default_constants>, f_kwargs=None, **kwargs)[source]¶ Apply constant optimization
Parameters: - measure – callable(individual, *f_args) -> scalar.
- individual – an individual tha is passed on to measure.
- bounds – bounds for the constant values (s.
scipy.optimize.minimize
). - method – Type of solver. Should either be ‘leastsq’, or one of scipy.optimize.minimize’s solvers.
Returns: (popt, measure_opt), popt: the optimal values for the constants; measure_opt: the measure evaluated at popt.
-
const_opt_leastsq
(measure, individual, default_constants=<function default_constants>, f_kwargs=None, **kwargs)[source]¶
-
default_constants
(ind)[source]¶ Return a one for each different constant in the primitive set.
Parameters: ind ( glyph.gp.individual.AExpressionTree
) –Returns: A value for each constant in the primitive set.
-
max_fitness_on_timeout
(max_fitness, timeout)[source]¶ Decorate a function. Associate max_fitness with long running individuals.
Parameters: - max_fitness – fitness of aborted individual calls.
- timeout – time until timeout
Returns: fitness or max_fitness
-
measure
(*funcs, pre=<function identity>, post=<function identity>)[source]¶ Combine several measurement functions into one.
Optionaly do pre- and/or post-processing.
Parameters: - funcs – a sequence of measure functions as returned by measure() (eg.
callable(*a, **kw) -> tuple
), and/or single valued functions (eg.callable(*a, **kw)
-> numerical value). - pre – some pre-processing function that is to be apllied on input once before passing the result to each function in funcs.
- post – some post-processing function that is to be apllied on the tuple of measure values as returned by the combined funcs.
Returns: callable(input) -> tuple of measure values, where input is usually a phenotype (eg. an expression tree).
- funcs – a sequence of measure functions as returned by measure() (eg.
glyph.observer module¶
-
class
ProgressObserver
[source]¶ Bases:
object
Animates the progress of the evolutionary optimization.
Note
Uses matplotlib’s interactive mode.
-
__call__
(app)[source]¶ Note
To be used as a callback in
glyph.application.Application
.Parameters: app (glyph.application.Application) –
-