Skip to content

Commit

Permalink
Merge branch 'release/v0.6.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
markcoletti committed Jun 13, 2021
2 parents d9bc0b2 + e2d5479 commit 7b0638d
Show file tree
Hide file tree
Showing 123 changed files with 12,427 additions and 6,204 deletions.
25 changes: 12 additions & 13 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# Just copied of .gitignore that covers All The Things. (Hopefully.)
#
/tmp.*
/local
*.log
Expand All @@ -11,46 +9,46 @@ docker-nom/build/
venv/
*.egg-info/
docs/build/
.coverage
.coverage*
htmlcov/
.ipynb_checkpoints/
.pytest_cache
build/
dist/

#Subversion
# Subversion
.svn


#Vim (and some others)
# Vim (and some others)
*~
*.swp

#Eclipse
# Eclipse
.cache
.classpath
.project
.settings
build-eclipse

#Gradle
# Gradle
.gradle
gradle-app.setting

#Sublime Text
# Sublime Text
*.sublime-workspace

#NetBeans
# NetBeans
.netbeans
catalog.xml
generated
nb-configuration.xml

#Mac OS
# Mac OS
.DS_Store
__MACOSX

#Intellij
# Intellij
.idea/
.idea/workspace.xml
.idea/libraries
Expand All @@ -75,10 +73,11 @@ __MACOSX
.idea/misc.xml
.idea/modules.xml


#vscode
# vscode
.vscode

# dask
dask-worker-space/

# Generated data
*.csv
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ language: python

# Versions of Python to test with
python:
- "3.6"
- "3.7"
- "3.8"
- "3.9"
Expand Down
70 changes: 69 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,70 @@

Being a terse compilation by version of changes.

## 0.6.0
## 0.7.0

## 0.6.0, 6/13/2021

* Drop support for Python 3.6
* This keeps us in sync with numpy and dask that also dropped support for 3.6 this year

* New features
* Added `landscape_features` package with some initial exploratory landscape analysis tools
* Added elitism
* Added a new example demonstrating integer representations
* Added a `mutate_binomial()` operator for integer representations
* Added visualization of ANN weights for `SimpleNeuralNetworkExecutable` phenotypes
* Added metrics for logging population diversity
* Added support for lexicographical and Koza-style parsimony pressure
* Added `HistPhenotypePlotProbe`
* Added `ops.grouped_evaluate()` for evaluating batches of individuals
* Added `ExternalProcessproblem` for using external programs as fitness functions

* Documentation
* Added documentation on `leap_ec.context` and updated software development
guidelines to encourage its use if tracking persistent state outside of
function calls was necessary.

* CI/CD
* Added a `make test-slow` harness
* Added tests that run the `examples/` scripts
* Organized examples into subdirectories
* Improved test coverage

* Bugfixes
* Fix `viz` parameter when calling `simple.ea_solve()`
* Fix algebra error in `real_rep.problems.NoisyQuarticProblem`
* Tell `dask` that functions are impure by default, to make sure it doesn't cache results
* Change `Makefile` to use `pip install -e .` instead of the deprecated `python setup.py develop`

* API changes
* Significantly refactored the `executable_rep.rules` package to simplify learning classifier systems
* Added `leap_ec.__version__` attribute
* Added a `hard_bounds` flag to `ea_solve()` to tell it to respect the `bounds` at all times (rather than just initialization); defaults to `True`
* Added the most frequent imports (ex. `Individual`, `Representation`) into the top-level package
* Renamed the `generations` parameter of `generational_ea()` to `max_generations` and added an optional `stop` parameter for other stopping conditions
* Added probability parameter for the `uniform_crossover` operator
* `mutate_gaussian` now accepts a list of gene-wise hard bound
* Added `select_worst` Boolean parameter to `tournament_selection`
* Added `notes` columns parameter to `FitnessStatsCSVProbe`
* Added a `pad_inputs` parameter to `TruthTableProblem` to handle varying-dimension inputs
* Added a `pad` parameter to `CartesianPhenotypePlotProbe` to plot 2D projections of higher-D functions
* Added `FitnessPlotProbe` as a convenience wrapper for `PopulationMetricsPlotProbe`
* Added an `x_axis_value` parameter to `FitnessPlotProbe` and `PopulationMetricsPlotProbe`
* Renamed `PlotTrajectoryProbe` to the more descriptive `CartesianPhenotypePlotProbe`
* Renamed `PopulationPlotProbe` to the more descriptive `PopulationMetricsPlotProbe`
* Renamed `leap_ec.distributed` to `leap_ec.distrib` to reduce name space
confusion with `dask.distributed`
* Renamed `leap_ec.context` to `leap_ec.global_vars`
* Default behavior changes
* `Individual.decoder` and `Representation.decoder` now uses a phenotypic representation (`IdentityDecoder`) by default
* Mutation operators no longer have default mutation rates (they must be explicitly set by the user).
* Set default `p_swap = 0.2` for `uniform_crossover`, instead of 0.5
* Set default `num_points = 2` for `n_ary_crossover`, instead of 1
* Set default value for `context` parameter on probes, so users needn't set it
* standardized on making `context` last function argument that defaults to
`leap_ec.context.context`


## 0.5.0, 1/9/2021

Expand All @@ -16,6 +79,7 @@ Being a terse compilation by version of changes.
* Added a Cartesian genetic programming (CGP) representation, `executable_rep.cgp`, with example in `examples/cgp.py`
* Added support for heterogeneous island models, demoed in `examples/multitask_island_model.py`


## 0.4.0, 9/19/2020

* Significantly added to online [documentation](https://leap-gmu.readthedocs.io/en/latest/index.html)
Expand All @@ -33,21 +97,25 @@ Being a terse compilation by version of changes.
that could be used to name output files and directories, yet do not have a
direct impact on fitness


## 0.3.1

* Apply `Representation` consistently throughout LEAP, particularly the top-level monolithic functions
* Added probe to `leap_ec.distributed.asynchronous.steady_state()` to take regular snapshots of the population


## 0.3, 6/14/2020

* fix how non-viable individuals sort themselves when compared since the prior method of comparing `math.nan` to `math.nan` yielded non-ideal behavior
* minor maintenance tweaks


## 0.2, 6/14/2020

* changed package name to `leap_ec` from `leap` to mitigate pypi namespace collisions
* minor maintenance tweaks


## 0.1

* first major "mature" release of LEAP
8 changes: 5 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@ venv:
.PHONY: doc setup test test-fast test-slow kernel test-jupyter clean

doc:
pip install -r docs/requirements.txt
# The apidoc call is long because we need to tell it to
# use the venv's version of sphinx-build
sphinx-apidoc -f -o docs/source/ leap_ec/ SPHINXBUILD='python $(shell which sphinx-build)'
cd docs && make html

setup:
python setup.py develop
pip install -e .
pip install -r test_requirements.txt

depend:
pip install -r requirements_freeze.txt
Expand All @@ -52,10 +54,10 @@ test:
python -m pytest -m "not jupyter"

test-fast:
python -m pytest -m "not system and not jupyter"
python -m pytest -m "not slow and not jupyter"

test-slow:
python -m pytest -m system
python -m pytest -m slow

kernel:
# Setup a kernel for Jupyter with the name test-jupyter uses to find it
Expand Down
15 changes: 7 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ from leap_ec.binary_rep import problems
from leap_ec.binary_rep.ops import mutate_bitflip

pop_size = 5
ea = generational_ea(generations=10, pop_size=pop_size,
ea = generational_ea(max_generations=10, pop_size=pop_size,

# Solve a MaxOnes Boolean optimization problem
problem=problems.MaxOnes(),
Expand All @@ -77,11 +77,12 @@ ea = generational_ea(generations=10, pop_size=pop_size,
),

# The operator pipeline
pipeline=[ops.tournament_selection,
pipeline=[
# Select parents via tournament_selection selection
ops.tournament_selection,
ops.clone, # Copy them (just to be safe)
# Basic mutation: defaults to a 1/L mutation rate
mutate_bitflip,
# Basic mutation with a 1/L mutation rate
mutate_bitflip(expected_num_mutations=1),
# Crossover with a 40% chance of swapping each gene
ops.uniform_crossover(p_swap=0.4),
ops.evaluate, # Evaluate fitness
Expand Down Expand Up @@ -132,7 +133,7 @@ while generation_counter.generation() < 6:
offspring = pipe(parents,
ops.tournament_selection,
ops.clone,
mutate_bitflip,
mutate_bitflip(expected_num_mutations=1),
ops.uniform_crossover(p_swap=0.2),
ops.evaluate,
ops.pool(size=len(parents))) # accumulate offspring
Expand All @@ -150,7 +151,7 @@ A number of LEAP demo applications are found in the the `example/` directory of

```bash
git clone https://github.com/AureumChaos/LEAP.git
python LEAP/example/island_models.py
python LEAP/examples/advanced/island_models.py
```

![Demo of LEAP running a 3-population island model on a real-valued optimization problem.](_static/island_model_animation.gif)
Expand Down Expand Up @@ -201,5 +202,3 @@ make test-slow
respectively.

![pytest output example](_static/pytest_output.png)


102 changes: 102 additions & 0 deletions docs/GUIDELINES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# LEAP SOFTWARE DEVELOPMENT GUIDELINES

This document provides guidance on developing for this project.

## PEP8 style compliance

Code should be [PEP8](https://www.python.org/dev/peps/pep-0008/) compliant,
wherever possible. However, we're a little relaxed when it comes to
whitespaces, and enforcing wrapping at column 80 for block comments. The
latter addresses situations where URLs and paths just won't nicely fit
within 80 columns.

We recommend the [`flake8`](https://pypi.org/project/flake8/) PEP8 linter.

## Modules, classes, and functions should have docstrings.

Essentially, everything that can have a docstring, should have a docstring,
which mostly captures the spirit of [PEP 257](https://www.python.org/dev/peps/pep-0257/)
for new code.

## We encourage use of Rich Structure Formatted descriptors in docstrings

[PEP 287](https://www.python.org/dev/peps/pep-0287/) specifies use of reStructuredText Docstring formats for docstrings,
though it doesn't do a good job of specifying on standardizing docstring
content.

Generally, for functions we try to document them with this docstring pattern:

```python
def foo(a, b, c):
""" One liner summary for foo
:param a: does this
:param b: does that
:param c: does something else
:returns: a * b * c
"""
return a * b * c
```

## We encourage use of type hints
[PEP 484](https://www.python.org/dev/peps/pep-0484/) describes the python3 type
hint syntax, and we encourage its use.

(However, we admit at the time of this writing that we, ourselves, are
inconsistent in the LEAP implementation, and which we will address at a
later point.)

## We encourage inclusion of comment blocks before functions and classes
We have an admittedly idiosyncratic standard for including a comment block
of this form before functions and classes:

```python
##############################
# Class ExampleClass
##############################
```

And:

```python
##############################
# Function foo()
##############################
```

Some editors support a summary window of the entire file, such as sublime
and PyCharm, and sometimes those types of comment blocks stand out in those
windows to make it easier to pick out module organization.

(We confess we're not consistent in doing this ourselves, but we're trying
to get better at enforcement.)

## We encourage the use of doctests

[Doctests](https://docs.python.org/3/library/doctest.html) are a handy way to not only provide examples of use, but provide a
simple unit test for a given function. With that in mind, we also encourage
the writing of doctests for any new functions.

## We encourage implementation of unittest

We also encourage the inclusion of unittests that will be regularly
exercised in our CI pipeline after pushing to the central repository. You
can see examples of existing unit tests in `./tests`.

Note that we also have stochastic unit tests, which are important for
evolutionary algorigthms because they're inherently stochastic.

## Use `leap_ec.context` to track state

`leap_ec.context` to track state that needs to persist outside, say, pipeline
operators or function invocations. If you create a new operator or that
function that relies on `leap_ec.context`, please make it the last argument
and have it default to `leap_ec.context.context`.


## Add an optional `key` argument for new selection operators

Add an optional `key` argument for selection operators as seen for `max()`
and `sort()` because this allows for passing in functions for changing the
default selection criteria. One common use for this is to add in parsimony
pressure.
5 changes: 1 addition & 4 deletions docs/release_procedure.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ These are the things to do when performing a release.
1. git pull
> to ensure in sync with develop latest
1. git flow release start 'new release number'
1. update release number everywhere
1. `setup.py`
1. `docs/source/conf.py`
> this is for the ReadTheDocs version number
1. update release number in `leap_ec/__version__.py` (`setup.py` pulls the version number from here)
1. update CHANGELOG.md
1. if necessary sync `docs/source/roadmap.rst` with realistic expectations
1. git flow release finish 'new release number'
Expand Down
4 changes: 4 additions & 0 deletions docs/source/bibliography.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
References
==========

.. bibliography::leap.bib
1 change: 1 addition & 0 deletions docs/source/concepts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,5 @@ sections.
Operators <ops>
Contexts <context>
Probes <probes>
Parsimony <parsimony>
Visualizations <visualization>
Loading

0 comments on commit 7b0638d

Please sign in to comment.