Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ instance/
# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/
Expand All @@ -81,6 +79,7 @@ celerybeat-schedule

# virtualenv
venv/
.venv/
ENV/

# Spyder project settings
Expand All @@ -99,3 +98,7 @@ benchmarks/results/

# vscode configuration
.vscode/

# Zensical
_site/
.notebook_cache/
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ repos:
rev: "v1.15.0"
hooks:
- id: mypy
exclude: ipynb_filter.py|docs/source/conf.py
exclude: ipynb_filter.py
2 changes: 1 addition & 1 deletion AUTHORS.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## 👥 Authors
## Authors

The current maintainers of Adaptive are:

Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# 🗞️ Changelog
# Changelog

## [v1.4.0](https://github.com/python-adaptive/adaptive/tree/v1.3.0) (2025-05-13)

Expand Down
84 changes: 50 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

# ![logo](https://adaptive.readthedocs.io/en/latest/_static/logo.png) *Adaptive*: Parallel Active Learning of Mathematical Functions
<!-- badges-start -->
<!-- --8<-- [start:badges] -->

[![Binder](https://mybinder.org/badge.svg)](https://mybinder.org/v2/gh/python-adaptive/adaptive/main?filepath=example-notebook.ipynb)
[![Conda](https://img.shields.io/badge/install%20with-conda-green.svg)](https://anaconda.org/conda-forge/adaptive)
Expand All @@ -9,24 +9,24 @@
[![Documentation](https://readthedocs.org/projects/adaptive/badge/?version=latest)](https://adaptive.readthedocs.io/en/latest/?badge=latest)
[![Downloads](https://img.shields.io/conda/dn/conda-forge/adaptive.svg)](https://anaconda.org/conda-forge/adaptive)
[![GitHub](https://img.shields.io/github/stars/python-adaptive/adaptive.svg?style=social)](https://github.com/python-adaptive/adaptive/stargazers)
[![Gitter](https://img.shields.io/gitter/room/nwjs/nw.js.svg)](https://gitter.im/python-adaptive/adaptive)
[![PyPI](https://img.shields.io/pypi/v/adaptive.svg)](https://pypi.python.org/pypi/adaptive)
[![Python](https://img.shields.io/pypi/pyversions/adaptive.svg)](https://pypi.python.org/pypi/adaptive)

<!-- badges-end -->
<!-- --8<-- [end:badges] -->

<!-- summary-start -->
<!-- --8<-- [start:summary] -->

Adaptive is an open-source Python library that streamlines adaptive parallel function evaluations.
Rather than calculating all points on a dense grid, it intelligently selects the "best" points in the parameter space based on your provided function and bounds.
With minimal code, you can perform evaluations on a computing cluster, display live plots, and optimize the adaptive sampling algorithm.

Adaptive is most efficient for computations where each function evaluation takes at least ≈50ms due to the overhead of selecting potentially interesting points.

To see Adaptive in action, try the [example notebook on Binder](https://mybinder.org/v2/gh/python-adaptive/adaptive/main?filepath=example-notebook.ipynb) or explore the [tutorial on Read the Docs](https://adaptive.readthedocs.io/en/latest/tutorial/tutorial).
To see Adaptive in action, try the [example notebook on Binder](https://mybinder.org/v2/gh/python-adaptive/adaptive/main?filepath=example-notebook.ipynb) or explore the [tutorial on Read the Docs](https://adaptive.readthedocs.io/en/latest/tutorial/tutorial/).

<!-- summary-end -->
<!-- --8<-- [end:summary] -->

<details><summary><b><u>[ToC]</u></b> 📚</summary>
<details><summary><b>Table of contents</b></summary>

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
Expand All @@ -38,6 +38,7 @@ To see Adaptive in action, try the [example notebook on Binder](https://mybinder
- [Installation](#installation)
- [Faster triangulation (optional)](#faster-triangulation-optional)
- [Development](#development)
- [Documentation](#documentation)
- [Citing](#citing)
- [Draft Paper](#draft-paper)
- [Credits](#credits)
Expand All @@ -46,20 +47,20 @@ To see Adaptive in action, try the [example notebook on Binder](https://mybinder

</details>

<!-- key-features-start -->
<!-- --8<-- [start:key-features] -->

## Key features

- 🎯 **Intelligent Adaptive Sampling**: Adaptive focuses on areas of interest within a function, ensuring better results with fewer evaluations, saving time, and computational resources.
- ⚡ **Parallel Execution**: The library leverages parallel processing for faster function evaluations, making optimal use of available computational resources.
- 📊 **Live Plotting and Info Widgets**: When working in Jupyter notebooks, Adaptive offers real-time visualization of the learning process, making it easier to monitor progress and identify areas of improvement.
- 🔧 **Customizable Loss Functions**: Adaptive supports various loss functions and allows customization, enabling users to tailor the learning process according to their specific needs.
- 📈 **Support for Multidimensional Functions**: The library can handle functions with scalar or vector outputs in one or multiple dimensions, providing flexibility for a wide range of problems.
- 🧩 **Seamless Integration**: Adaptive offers a simple and intuitive interface, making it easy to integrate with existing Python projects and workflows.
- 💾 **Flexible Data Export**: The library provides options to export learned data as NumPy arrays or Pandas DataFrames, ensuring compatibility with various data processing tools.
- 🌐 **Open-Source and Community-Driven**: Adaptive is an open-source project, encouraging contributions from the community to continuously improve and expand the library's features and capabilities.
- **Intelligent Adaptive Sampling**: Adaptive focuses on areas of interest within a function, ensuring better results with fewer evaluations, saving time, and computational resources.
- **Parallel Execution**: The library leverages parallel processing for faster function evaluations, making optimal use of available computational resources.
- **Live Plotting and Info Widgets**: When working in Jupyter notebooks, Adaptive offers real-time visualization of the learning process, making it easier to monitor progress and identify areas of improvement.
- **Customizable Loss Functions**: Adaptive supports various loss functions and allows customization, enabling users to tailor the learning process according to their specific needs.
- **Support for Multidimensional Functions**: The library can handle functions with scalar or vector outputs in one or multiple dimensions, providing flexibility for a wide range of problems.
- **Seamless Integration**: Adaptive offers a simple and intuitive interface, making it easy to integrate with existing Python projects and workflows.
- **Flexible Data Export**: The library provides options to export learned data as NumPy arrays or Pandas DataFrames, ensuring compatibility with various data processing tools.
- **Open-Source and Community-Driven**: Adaptive is an open-source project, encouraging contributions from the community to continuously improve and expand the library's features and capabilities.

<!-- key-features-end -->
<!-- --8<-- [end:key-features] -->

## Example usage

Expand All @@ -81,7 +82,13 @@ runner.live_info()
runner.live_plot()
```

<img src="https://user-images.githubusercontent.com/6897215/38739170-6ac7c014-3f34-11e8-9e8f-93b3a3a3d61b.gif" width='20%'> </img> <img src="https://user-images.githubusercontent.com/6897215/35219611-ac8b2122-ff73-11e7-9332-adffab64a8ce.gif" width='40%'> </img> <img src="https://user-images.githubusercontent.com/6897215/47256441-d6d53700-d480-11e8-8224-d1cc49dbdcf5.gif" width='20%'> </img>
With the same number of points, adaptive sampling resolves features that a homogeneous grid misses:

<p align="center">
<img src="https://raw.githubusercontent.com/python-adaptive/adaptive/main/docs/_static/readme/learner1d.gif" width="43%" alt="Learner1D: homogeneous grid versus adaptive sampling of a sharp peak">
<img src="https://raw.githubusercontent.com/python-adaptive/adaptive/main/docs/_static/readme/learner2d.gif" width="36%" alt="Learner2D: homogeneous grid versus adaptive triangulation of a ring">
<img src="https://raw.githubusercontent.com/python-adaptive/adaptive/main/docs/_static/readme/learnerND.gif" width="19%" alt="LearnerND: sampled points concentrate on a spherical shell">
</p>

### Exporting Data

Expand All @@ -97,7 +104,7 @@ If you have Pandas installed, you can also export the data as a DataFrame:
df = learner.to_dataframe()
```

<!-- implemented-algorithms-start -->
<!-- --8<-- [start:implemented-algorithms] -->

## Implemented Algorithms

Expand All @@ -110,15 +117,15 @@ While `adaptive` provides sensible default choices, the adaptive sampling proces

The following learners are implemented:

<!-- implemented-algorithms-end -->
<!-- --8<-- [end:implemented-algorithms] -->

- `Learner1D`: for 1D functions `f: ℝ → ℝ^N`,
- `Learner2D`: for 2D functions `f: ℝ^2 → ℝ^N`,
- `LearnerND`: for ND functions `f: ℝ^N → ℝ^M`,
- `AverageLearner`: for random variables, allowing averaging of results over multiple evaluations,
- `AverageLearner1D`: for stochastic 1D functions, estimating the mean value at each point,
- `IntegratorLearner`: for integrating a 1D function `f: ℝ → ℝ`,
- `BalancingLearner`: for running multiple learners simultaneously and selecting the "best" one as more points are gathered.
- `SequenceLearner`: for evaluating a fixed sequence of points while still using the runners, parallelism, and data export of Adaptive.

Meta-learners (to be used with other learners):

Expand All @@ -132,11 +139,11 @@ In addition to learners, `adaptive` offers primitives for parallel sampling acro
[ipyparallel](https://ipyparallel.readthedocs.io/en/latest/), and
[distributed](https://distributed.readthedocs.io/en/latest/).

<!-- rest-start -->
<!-- --8<-- [start:rest] -->

## Installation

`adaptive` works with Python 3.7 and higher on Linux, Windows, or Mac, and provides optional extensions for working with the Jupyter/IPython Notebook.
`adaptive` works with Python 3.11 and higher on Linux, Windows, or Mac, and provides optional extensions for working with Jupyter.

The recommended way to install adaptive is using `conda`:

Expand All @@ -150,7 +157,7 @@ conda install -c conda-forge adaptive
pip install "adaptive[notebook]"
```

The `[notebook]` above will also install the optional dependencies for running `adaptive` inside a Jupyter notebook.
The `[notebook]` above also installs the optional dependencies for live plotting and widgets in JupyterLab and Jupyter Notebook; no extra Jupyter extensions need to be installed.

### Faster triangulation (optional)

Expand All @@ -163,24 +170,17 @@ pip install "adaptive[rust]"
No code changes are needed — the Rust backend is detected and used automatically.
To control the selection, pass `LearnerND(..., triangulation_backend="python" | "rust" | "auto")` per learner, or set the environment variable `ADAPTIVE_TRIANGULATION_BACKEND=python` to force the pure-Python implementation globally (or to `rust` to make a missing Rust backend an error instead of a silent fallback).

To use Adaptive in Jupyterlab, you need to install the following labextensions.

```bash
jupyter labextension install @jupyter-widgets/jupyterlab-manager
jupyter labextension install @pyviz/jupyterlab_pyviz
```

## Development

Clone the repository and run `pip install -e ".[notebook,test,other]"` to add a link to the cloned repo into your Python path:
Clone the repository and install it in editable mode with the optional dependencies:

```bash
git clone git@github.com:python-adaptive/adaptive.git
cd adaptive
pip install -e ".[notebook,test,other]"
```

We recommend using a Conda environment or a virtualenv for package management during Adaptive development.
We recommend a virtual environment, for example with [uv](https://docs.astral.sh/uv/) (`uv sync --extra notebook --extra test --extra other`) or Conda.

To avoid polluting the history with notebook output, set up the git filter by running:

Expand All @@ -198,6 +198,19 @@ pre-commit install

in the repository.

### Documentation

The documentation is built with [Zensical](https://zensical.org).
The executable pages in `docs/notebooks/` are Jupyter notebooks in [jupytext's MyST Markdown format](https://jupytext.readthedocs.io/en/latest/formats-markdown.html).
`docs/build_notebooks.py` executes them (with caching) and renders them into `docs/`, after which Zensical builds the site:

```bash
uv run --group docs python docs/build_notebooks.py
uv run --group docs zensical serve # preview on http://localhost:8000
```

The animations in this README are rendered from real learner runs with `uv run --group docs python docs/make_animations.py` (requires `ffmpeg` and Chrome or Chromium).

## Citing

If you used Adaptive in a scientific work, please cite it as follows.
Expand All @@ -224,7 +237,10 @@ We would like to give credits to the following people:
- Pedro Gonnet for his implementation of [CQUAD](https://www.gnu.org/software/gsl/manual/html_node/CQUAD-doubly_002dadaptive-integration.html), “Algorithm 4” as described in “Increasing the Reliability of Adaptive Quadrature Using Explicit Interpolants”, P. Gonnet, ACM Transactions on Mathematical Software, 37 (3), art. no. 26, 2010.
- Pauli Virtanen for his `AdaptiveTriSampling` script (no longer available online since SciPy Central went down) which served as inspiration for the `adaptive.Learner2D`.

<!-- rest-end -->
<!-- --8<-- [end:rest] -->
<!-- --8<-- [start:community] -->

For general discussion, we have a [Gitter chat channel](https://gitter.im/python-adaptive/adaptive).
If you find any bugs or have any feature suggestions please file a GitHub [issue](https://github.com/python-adaptive/adaptive/issues/new) or submit a [pull request](https://github.com/python-adaptive/adaptive/pulls).

<!-- --8<-- [end:community] -->
9 changes: 7 additions & 2 deletions docs/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
build/*
source/_static/holoviews.*
# Rendered from docs/notebooks/ by docs/build_notebooks.py
/algorithms_and_examples.md
/benchmarks.md
/tutorial/
*.ipynb
# Written by notebooks during execution
/notebooks/tutorial/data/
1 change: 1 addition & 0 deletions docs/CHANGELOG.md
27 changes: 0 additions & 27 deletions docs/Makefile

This file was deleted.

89 changes: 89 additions & 0 deletions docs/_static/extra.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/* Viridis-inspired palette, matching the logo */
[data-md-color-primary="custom"] {
--md-primary-fg-color: #3b528b;
--md-primary-fg-color--light: #5a6fa8;
--md-primary-fg-color--dark: #2c3e6b;
--md-primary-bg-color: #ffffff;
--md-primary-bg-color--light: #ffffffb3;
}
[data-md-color-accent="custom"] {
--md-accent-fg-color: #21918c;
--md-accent-fg-color--transparent: #21918c1a;
--md-accent-bg-color: #ffffff;
--md-accent-bg-color--light: #ffffffb3;
}
[data-md-color-scheme="slate"][data-md-color-primary="custom"] {
--md-typeset-a-color: #7ea6e0;
}

/* Animated logo on the home page */
.adaptive-logo-video {
display: block;
width: 320px;
max-width: 100%;
margin: 1.5rem auto;
}

/* Notebook outputs rendered by docs/build_notebooks.py */
.md-typeset .nb-output {
overflow-x: auto;
}
/* Script-only outputs (e.g. the HoloViews extension loader) take no space */
.md-typeset .nb-output:has(> :not(script, style, link, div:empty)) {
margin: 0 0 1.5em;
}
.md-typeset .highlight.nb-output-text pre {
border-left: 0.2rem solid var(--md-accent-fg-color);
}
.md-typeset .highlight.nb-output-text code {
background: transparent;
}

/* Bokeh plots and widgets are designed for a light background */
/* (empty roots are the HoloViews extension loader, which renders nothing) */
[data-md-color-scheme="slate"] .md-typeset .nb-output:has([data-root-id]:not(:empty)),
[data-md-color-scheme="slate"] .md-typeset .nb-output:has(.plotly-graph-div),
[data-md-color-scheme="slate"] .md-typeset .nb-output:has(.jupyter-widgets) {
background: #ffffff;
color: #000000;
border-radius: 0.4rem;
padding: 0.5rem;
}

/* `live_info` and `live_plot` cancel buttons do nothing on a static page */
.md-typeset .nb-output .widget-button,
.md-typeset .nb-output:has(.widget-button):not(:has(.widget-html)) {
display: none !important;
}

/* pandas DataFrames */
.md-typeset .nb-output table.dataframe {
border: none;
border-collapse: collapse;
border-spacing: 0;
font-size: 0.7rem;
table-layout: fixed;
}
.md-typeset .nb-output table.dataframe thead {
border-bottom: 1px solid var(--md-default-fg-color--lighter);
vertical-align: bottom;
}
.md-typeset .nb-output table.dataframe :is(tr, th, td) {
text-align: right;
vertical-align: middle;
padding: 0.4em 0.6em;
line-height: normal;
white-space: normal;
border: none;
}
.md-typeset .nb-output table.dataframe tbody tr:nth-child(odd) {
background: var(--md-code-bg-color);
}
.md-typeset .nb-output table.dataframe tbody tr:hover {
background: var(--md-accent-fg-color--transparent);
}

/* README animations on the home page */
.md-typeset img[src*="_static/readme/"] {
border-radius: 0.4rem;
}
11 changes: 11 additions & 0 deletions docs/_static/katex.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Render the math that pymdownx.arithmatex wraps in `.arithmatex` elements.
document$.subscribe(({ body }) => {
for (const element of body.querySelectorAll(".arithmatex")) {
renderMathInElement(element, {
delimiters: [
{ left: "\\(", right: "\\)", display: false },
{ left: "\\[", right: "\\]", display: true },
],
});
}
});
File renamed without changes
File renamed without changes
Binary file added docs/_static/logo_docs.webm
Binary file not shown.
Binary file added docs/_static/readme/learner1d.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/readme/learner2d.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/readme/learnerND.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading