Skip to main content

wrapper to call fortran routines from SEISCOPE optimization toolbox

Project description

GitHub release (latest by date) Build Status last-commit DOI codecov Code style: black

sotb-wrapper: A Python wrapper for the SEISCOPE optimization toolbox (using Ctypes)

This repo demonstrates how it is possible to use the SEISCOPE optimization toolbox (written in Fortran) from Python. The original code is public domain and was written by Ludovic Métivier and Romain Brossier. Minor changes to the original code have been made to allow the call of the gradient-based optimization subroutines from Python. Such changes and some improvements are listed as follows.

  • The original source organized in 6 subdirectories (each of which is associated with one gradient-based algorithm) was placed in only one folder in a modular fashion. That is, one module for each optimization algorithm grouping the procedures from each one of the old subdirectories.
  • The Euclidean vector norm and scalar product calculations were replaced with calls to the intrinsic Fortran norm2 and dot_product functions, respectively.
  • Removing Trivial Code Duplication: i.e., same procedures in Steepest Descent and Preconditioned Nonlinear Conjugate Gradient subdirectories.
  • Removing unused variable declarations.
  • Vectors of lower and upper bounds (box constraints) are now optional arguments in the optimization subroutines instead of array components of a derived data type

The SEISCOPE toolbox uses a derived data type (optim); functionality that is not yet supported at this time by f2py - and for this reason it is used ctypes. The optim data type is maintained, but without allocatable arrays.

The repo contains a src directory with the modified fortran source files and another named apps where each method is used to find the minimum of the banana Rosenbrock function. The python wrapper for the SEISCOPE optimization toolbox is found inside the sotb_wrapper directory. A test directory includes a script to check that the wrapper has suceeded in reproducing the results of the original fortran code.

Install Seiscope optimization toolbox (sotb)

If you only want to use the Fortran library, you can simply clone the repo and build it with Fortran Package Manager or CMake. In the first case you just need to run

fpm build --profile release

This command creates the library in static form, as originally designed as well as executable files from demo codes.

To use sotb within your fpm project, add the following to your fpm.toml file:

[dependencies]
sotb = { git="https://github.com/ofmla/seiscope_opt_toolbox_w_ctypes.git" }

In the second case, you can run a workflow as the following:

FC=gfortran cmake -B _build -DCMAKE_INSTALL_PREFIX=$PREFIX -DCMAKE_BUILD_TYPE=Release
cmake --build _build
cmake --install _build

where you need to replace $PREFIX with the desired directory.

Examples of use of sotb can be found in the app folder, which contains a folder with an example for each one of the optimization algorithms available in the library. The executable files for each example are built with cmake invocation above and made available at $PREFIX/bin folder. As mentioned before, when you use fpm, executable files for the examples are also created. In this latest case, you can use fpm run --profile release <test_name> to run an specific example. So, if you want to run the example that uses the limited-memory version of Broyden-Fletcher-Goldfarb-Shanno (L-BFGS) algorithm, simply run fpm run --profile release test_LBFGS. If you run fpm run --profile release you can see the names of the six available examples. You can also find a simple example on calling the Fortran subroutines from a C main program in the c_code directory. The example uses the L-BFGS to minimize the Rosenbrock's "banana function". Assuming that $PREFIX points to the repository root directory, you can create the executable from c_code directory, by running

cmake -S. -B _build -DCMAKE_PREFIX_PATH="`pwd`/../../"
cmake --build _build

or

cmake -S. -B _build -Dsotb_DIR="`pwd`/../../lib/cmake/sotb"
cmake --build _build

Install the python wrapper of sotb (sotb-wrapper)

To install the Python API with the embedded sotb shared library you can use pip.

pip install sotb-wrapper

It is also possible to install directly from the GitHub repository. You will need a Fortran compiler such as GFortran to compile the shared library but the whole process is automated via scikit-build.

pip install git+https://github.com/ofmla/seiscope_opt_toolbox_w_ctypes

Usage

The following example demonstrates how to define and solve the classical Rosenbrock problem

import numpy as np
from sotb_wrapper import interface

# Declare the objective function
def rosenbrock(X):
    """
    http://en.wikipedia.org/wiki/Rosenbrock_function
    A generalized implementation is available
    as the scipy.optimize.rosen function
    """
    a = 1. - X[0]
    b = X[1] - X[0]*X[0]
    return a*a + b*b*100., np.array([-a*2. - 400.*X[0]*b, 200.*b], dtype=np.float32)
    
# Create an instance of the SEISCOPE optimization toolbox wrapper (sotb_wrapper) Class. 
sotb = interface.sotb_wrapper()
n = 2 # dimension
flag = 0 # first flag; 0 means initialization
X = np.ones(2, dtype=np.float32)*-1. # initial guess

# computation of the cost and gradient associated with the initial guess
fcost, grad = rosenbrock(X)
# copy of grad in grad_preco: no preconditioning in this test
grad_preco = np.copy(grad)
# Set parameters of the UserDefined derived type in Fortran (ctype structure).
# The first two parameters are mandatory; all others are optional. 
sotb.set_inputs(fcost, 10000, conv=1e-8, l=10)

# optimization loop: while convergence not reached or linesearch not failed, iterate
while (flag != 2 and flag != 4):
    flag = sotb.PSTD(n, X, fcost, grad, grad_preco, flag)
    if flag == 1:
        # compute cost and gradient at point x
        fcost, grad = rosenbrock(X)
        # no preconditioning in this test: simply copy grad in grad_preco
        grad_preco = np.copy(grad)
print('FINAL iterate is : ', X)

The code above is part of a tutorial in the form of a Jupyter notebook (rosenbrock.ipynb) provided in the examples subdirectory. The goal of the tutorial is show you how one can use sotb-wrapper to find a minimum for a problem, which can optionally be subject to bound constraints (also called box constraints). The directory also includes examples in the context of geophysical inversion. Note that you must have Devito in order to be able to run them. A python script plot_curves.py is also provide in the examples directory. It may not be the best implementation and is intended for illustrative purposes only.

The following figures were obtained with the plot_curves.py script after ran one of the examples (lsrtm_aniso.py).

License

sotb-wrapper is distributed under the MIT license. See the included LICENSE file for details.

See also

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sotb-wrapper-2.0.0.tar.gz (1.1 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

sotb_wrapper-2.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.2 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

sotb_wrapper-2.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.2 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ x86-64

sotb_wrapper-2.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.2 MB view details)

Uploaded CPython 3.8manylinux: glibc 2.17+ x86-64

sotb_wrapper-2.0.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.2 MB view details)

Uploaded CPython 3.7mmanylinux: glibc 2.17+ x86-64

sotb_wrapper-2.0.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.2 MB view details)

Uploaded CPython 3.6mmanylinux: glibc 2.17+ x86-64

File details

Details for the file sotb-wrapper-2.0.0.tar.gz.

File metadata

  • Download URL: sotb-wrapper-2.0.0.tar.gz
  • Upload date:
  • Size: 1.1 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.9.13

File hashes

Hashes for sotb-wrapper-2.0.0.tar.gz
Algorithm Hash digest
SHA256 d742645383208bed6da3f9a5677d109f2642172ba8bc90289b86ec28dbc3f3e3
MD5 84d2d432eb325ec176d83d20abefe4b5
BLAKE2b-256 7bc0815bec4eaf6f1fd02e4ce6a6ade2c2b66e242ee24f77af88837a658e1a3b

See more details on using hashes here.

File details

Details for the file sotb_wrapper-2.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for sotb_wrapper-2.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 6aebd0db2a88a5396f6b41a8aba08914a0d5fdec2287e147e6fa3f0bd2cc567e
MD5 cb2d25ae54b39b038535b0a4bb6efc2d
BLAKE2b-256 fa799f19920ad7c176d48be6f512e57a23e079fd01b0fc0abf1a4d9f3b398f2a

See more details on using hashes here.

File details

Details for the file sotb_wrapper-2.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for sotb_wrapper-2.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 55e0645f6076232b56ab448e2da04378c64ed6a12e6bcc168db0f894b695fc12
MD5 c0cc88d3a19ad48b2f005d9822e8504d
BLAKE2b-256 40087882695cb780ec6fd07ab348186961a486080464da4c735520a727a6062d

See more details on using hashes here.

File details

Details for the file sotb_wrapper-2.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for sotb_wrapper-2.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 a2270e5d0b08387ccd876b32d5ecf18123cf669b7e668061a9009e38e0e8ada7
MD5 3e88e7d2e2f385bc89abe7934cd386da
BLAKE2b-256 66f89b1e1ac648becfbb7d64a27101cb3ea75b0f02a741c5963e60d9f374372b

See more details on using hashes here.

File details

Details for the file sotb_wrapper-2.0.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for sotb_wrapper-2.0.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 1e406b36c83e77d78a9e2e440aef4a595aa72b47a5d97a146db39180b6eb0b2b
MD5 6a55d17ad26e5b9ce1c6425295ad767a
BLAKE2b-256 85e92df528d7e3cdc1f3a3c0b628b94157e3428dc79d52e3f519596f7ce010b8

See more details on using hashes here.

File details

Details for the file sotb_wrapper-2.0.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for sotb_wrapper-2.0.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 3a526b0312390321315d59e699364ee1453e478950adc651d1ddb25c85106c93
MD5 e71b970a6c4f03adfc7c5f7a003a83fc
BLAKE2b-256 ac67701b24ec811213e0d173e9ec71f63d8aa966f3ac56b06701a8fdb25708a6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page