Skip to content

Commit

Permalink
Merge pull request #13 from keurfonluu/devel
Browse files Browse the repository at this point in the history
Add option verbosity and modernize repository
  • Loading branch information
keurfonluu committed Jun 5, 2023
2 parents 5f6625c + 7870075 commit 7fc532e
Show file tree
Hide file tree
Showing 25 changed files with 236 additions and 96 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.6, 3.7, 3.8, 3.9]
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
steps:
- uses: actions/setup-python@v2
with:
Expand Down
48 changes: 48 additions & 0 deletions .github/workflows/doc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Build documentation

on:
push:
branches:
- master
pull_request:

jobs:
docs:

runs-on: ubuntu-latest
env:
PYVISTA_OFF_SCREEN: 'True'
ALLOW_PLOTTING: true
SHELLOPTS: 'errexit:pipefail'

steps:
- uses: nschloe/action-cached-lfs-checkout@v1
- uses: actions/setup-python@v4
with:
python-version: '3.9'
- name: Install OSMesa VTK
run: |
sudo apt update
sudo apt install libosmesa6-dev libgl1-mesa-dev retry --option="APT::Acquire::Retries=3"
pip install https://github.com/pyvista/pyvista-wheels/raw/main/vtk-osmesa-9.1.0-cp39-cp39-linux_x86_64.whl
- name: Install libGLU for pygmsh
run: |
sudo apt install libglu1
- name: Install toughio
run: |
git lfs pull
pip install -e .[full]
- name: Install dependencies
run: |
pip install -r doc/requirements.txt
- name: Sphinx build
run: |
sphinx-build -b html doc/source doc/build
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
if: ${{ github.event_name == 'push' }}
with:
publish_branch: gh-pages
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: doc/build/
force_orphan: true
20 changes: 0 additions & 20 deletions .travis.yml

This file was deleted.

6 changes: 3 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
stochopy
========

|License| |Stars| |Pyversions| |Version| |Downloads| |Code style: black| |Codacy Badge| |Codecov| |Build| |Travis| |DOI|
|License| |Stars| |Pyversions| |Version| |Downloads| |Code style: black| |Codacy Badge| |Codecov| |Build| |Docs| |DOI|

**stochopy** provides functions for sampling or optimizing objective functions with or without constraints. Its API is directly inspired by **scipy**'s own optimization submodule which should make the switch from one module to another straightforward.

Expand Down Expand Up @@ -142,8 +142,8 @@ Related projects
.. |DOI| image:: https://zenodo.org/badge/DOI/10.5281/zenodo.4058008.svg?style=flat
:target: https://doi.org/10.5281/zenodo.4058008

.. |Build| image:: https://img.shields.io/github/workflow/status/keurfonluu/stochopy/Python%20package
.. |Build| image:: https://img.shields.io/github/workflow/status/keurfonluu/stochopy/ci.yml
:target: https://github.com/keurfonluu/stochopy

.. |Travis| image:: https://img.shields.io/travis/com/keurfonluu/stochopy/master?label=docs
.. |Docs| image:: https://img.shields.io/github/actions/workflow/status/keurfonluu/stochopy/doc.yml?label=docs
:target: https://keurfonluu.github.io/stochopy/
2 changes: 1 addition & 1 deletion doc/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ sphinx-argparse
sphinx-gallery
pydata-sphinx-theme
sphinxcontrib-bibtex
-e git://github.com/Naeka/pybtex-apa-style.git#egg=pybtex-apa-style
pybtex-apa-style
1 change: 0 additions & 1 deletion github_deploy_key_keurfonluu_stochopy.enc

This file was deleted.

4 changes: 3 additions & 1 deletion requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
black
build
docformatter
invoke
isort
pytest
pytest-cov
pytest-cov
twine
13 changes: 9 additions & 4 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = stochopy
version = 2.2.0
version = file: stochopy/VERSION
author = Keurfon Luu
email = keurfonluu@outlook.com
description = Python library for stochastic numerical optimization
Expand All @@ -16,18 +16,23 @@ classifiers =
License :: OSI Approved :: BSD License
Operating System :: OS Independent
Development Status :: 5 - Production/Stable
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11

[options]
packages = find:
install_requires =
importlib_metadata
numpy
joblib >= 0.12
python_requires = >= 3.6
python_requires = >= 3.7
setup_requires =
setuptools >= 42
wheel
wheel

[options.package_data]
stochopy =
VERSION
1 change: 1 addition & 0 deletions stochopy/VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2.3.0
16 changes: 8 additions & 8 deletions stochopy/__about__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
try:
from importlib import metadata
except ImportError:
import importlib_metadata as metadata
import pathlib

try:
__version__ = metadata.version("stochopy")
except Exception:
__version__ = "unknown"
__all__ = [
"__version__",
]


with open(f"{pathlib.Path(__file__).parent}/VERSION") as f:
__version__ = f.readline().strip()
7 changes: 4 additions & 3 deletions stochopy/optimize/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ class OptimizeResult(BaseResult):
nit : int
Number of iterations performed by the optimizer.
Notes
-----
Note
----
There may be additional attributes not listed above depending of the specific solver.
"""
Expand Down Expand Up @@ -70,7 +70,8 @@ def minimize(fun, bounds, x0=None, args=(), method="de", options=None, callback=
- maxiter (int): maximum number of iterations to perform
- seed (int or None): seed for random number generator
- return_all (bool): set to True to return an array of all the solutions at each iteration.
- return_all (bool): set to True to return an array of all the solutions at each iteration
- verbosity: fraction of population to consider in `return_all`
callback : callable or None, optional, default None
Called after each iteration. It is a callable with the signature ``callback(X, OptimizeResult state)``, where ``X`` is the current population and ``state`` is a partial :class:`stochopy.optimize.OptimizeResult` object with the same fields as the ones from the return (except ``"success"``, ``"status"`` and ``"message"``).
Expand Down
24 changes: 18 additions & 6 deletions stochopy/optimize/cmaes/_cmaes.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def minimize(
workers=1,
backend=None,
return_all=False,
verbosity=1.0,
callback=None,
):
"""
Expand Down Expand Up @@ -70,7 +71,9 @@ def minimize(
- 'mpi': use MPI (uses :mod:`mpi4py`)
return_all : bool, optional, default False
Set to True to return an array with shape (``nit``, ``popsize``, ``ndim``) of all the solutions at each iteration.
Set to True to return an array with shape (``nit``, ``verbosity`` * ``popsize``, ``ndim``) of all the solutions at each iteration.
verbosity : float, optional, default 1.0
Fraction of population to consider in `return_all`. If 0.0, returns the best solution at each iteration.
callback : callable or None, optional, default None
Called after each iteration. It is a callable with the signature ``callback(X, OptimizeResult state)``, where ``X`` is the current population and ``state`` is a partial :class:`stochopy.optimize.OptimizeResult` object with the same fields as the ones from the return (except ``"success"``, ``"status"`` and ``"message"``).
Expand Down Expand Up @@ -129,6 +132,7 @@ def minimize(
xtol,
ftol,
return_all,
verbosity,
callback,
)
res = cmaes(fun, args, True, workers, backend, *optargs)
Expand All @@ -153,6 +157,7 @@ def cmaes(
xtol,
ftol,
return_all,
verbosity,
callback,
):
"""Optimize with CMA-ES."""
Expand Down Expand Up @@ -197,16 +202,17 @@ def cmaes(
D = np.ones(ndim)
C = np.eye(ndim)
invsqrtC = np.eye(ndim)
chind = np.sqrt(ndim) * (1.0 - 1.0 / (4.0 * ndim) + 1.0 / (21.0 * ndim ** 2))
chind = np.sqrt(ndim) * (1.0 - 1.0 / (4.0 * ndim) + 1.0 / (21.0 * ndim**2))

# Initialize boundaries weights
bnd_weights = np.zeros(ndim)
dfithist = np.ones(1)

# Initialize arrays
if return_all:
xall = np.empty((maxiter, popsize, ndim))
funall = np.empty((maxiter, popsize))
nout = int(np.ceil(verbosity * popsize))
xall = np.empty((maxiter, max(1, nout), ndim))
funall = np.empty((maxiter, max(1, nout)))

# (mu, lambda)-CMA-ES
nfev = 0
Expand Down Expand Up @@ -253,8 +259,14 @@ def cmaes(
nfev += popsize

if return_all:
xall[it - 1] = unstandardize(arxvalid)
funall[it - 1] = arfitness.copy()
if nout > 0:
xall[it - 1] = unstandardize(arxvalid[:nout])
funall[it - 1] = arfitness[:nout].copy()

else:
idx = arfitness.argmin()
xall[it - 1] = unstandardize(arxvalid[idx])
funall[it - 1] = arfitness[idx].copy()

# Sort by fitness and compute weighted mean into xmean
arindex = np.argsort(arfitness)
Expand Down
2 changes: 1 addition & 1 deletion stochopy/optimize/cmaes/_constraints.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def Penalize(

# Get delta fitness values
perc = np.percentile(arfitness, [25.0, 75.0])
delta = (perc[1] - perc[0]) / ndim / diagC.mean() / sigma ** 2
delta = (perc[1] - perc[0]) / ndim / diagC.mean() / sigma**2

# Catch non-sensible values
if delta == 0:
Expand Down
34 changes: 27 additions & 7 deletions stochopy/optimize/cpso/_cpso.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def minimize(
workers=1,
backend=None,
return_all=False,
verbosity=1.0,
callback=None,
):
"""
Expand Down Expand Up @@ -79,7 +80,9 @@ def minimize(
- 'mpi': use MPI (uses :mod:`mpi4py`)
return_all : bool, optional, default False
Set to True to return an array with shape (``nit``, ``popsize``, ``ndim``) of all the solutions at each iteration.
Set to True to return an array with shape (``nit``, ``verbosity`` * ``popsize``, ``ndim``) of all the solutions at each iteration.
verbosity : float, optional, default 1.0
Fraction of population to consider in `return_all`. If 0.0, returns the best solution at each iteration.
callback : callable or None, optional, default None
Called after each iteration. It is a callable with the signature ``callback(X, OptimizeResult state)``, where ``X`` is the current population and ``state`` is a partial :class:`stochopy.optimize.OptimizeResult` object with the same fields as the ones from the return (except ``"success"``, ``"status"`` and ``"message"``).
Expand Down Expand Up @@ -168,6 +171,7 @@ def minimize(
xtol,
ftol,
return_all,
verbosity,
callback,
)
res = cpso(fun, args, sync, workers, backend, *optargs)
Expand All @@ -194,6 +198,7 @@ def cpso(
xtol,
ftol,
return_all,
verbosity,
callback,
):
"""Optimize with CPSO."""
Expand Down Expand Up @@ -226,10 +231,19 @@ def cpso(

# Initialize arrays
if return_all:
xall = np.empty((maxiter, popsize, ndim))
funall = np.empty((maxiter, popsize))
xall[0] = X.copy()
funall[0] = pfit.copy()
nout = int(np.ceil(verbosity * popsize))

if nout > 0:
xall = np.empty((maxiter, nout, ndim))
funall = np.empty((maxiter, nout))
xall[0] = X[:nout].copy()
funall[0] = pfit[:nout].copy()

else:
xall = np.empty((maxiter, 1, ndim))
funall = np.empty((maxiter, 1))
xall[0] = gbest
funall[0] = gfit

# First iteration for callback
if callback is not None:
Expand Down Expand Up @@ -269,8 +283,14 @@ def cpso(
)

if return_all:
xall[it - 1] = X.copy()
funall[it - 1] = pfit.copy()
if nout > 0:
xall[it - 1] = X[:nout].copy()
funall[it - 1] = pfit[:nout].copy()

else:
idx = pfit.argmin()
xall[it - 1] = X[idx].copy()
funall[it - 1] = pfit[idx].copy()

converged = status is not None

Expand Down

0 comments on commit 7fc532e

Please sign in to comment.