https://github.com/ripples-sci/ripples
Ripples is a scientific computation library that aims to provide a unified, numerically accurate, with good performance and easy to use framework for multi-discipline numerical work.
https://github.com/ripples-sci/ripples
differentiation optimization python ripples scientific-computing
Last synced: about 1 month ago
JSON representation
Ripples is a scientific computation library that aims to provide a unified, numerically accurate, with good performance and easy to use framework for multi-discipline numerical work.
- Host: GitHub
- URL: https://github.com/ripples-sci/ripples
- Owner: ripples-sci
- License: apache-2.0
- Created: 2026-06-01T01:45:32.000Z (about 1 month ago)
- Default Branch: main
- Last Pushed: 2026-06-01T02:59:23.000Z (about 1 month ago)
- Last Synced: 2026-06-01T03:15:42.666Z (about 1 month ago)
- Topics: differentiation, optimization, python, ripples, scientific-computing
- Language: Python
- Homepage:
- Size: 0 Bytes
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.txt
- Citation: CITATION.cff
- Notice: NOTICE
Awesome Lists containing this project
README
# Contents
# 1 - Overview
## 1.1 - What is Ripples?
**Ripples** is a scientific computation library built on top of NumPy that aims to
provide a unified, numerically accurate, with good performance and easy to use
framework for multi-discipline numerical work.
It currently provides **differentiation** and **optimization** suites; many more
sub-fields of computational science are planned for the future (see the
[Roadmap](#5---roadmap)).
## 1.2 - Why "Ripples"?
As someone who loves physics, the author is fascinated by the fact that much of modern
physics is fundamentally a ripple propagating through a field; from the light we see
to gravity we experience.
In addition to this, the butterfly effect is equally fascinating. It perfectly
represents the intrinsic chaotic nature of the many nonlinear differential equations
that govern so much of our world. This can be thought of as a ripple effect: tiny
changes at the start can lead to completely different outcomes, creating unpredictable
chains of cause and effect.
With these two important and fundamental aspects of reality in mind, the chosen name
for a library intended to provide a framework to simulate and visualize said reality
was straightforward.
## 1.3 - Philosophy
This library has been written with two kinds of people in mind.
- **The user**, who just wants a library that simply works well. For this reason every
public function carries an extensive docstring: a description, brief usage guidelines,
the relevant references, and a worked examples block - enough to use it correctly, and
enough to understand what it does.
- **The reader**, who wants to understand how everything works, quickly and without
friction. Considerable effort has gone into the readability and the explanations of
the different files in this package, so that even a non-expert can follow what each
function is doing. The documentation explains things thoroughly, but it is not a
textbook: anyone who wants to understand a method in full depth is pointed to the
literature, which is referenced throughout. The reading itself is guided, too - each
submodule's `__init__.py` lists the recommended reading order, walking the code from
the lowest-level utilities up to the public entry point.
# 2 - Installation
### Requirements
- **Python** ≥ 3.10
- **NumPy** ≥ 1.24
### Install via pip
```bash
pip install ripples-sci
```
### Install from source
```bash
git clone https://github.com/ripples-sci/ripples.git
cd ripples
pip install -e . # editable install
```
### Verify the installation
```python
import ripples
print(ripples.__version__)
ripples.test()
```
# 3 - Features
Two suites - **differentiation** and **optimization** are available and can be reached
directly from `import ripples`. The two sections below describe each suite: what it
covers, its public API, the object it returns, and a set of brief examples that show
basic functionalities.
## 3.1 - Differentiation
`ripples.differentiation` computes derivatives of scalar functions of any number of
variables: gradients, Hessians, and the full mixed-partial tensors of arbitrary order;
through three numerical strategies of increasing accuracy and decreasing generality:
| Strategy | Accuracy | Cost | Restrictions |
|---|---|---|---|
| **Central finite differences** | `O(h^(p+1-n))` | `p` evaluations per component | Function must be `n`-times continuously differentiable |
| **Richardson extrapolation** | Each pass adds `O(h^2)` more | `p + k` evaluations (`k` = number of passes) | Same as above, also gives a Romberg-style error bound |
| **Complex-step method** | ~machine precision (`O(eps)`) | **1** function evaluation | First derivatives only; function must be analytic over C |
*`n` = derivative order, `p` = effective stencil point count, `h` = step size.*
### Public API
| Function | What it does |
|---|---|
| **`nth_numerical_derivative`** | Builds a callable that evaluates the n-th partial derivative of `f` (gradient, Hessian, or full mixed-partials tensor). |
| **`numerical_hessian_vector_product`** | Computes `H(x) @ v` without ever forming the full Hessian - `O(p)` gradient calls regardless of dimension. |
### Output
**`DifferentiationResult`** - the object returned by both functions above. It is immutable and behaves like a read-only `numpy.ndarray` of the derivative, so it can be dropped straight into further array arithmetic while also carrying the full record of the computation:
- `derivative` - the computed value (gradient vector, Hessian matrix, or full mixed-partials tensor).
- `error_estimate` - a Romberg-style upper bound on the truncation error (available when Richardson extrapolation is used).
- `differentiation_method` - which strategy produced the result (`'central_difference'`, `'richardson'`, or `'complex_step'`).
- `is_scalar` - whether the input was a single-variable point.
together with the rest of the configuration that produced it.
### Examples
Gradients, Hessians, and higher mixed partials
```python
import numpy as np
from ripples import nth_numerical_derivative
# Gradient of a 3-variable function
def f(x):
return x[0] ** 2 + 3.0 * x[1] + np.sin(x[2])
gradient_f = nth_numerical_derivative(f, derivative_order=1)
result = gradient_f(np.array([1.0, 2.0, 0.5]))
result.derivative # array([2., 3., 0.87758256])
result.differentiation_method # 'central_difference'
# Full Hessian via Richardson - bonus: a truncation error upper bound
def g(x):
return x[0] ** 2 * x[1] + x[1] ** 3
hessian_g = nth_numerical_derivative(
g, derivative_order=2, richardson_extrapolation=True,
)
result = hessian_g(np.array([1.0, 2.0]))
result.derivative # [[4., 2.], [2., 12.]]
result.error_estimate # Romberg-style upper bound on the truncation error
# Single component of a higher-order mixed partial
mixed = nth_numerical_derivative(
g, derivative_order=3, single_component=(1, 1, 1),
)
mixed(np.array([1.0, 2.0])).derivative # 6.0 (d^{3}g / dx_1^3)
```
Hessian-vector products without forming the Hessian
```python
from ripples import numerical_hessian_vector_product
A = np.array([[4.0, 1.0], [1.0, 3.0]])
def grad_quadratic(x):
return A @ x
hvp = numerical_hessian_vector_product(
gradient_function = grad_quadratic,
point = np.array([1.0, -2.0]),
vector = np.array([1.0, 1.0]),
)
hvp.derivative # array([5., 4.]) == A @ v
```
## 3.2 - Optimization
`ripples.optimization` exposes a single unified entry point - **`minimizer`** - that
dispatches to ten algorithms covering first-order, line-search, trust-region, global,
and constrained optimization. The same call shape works whether your problem is convex
or non-convex, smooth or noisy, bounded or constrained, low- or moderate-dimensional.
The ten methods group into the following families:
| Family | Methods (`method=`) | Best for |
|---|---|---|
| **First-order** | `nesterov`, `adam` | Noisy, stochastic, or piecewise-smooth objectives, or when starting close to an optimum. Poor as general-purpose solvers. |
| **Conjugate gradient** | `conjugate_gradient` | Smooth problems with fewer than ~500 parameters. |
| **Quasi-Newton** | `bfgs`, `lbfgs` | `bfgs` is best for smooth problems with < ~500 parameters. `lbfgs` scales well for smooth problems with > ~500 parameters and serves as an excellent general-purpose first try. |
| **Newton-type** | `newton_conjugate_gradient` | Smooth, large-scale problems (> ~500 parameters) where it scales efficiently. |
| **Trust-region** | `trust_ncg`, `trust_lanczos` | Preferred for ill-conditioned or poorly scaled problems due to numerical stability. `trust_ncg` is also a great general-purpose first try and the default method; `trust_lanczos` is the least sensitive to ill-conditioning. Both suit smooth problems with < ~500 parameters. |
| **Global** | `direct`, `annealing` | `direct` is a brute-force grid search effective for tight boxes under ~4 dimensions. `annealing` is preferred for many local minima or bounded problems without a reliable gradient. |
| **Constrained** | any of the above + `constraints=` / `bounds=` | General smooth constrained problems, via an Augmented-Lagrangian outer loop. |
### Public API
| Function | What it does |
|---|---|
| **`minimizer`** | The single unified entry point. Selects the algorithm through the `method` argument, builds numerical gradients and Hessian-vector products automatically when analytical ones are not supplied, and returns an `OptimizationResult`. |
### Output
**`OptimizationResult`** - every method returns this same object. It behaves like a read-only `numpy.ndarray` of the optimized parameters, so you can use it directly in further computation, while also recording everything about the run:
- the outcome - `success`, `final_params`, `final_cost`, `termination_reason`;
- the cost of getting there - `iteration_number`, `func_evals_number`, `grad_evals_number`, `elapsed_time`;
- the shape of the problem - `is_bounded`, `is_constrained`, `constraint_count`, `is_global_method`;
- and the full configuration that produced it.
It also offers conversion helpers (`as_array`, `as_float`, `to_list`, `to_dict`), equality checks (`==`, `allclose`), and a `summary(...)` method for a report. Printing the object shows a compact summary.
### Examples
Minimize a smooth function with the default method
```python
import ripples
def rosenbrock(x):
return (1.0 - x[0]) ** 2 + 100.0 * (x[1] - x[0] ** 2) ** 2
result = ripples.minimizer(
function = rosenbrock,
initial_params = [-1.2, 1.0],
)
result.final_params # ~ [1., 1.]
result.final_cost # ~ 1e-18
```
Hessian-vector product for trust-region in moderate dimension
```python
rng = np.random.default_rng(seed=0)
A = rng.standard_normal((5, 5))
A = A @ A.T + np.eye(5) # Symmetric Positive Definite
def f(x): return 0.5 * x @ A @ x
def g(x): return A @ x
def hvp(x,p): return A @ p # constant Hessian
result = minimizer(
function = f,
initial_params = rng.standard_normal(5),
method = 'trust_lanczos',
gradient_function = g,
hessian_vector_function = hvp,
)
result.final_params # ~ [0, 0, 0, 0, 0]
result.final_cost # ~ 0.
result.hessian_vector_product_provided # True
```
Box bounds - optimum on the boundary
```python
def shifted_sphere(x):
return np.sum((x - 3.0) ** 2) # unconstrained min at [3, 3]
result = minimizer(
function = shifted_sphere,
initial_params = [0.0, 0.0],
method = 'lbfgs',
bounds = ([-1.0, -1.0], [1.0, 1.0]),
)
result.final_params # ~ [1., 1.] (corner of the box)
result.is_bounded # True
```
Equality constraint
```python
def objective(x): return (x[0] - 3.0) ** 2 + (x[1] - 2.0) ** 2
constraints = (
{'type': 'eq', 'fun': lambda x: x[0] + x[1] - 3.0},
)
result = minimizer(
function = objective,
initial_params = [0.0, 0.0],
method = 'bfgs',
constraints = constraints,
)
result.final_params # ~ [2., 1.] (unconstrained solution is at [3., 2.])
result.constraint_count # ~ 1
```
Global optimization on Rastrigin
```python
def rastrigin(x):
return 10.0 * len(x) + np.sum(x ** 2 - 10.0 * np.cos(2.0 * np.pi * x))
result = minimizer(
function = rastrigin,
method = 'annealing',
bounds = ([-512., -512.], [512., 512.]),
method_params = {'f_min': 1e-13},
)
result.is_global_method # True
result.final_params # ~ [0., 0.]
```
# 4 - References
Every entry below is a source actually cited in the docstrings of the submodule
files. Each one notes the methods that rely on it.
## 4.1 - Differentiation
1. **Press, W. H., Teukolsky, S. A., Vetterling, W. T., & Flannery, B. P. (2007).** *Numerical Recipes: The Art of Scientific Computing* (3rd ed.), §5.7. Cambridge University Press. ISBN 978-0-521-88068-8. - Central-difference stencils and the Romberg-style truncation error estimate.
2. **LeVeque, R. J. (2007).** *Finite Difference Methods for Ordinary and Partial Differential Equations: Steady-State and Time-Dependent Problems*, §1. SIAM. [https://doi.org/10.1137/1.9780898717839](https://doi.org/10.1137/1.9780898717839) - Finite-difference foundations and the Hessian-vector product.
3. **Martins, J. R. R. A., Sturdza, P., & Alonso, J. J. (2003).** *The complex-step derivative approximation.* ACM Transactions on Mathematical Software, 29(3), 245–262. [https://doi.org/10.1145/838250.838251](https://doi.org/10.1145/838250.838251) - The complex-step method.
4. **Burden, R. L., Faires, J. D., & Burden, A. M. (2016).** *Numerical Analysis* (10th ed.), §§4.2 & 4.5. Cengage Learning. ISBN 978-1-305-25366-7. - Richardson extrapolation and the automatic step-size selection.
5. **Wikipedia contributors.** *Finite differences.* [https://en.wikipedia.org/wiki/Finite_difference#Multivariate_finite_differences](https://en.wikipedia.org/wiki/Finite_difference#Multivariate_finite_differences) - Multivariate (mixed-partial) finite-difference composition.
## 4.2 - Optimization
1. **Nocedal, J., & Wright, S. J. (2006).** *Numerical Optimization* (2nd ed.). Springer Series in Operations Research and Financial Engineering. Springer, New York. [https://doi.org/10.1007/978-0-387-40065-5](https://doi.org/10.1007/978-0-387-40065-5) - Conjugate gradient (§5.4, eq. 5.45), BFGS (§6.1, eqs. 6.19–6.20), Newton-CG (§7.1), L-BFGS (§7.4–7.5), trust-region NCG (§7.2), trust-region Lanczos (pp. 175–176, Theorem 4.1, §4.3), and the augmented-Lagrangian outer loop (§17.3–17.4).
2. **Kochenderfer, M. J., & Wheeler, T. A. (2019).** *Algorithms for Optimization.* MIT Press. ISBN 978-0-262-03942-0. - Nesterov accelerated gradient (§5.4), Adam (§5.8), DIRECT (§7.6), and dual annealing (§8.3).
3. **SciPy contributors (2026).** *SciPy.optimize._linesearch.py source code (Version 1.17.1).* GitHub. [Source](https://github.com/scipy/scipy/blob/bb6b9da396f15355efdb2e28bdfa1aead105ce92/scipy/optimize/_linesearch.py) - Wolfe line search.
4. **Wikipedia contributors.** *Conjugate gradient method.* [https://en.wikipedia.org/wiki/Conjugate_gradient_method](https://en.wikipedia.org/wiki/Conjugate_gradient_method) - Linear conjugate gradient background.
5. **Wikipedia contributors.** *Nonlinear conjugate gradient method.* [https://en.wikipedia.org/wiki/Nonlinear_conjugate_gradient_method](https://en.wikipedia.org/wiki/Nonlinear_conjugate_gradient_method) - Polak-Ribière+ nonlinear conjugate gradient.
6. **Wikipedia contributors.** *BFGS method.* [https://en.wikipedia.org/wiki/BFGS](https://en.wikipedia.org/wiki/BFGS) - The BFGS Hessian update.
7. **Wikipedia contributors.** *Limited-memory BFGS (L-BFGS).* [https://en.wikipedia.org/wiki/LBFGS](https://en.wikipedia.org/wiki/LBFGS) - The L-BFGS two-loop recursion.
8. **Gould, N. I. M., Lucidi, S., Roma, M., & Toint, P. L. (1999).** *Solving the trust-region subproblem using the Lanczos method.* SIAM Journal on Optimization, 9(2), 504–525. [https://doi.org/10.1137/S1052623497322735](https://doi.org/10.1137/S1052623497322735) - The GLTR / Lanczos trust-region subproblem solver.
9. **Tsallis, C., & Stariolo, D. A. (1996).** *Generalized simulated annealing.* Physica A, 233(1–2), 395–406. [https://doi.org/10.1016/S0378-4371(96)00271-3](https://doi.org/10.1016/S0378-4371(96)00271-3) - Generalized simulated annealing.
10. **Xiang, Y., Gubian, S., & Martin, F. (2017).** *Generalized Simulated Annealing.* In *Computational Optimization in Engineering - Paradigms and Applications.* [http://dx.doi.org/10.5772/66071](http://dx.doi.org/10.5772/66071) - Dual annealing with periodic local refinement.
11. **Wikipedia contributors.** *q-Gaussian distribution.* [https://en.wikipedia.org/wiki/Q-Gaussian_distribution#Related_distributions](https://en.wikipedia.org/wiki/Q-Gaussian_distribution#Related_distributions) - The q-Gaussian visiting distribution used by dual annealing.
# 5 - Roadmap
| Version | Status | Scope / Module | Objective to implement |
| :--- | :--- | :--- | :--- |
| **0.1.X** | In progress | Bug fixes and readability improvements | Resolve open issues and improve clarity of the v0.1 codebase. |
| **0.X.0** | Planned | `ripples.optimization` | Implement multiple 1-dimensional methods, expand global methods, and improve the performance of existing algorithms. |
| **0.X.0** | Planned | `ripples.differentiation` | Introduce numerical alternatives including the Fornberg method and multi-complex step differentiation to expand current complex-step capabilities. |
| **0.X.0** | Planned | `ripples.integration` | Implement quadrature rules and ODE/PDE solvers. |
| **0.X.0** | Planned | `ripples.root_finding` | Provide multi-dimensional root-finding routines. |
| **0.X.0** | Planned | `ripples.interpolation` | Integrate standard interpolation routines for data smoothing and continuous approximation. |
| **0.X.0** | Planned | `ripples.differentiation` | Add Automatic Differentiation for both forward-mode and reverse-mode execution. |
| **0.X.0** | Planned | `ripples.machine_learning` | Provide a comprehensive suite of classical machine learning models for both supervised and unsupervised learning. |
| **0.X.0** | Planned | `ripples.machine_learning` | Design and build a modular neural network module. |
| **0.X.0** | Planned | `ripples.control_theory` | The foundations of control theory: state-space representation, transfer functions, PID controllers, and optimal control structures. |
| **0.X.0** | Planned | `ripples.simulation` | Build a core simulation API for Computational Fluid Dynamics (CFD) and Finite Element Method (FEM). |
| **0.X.0** | Planned | `ripples.visualization` | Provide convenience plotting helpers for most native data types, training results, and simulation curves. |
| **0.X.0** | Planned | Performance Redesign | Introduce compiled loops, multithreading, and parallelized computation while remaining an accessible, user-friendly package. |
| **1.0.0** | Goal | Production Release | Deliver a complete numerical computation and engineering library providing robust routines for most scientific disciplines, backed by a stable public API. |
Notes:
- The 0.X.0 versions are not presented in chronological order and are subject to change.
- There is no expected release timeline for the planned pre-realease versions, given
the project's ambitious roadmap, full implementation is expected to be a multi-year
effort.
# 6 - Author
**Álvaro Cátedra Sánchez**, last year Aerospace Engineering student with great
interest in scientific computing; unique author, maintainer, and responsible for
overall design, numerical methods implementation, and API consistency.
Professional contact:
[`alvaro.catedra.sanchez@gmail.com`](mailto:alvaro.catedra.sanchez@gmail.com)
# 7 - Contributing
Although this library was created by a single author in order to gain a deep learning
about the extensive field that is scientific computation; ***any*** feedback, bug
reports, or suggestions that could improve the library or its author in any way will
be ***greatly*** appreciated.
# 8 - Disclaimer
Ripples is pre-release software (versions before `1.0`). The public API is **stable
within a minor version** but may evolve between minor versions until `1.0`. While
considerable care has been taken to make the numerical methods accurate and
well-conditioned, no guarantee is given that any particular result is fit for any
particular purpose; the user is responsible for validating results against their own
problem requirements.
# 9 - License
Ripples is distributed under the **Apache License, Version 2.0**.
You may use, modify, and distribute this software under the terms of the license,
provided that proper attribution to the original author is preserved in all copies
or substantial portions of the software. See [`LICENSE.txt`](LICENSE.txt) at the
repository root for the full text.
```
Copyright (c) Álvaro Cátedra Sánchez
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
```
---
