{"id":37080085,"url":"https://github.com/ofmla/seiscope_opt_toolbox_w_ctypes","last_synced_at":"2026-01-14T09:43:06.390Z","repository":{"id":57771846,"uuid":"341695999","full_name":"ofmla/seiscope_opt_toolbox_w_ctypes","owner":"ofmla","description":"This repo shows how to use SEISCOPE optimization toolbox Fortran code from Python","archived":false,"fork":false,"pushed_at":"2023-11-14T13:13:40.000Z","size":2506,"stargazers_count":30,"open_issues_count":0,"forks_count":8,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-09-29T16:02:04.804Z","etag":null,"topics":["ctypes-wrapper","fortran","fortran-package-manager","geophysics","gradient-based-optimisation","python-bindings","wrapper-library"],"latest_commit_sha":null,"homepage":"","language":"Fortran","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ofmla.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-02-23T21:32:10.000Z","updated_at":"2025-06-23T16:46:44.000Z","dependencies_parsed_at":"2024-01-12T15:11:18.106Z","dependency_job_id":null,"html_url":"https://github.com/ofmla/seiscope_opt_toolbox_w_ctypes","commit_stats":{"total_commits":145,"total_committers":1,"mean_commits":145.0,"dds":0.0,"last_synced_commit":"74a25c29d13c506e16f8025eb13a2cf396dc23c0"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/ofmla/seiscope_opt_toolbox_w_ctypes","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ofmla%2Fseiscope_opt_toolbox_w_ctypes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ofmla%2Fseiscope_opt_toolbox_w_ctypes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ofmla%2Fseiscope_opt_toolbox_w_ctypes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ofmla%2Fseiscope_opt_toolbox_w_ctypes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ofmla","download_url":"https://codeload.github.com/ofmla/seiscope_opt_toolbox_w_ctypes/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ofmla%2Fseiscope_opt_toolbox_w_ctypes/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28416120,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T08:38:59.149Z","status":"ssl_error","status_checked_at":"2026-01-14T08:38:43.588Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ctypes-wrapper","fortran","fortran-package-manager","geophysics","gradient-based-optimisation","python-bindings","wrapper-library"],"created_at":"2026-01-14T09:43:05.605Z","updated_at":"2026-01-14T09:43:06.382Z","avatar_url":"https://github.com/ofmla.png","language":"Fortran","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![GitHub release (latest by date)](https://img.shields.io/github/v/release/ofmla/seiscope_opt_toolbox_w_ctypes)](https://github.com/ofmla/seiscope_opt_toolbox_w_ctypes/releases/tag/v1.0.1)\n![Build Status](https://github.com/ofmla/seiscope_opt_toolbox_w_ctypes/actions/workflows/python.yml/badge.svg)\n[![last-commit](https://img.shields.io/github/last-commit/ofmla/seiscope_opt_toolbox_w_ctypes)](https://github.com/ofmla/seiscope_opt_toolbox_w_ctypes/commits/main)\n[![DOI](https://zenodo.org/badge/341695999.svg)](https://zenodo.org/badge/latestdoi/341695999)\n[![codecov](https://codecov.io/gh/ofmla/seiscope_opt_toolbox_w_ctypes/branch/main/graph/badge.svg?token=BN7NK8A9OJ)](https://codecov.io/gh/ofmla/seiscope_opt_toolbox_w_ctypes)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n[![fpm](https://img.shields.io/badge/fpm-Fortran_package_manager-734f96)](https://fpm.fortran-lang.org)\n[![Fortran](https://img.shields.io/badge/Fortran-734f96?logo=fortran\u0026style=flat)](https://fortran-lang.org)\n\n\n# sotb-wrapper: A Python wrapper for the SEISCOPE optimization toolbox (using Ctypes)\n\nThis repo demonstrates how it is possible to use the [SEISCOPE optimization toolbox](https://seiscope2.osug.fr/SEISCOPE-OPTIMIZATION-TOOLBOX?lang=fr) (written in Fortran) from Python. The original code is public domain and was written by Ludovic Métivier\nand 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. \n * 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.\n *  The Euclidean vector norm and scalar product calculations were replaced with calls to the intrinsic Fortran ```norm2``` and ```dot_product``` functions, respectively.\n *  Removing Trivial Code Duplication: i.e., same procedures in Steepest Descent and Preconditioned Nonlinear Conjugate Gradient subdirectories.\n *  Removing unused variable declarations.\n *  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\n\nThe 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](https://docs.python.org/3/library/ctypes.html). The `optim` data type is maintained, but without allocatable arrays.\n\nThe 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.\n\n## Install Seiscope optimization toolbox (sotb)\n\nIf you only want to use the Fortran library, you can simply clone the repo and build it with [Fortran Package Manager](https://github.com/fortran-lang/fpm) or [CMake](https://cmake.org/). In the first case you just need to run \n```bash\nfpm build --profile release\n```\nThis command creates the library in static form, as originally designed as well as executable files from demo codes. \n\nTo use `sotb` within your fpm project, add the following to your `fpm.toml` file:\n\n```yml\n[dependencies]\nsotb = { git=\"https://github.com/ofmla/seiscope_opt_toolbox_w_ctypes.git\" }\n```\nIn the second case, you can run a workflow as the following:\n```bash\nFC=gfortran cmake -B _build -DCMAKE_INSTALL_PREFIX=$PREFIX -DCMAKE_BUILD_TYPE=Release\ncmake --build _build\ncmake --install _build\n```\nwhere you need to replace `$PREFIX` with the desired directory.\n\nExamples 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 \u003ctest_name\u003e` 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`](https://github.com/ofmla/seiscope_opt_toolbox_w_ctypes/tree/main/examples/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`](https://github.com/ofmla/seiscope_opt_toolbox_w_ctypes/tree/main/examples/c_code) directory, by running \n```bash\ncmake -S. -B _build -DCMAKE_PREFIX_PATH=\"`pwd`/../../\"\ncmake --build _build\n```\nor\n```bash\ncmake -S. -B _build -Dsotb_DIR=\"`pwd`/../../lib/cmake/sotb\"\ncmake --build _build\n```\n## Install the python wrapper of sotb (sotb-wrapper)\n\nTo install the Python API with the embedded `sotb` shared library you can use pip.\n```bash\npip install sotb-wrapper\n```\nIt 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](https://github.com/scikit-build/scikit-build).\n```bash\npip install git+https://github.com/ofmla/seiscope_opt_toolbox_w_ctypes\n```\n### Usage\n\nThe following example demonstrates how to define and solve the classical Rosenbrock problem\n```python\nimport numpy as np\nfrom sotb_wrapper import interface\n\n# Declare the objective function\ndef rosenbrock(X):\n    \"\"\"\n    http://en.wikipedia.org/wiki/Rosenbrock_function\n    A generalized implementation is available\n    as the scipy.optimize.rosen function\n    \"\"\"\n    a = 1. - X[0]\n    b = X[1] - X[0]*X[0]\n    return a*a + b*b*100., np.array([-a*2. - 400.*X[0]*b, 200.*b], dtype=np.float32)\n    \n# Create an instance of the SEISCOPE optimization toolbox wrapper (sotb_wrapper) Class. \nsotb = interface.sotb_wrapper()\nn = 2 # dimension\nflag = 0 # first flag; 0 means initialization\nX = np.ones(2, dtype=np.float32)*-1. # initial guess\n\n# computation of the cost and gradient associated with the initial guess\nfcost, grad = rosenbrock(X)\n# copy of grad in grad_preco: no preconditioning in this test\ngrad_preco = np.copy(grad)\n# Set parameters of the UserDefined derived type in Fortran (ctype structure).\n# The first two parameters are mandatory; all others are optional. \nsotb.set_inputs(fcost, 10000, conv=1e-8, l=10)\n\n# optimization loop: while convergence not reached or linesearch not failed, iterate\nwhile (flag != 2 and flag != 4):\n    flag = sotb.PSTD(n, X, fcost, grad, grad_preco, flag)\n    if flag == 1:\n        # compute cost and gradient at point x\n        fcost, grad = rosenbrock(X)\n        # no preconditioning in this test: simply copy grad in grad_preco\n        grad_preco = np.copy(grad)\nprint('FINAL iterate is : ', X)\n```\n\nThe code above is part of a tutorial in the form of a Jupyter notebook (`rosenbrock.ipynb`) provided in the [`examples`](https://github.com/ofmla/seiscope_opt_toolbox_w_ctypes/tree/main/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](https://www.devitoproject.org/) 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. \n\nThe following figures were obtained with the `plot_curves.py` script after ran one of the examples (`lsrtm_aniso.py`).\n\n\u003cimg src=\"./examples/computationalcost_curves.svg\" width=\"425\"/\u003e \u003cimg src=\"./examples/convergence_curves.svg\" width=\"425\"/\u003e \n\nLicense\n-----\n\nsotb-wrapper is distributed under the MIT license. See the included [`LICENSE`](https://github.com/ofmla/seiscope_opt_toolbox_w_ctypes/blob/main/LICENSE.md) file for details.\n\nSee also\n------\n * SEISCOPE optimization toolbox paper: https://library.seg.org/doi/10.1190/geo2015-0031.1\n * Original source code: http://seiscope2.osug.fr/IMG/tgz/TOOLBOX_22_09_2014_OPTIMIZATION.tgz\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fofmla%2Fseiscope_opt_toolbox_w_ctypes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fofmla%2Fseiscope_opt_toolbox_w_ctypes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fofmla%2Fseiscope_opt_toolbox_w_ctypes/lists"}