Skip to content

Commit 0936a93

Browse files
authored
Rewrite parts of README, reorder sections, and add features section (#400)
* Update README * Fix emojis * rename tags * fix emojis * Fix * add Tutorial emoji * Add extra text to examples * no zoom on scroll
1 parent 429c4bd commit 0936a93

File tree

14 files changed

+185
-80
lines changed

14 files changed

+185
-80
lines changed

.github/workflows/toc.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
on: push
2+
name: TOC Generator
3+
jobs:
4+
generateTOC:
5+
name: TOC Generator
6+
runs-on: ubuntu-latest
7+
steps:
8+
- uses: technote-space/toc-generator@v4
9+
with:
10+
TOC_TITLE: ""

AUTHORS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
## Authors
1+
## 👥 Authors
22

33
The current maintainers of Adaptive are:
44

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Changelog
1+
# 🗞️ Changelog
22

33
## [v0.15.0](https://github.com/python-adaptive/adaptive/tree/v0.15.0) (2022-11-30)
44

README.md

Lines changed: 99 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
<!-- badges-start -->
21

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

55
[![Binder](https://mybinder.org/badge.svg)](https://mybinder.org/v2/gh/python-adaptive/adaptive/main?filepath=example-notebook.ipynb)
66
[![Conda](https://img.shields.io/badge/install%20with-conda-green.svg)](https://anaconda.org/conda-forge/adaptive)
@@ -13,56 +13,57 @@
1313
[![Pipeline-status](https://dev.azure.com/python-adaptive/adaptive/_apis/build/status/python-adaptive.adaptive?branchName=main)](https://dev.azure.com/python-adaptive/adaptive/_build/latest?definitionId=6?branchName=main)
1414
[![PyPI](https://img.shields.io/pypi/v/adaptive.svg)](https://pypi.python.org/pypi/adaptive)
1515

16-
> *Adaptive*: parallel active learning of mathematical functions.
17-
1816
<!-- badges-end -->
1917

2018
<!-- summary-start -->
2119

22-
`adaptive` is an open-source Python library designed to make adaptive parallel function evaluation simple. With `adaptive` you just supply a function with its bounds, and it will be evaluated at the “best” points in parameter space, rather than unnecessarily computing *all* points on a dense grid.
23-
With just a few lines of code you can evaluate functions on a computing cluster, live-plot the data as it returns, and fine-tune the adaptive sampling algorithm.
20+
Adaptive is an open-source Python library that streamlines adaptive parallel function evaluations.
21+
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.
22+
With minimal code, you can perform evaluations on a computing cluster, display live plots, and optimize the adaptive sampling algorithm.
2423

25-
`adaptive` excels on computations where each function evaluation takes *at least* ≈50ms due to the overhead of picking potentially interesting points.
24+
Adaptive is most efficient for computations where each function evaluation takes at least ≈50ms due to the overhead of selecting potentially interesting points.
2625

27-
Run the `adaptive` example notebook [live on Binder](https://mybinder.org/v2/gh/python-adaptive/adaptive/main?filepath=example-notebook.ipynb) to see examples of how to use `adaptive` or visit the [tutorial on Read the Docs](https://adaptive.readthedocs.io/en/latest/tutorial/tutorial.html).
26+
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.html).
2827

2928
<!-- summary-end -->
3029

31-
## Implemented algorithms
30+
<details><summary><b><u>[ToC]</u></b> 📚</summary>
3231

33-
The core concept in `adaptive` is that of a *learner*.
34-
A *learner* samples a function at the best places in its parameter space to get maximum “information” about the function.
35-
As it evaluates the function at more and more points in the parameter space, it gets a better idea of where the best places are to sample next.
32+
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
33+
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
3634

37-
Of course, what qualifies as the “best places” will depend on your application domain! `adaptive` makes some reasonable default choices, but the details of the adaptive sampling are completely customizable.
35+
- [:star: Key features](#star-key-features)
36+
- [:rocket: Example usage](#rocket-example-usage)
37+
- [:floppy_disk: Exporting Data](#floppy_disk-exporting-data)
38+
- [:test_tube: Implemented Algorithms](#test_tube-implemented-algorithms)
39+
- [:package: Installation](#package-installation)
40+
- [:wrench: Development](#wrench-development)
41+
- [:books: Citing](#books-citing)
42+
- [:page_facing_up: Draft Paper](#page_facing_up-draft-paper)
43+
- [:sparkles: Credits](#sparkles-credits)
3844

39-
The following learners are implemented:
45+
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
4046

41-
<!-- not-in-documentation-start -->
47+
</details>
4248

43-
- `Learner1D`, for 1D functions `f: ℝ → ℝ^N`,
44-
- `Learner2D`, for 2D functions `f: ℝ^2 → ℝ^N`,
45-
- `LearnerND`, for ND functions `f: ℝ^N → ℝ^M`,
46-
- `AverageLearner`, for random variables where you want to average the result over many evaluations,
47-
- `AverageLearner1D`, for stochastic 1D functions where you want to estimate the mean value of the function at each point,
48-
- `IntegratorLearner`, for when you want to intergrate a 1D function `f: ℝ → ℝ`.
49-
- `BalancingLearner`, for when you want to run several learners at once, selecting the “best” one each time you get more points.
49+
<!-- key-features-start -->
5050

51-
Meta-learners (to be used with other learners):
51+
## :star: Key features
5252

53-
- `BalancingLearner`, for when you want to run several learners at once, selecting the “best” one each time you get more points,
54-
- `DataSaver`, for when your function doesn't just return a scalar or a vector.
53+
- 🎯 **Intelligent Adaptive Sampling**: Adaptive focuses on areas of interest within a function, ensuring better results with fewer evaluations, saving time, and computational resources.
54+
-**Parallel Execution**: The library leverages parallel processing for faster function evaluations, making optimal use of available computational resources.
55+
- 📊 **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.
56+
- 🔧 **Customizable Loss Functions**: Adaptive supports various loss functions and allows customization, enabling users to tailor the learning process according to their specific needs.
57+
- 📈 **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.
58+
- 🧩 **Seamless Integration**: Adaptive offers a simple and intuitive interface, making it easy to integrate with existing Python projects and workflows.
59+
- 💾 **Flexible Data Export**: The library provides options to export learned data as NumPy arrays or Pandas DataFrames, ensuring compatibility with various data processing tools.
60+
- 🌐 **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.
5561

56-
In addition to the learners, `adaptive` also provides primitives for running the sampling across several cores and even several machines, with built-in support for
57-
[concurrent.futures](https://docs.python.org/3/library/concurrent.futures.html),
58-
[mpi4py](https://mpi4py.readthedocs.io/en/stable/mpi4py.futures.html),
59-
[loky](https://loky.readthedocs.io/en/stable/),
60-
[ipyparallel](https://ipyparallel.readthedocs.io/en/latest/), and
61-
[distributed](https://distributed.readthedocs.io/en/latest/).
62+
<!-- key-features-end -->
6263

63-
## Examples
64+
## :rocket: Example usage
6465

65-
Adaptively learning a 1D function (the `gif` below) and live-plotting the process in a Jupyter notebook is as easy as
66+
Adaptively learning a 1D function and live-plotting the process in a Jupyter notebook:
6667

6768
```python
6869
from adaptive import notebook_extension, Runner, Learner1D
@@ -82,9 +83,58 @@ runner.live_plot()
8283

8384
<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>
8485

85-
<!-- not-in-documentation-end -->
86+
### :floppy_disk: Exporting Data
87+
88+
You can export the learned data as a NumPy array:
89+
90+
```python
91+
data = learner.to_numpy()
92+
```
93+
94+
If you have Pandas installed, you can also export the data as a DataFrame:
95+
96+
```python
97+
df = learner.to_dataframe()
98+
```
99+
100+
<!-- implemented-algorithms-start -->
101+
102+
## :test_tube: Implemented Algorithms
86103

87-
## Installation
104+
The core concept in `adaptive` is the *learner*.
105+
A *learner* samples a function at the most interesting locations within its parameter space, allowing for optimal sampling of the function.
106+
As the function is evaluated at more points, the learner improves its understanding of the best locations to sample next.
107+
108+
The definition of the "best locations" depends on your application domain.
109+
While `adaptive` provides sensible default choices, the adaptive sampling process can be fully customized.
110+
111+
The following learners are implemented:
112+
113+
<!-- implemented-algorithms-end -->
114+
115+
- `Learner1D`: for 1D functions `f: ℝ → ℝ^N`,
116+
- `Learner2D`: for 2D functions `f: ℝ^2 → ℝ^N`,
117+
- `LearnerND`: for ND functions `f: ℝ^N → ℝ^M`,
118+
- `AverageLearner`: for random variables, allowing averaging of results over multiple evaluations,
119+
- `AverageLearner1D`: for stochastic 1D functions, estimating the mean value at each point,
120+
- `IntegratorLearner`: for integrating a 1D function `f: ℝ → ℝ`,
121+
- `BalancingLearner`: for running multiple learners simultaneously and selecting the "best" one as more points are gathered.
122+
123+
Meta-learners (to be used with other learners):
124+
125+
- `BalancingLearner`: for running several learners at once, selecting the "most optimal" one each time you get more points,
126+
- `DataSaver`: for when your function doesn't return just a scalar or a vector.
127+
128+
In addition to learners, `adaptive` offers primitives for parallel sampling across multiple cores or machines, with built-in support for:
129+
[concurrent.futures](https://docs.python.org/3/library/concurrent.futures.html),
130+
[mpi4py](https://mpi4py.readthedocs.io/en/stable/mpi4py.futures.html),
131+
[loky](https://loky.readthedocs.io/en/stable/),
132+
[ipyparallel](https://ipyparallel.readthedocs.io/en/latest/), and
133+
[distributed](https://distributed.readthedocs.io/en/latest/).
134+
135+
<!-- rest-start -->
136+
137+
## :package: Installation
88138

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

@@ -109,7 +159,7 @@ jupyter labextension install @jupyter-widgets/jupyterlab-manager
109159
jupyter labextension install @pyviz/jupyterlab_pyviz
110160
```
111161

112-
## Development
162+
## :wrench: Development
113163

114164
Clone the repository and run `pip install -e ".[notebook,testing,other]"` to add a link to the cloned repo into your Python path:
115165

@@ -119,25 +169,25 @@ cd adaptive
119169
pip install -e ".[notebook,testing,other]"
120170
```
121171

122-
We highly recommend using a Conda environment or a virtualenv to manage the versions of your installed packages while working on `adaptive`.
172+
We recommend using a Conda environment or a virtualenv for package management during Adaptive development.
123173

124-
In order to not pollute the history with the output of the notebooks, please setup the git filter by executing
174+
To avoid polluting the history with notebook output, set up the git filter by running:
125175

126176
```bash
127177
python ipynb_filter.py
128178
```
129179

130180
in the repository.
131181

132-
We implement several other checks in order to maintain a consistent code style. We do this using [pre-commit](https://pre-commit.com), execute
182+
To maintain consistent code style, we use [pre-commit](https://pre-commit.com). Install it by running:
133183

134184
```bash
135185
pre-commit install
136186
```
137187

138188
in the repository.
139189

140-
## Citing
190+
## :books: Citing
141191

142192
If you used Adaptive in a scientific work, please cite it as follows.
143193

@@ -151,17 +201,19 @@ If you used Adaptive in a scientific work, please cite it as follows.
151201
}
152202
```
153203

154-
## Credits
204+
## :page_facing_up: Draft Paper
205+
206+
If you're interested in the scientific background and principles behind Adaptive, we recommend taking a look at the [draft paper](https://github.com/python-adaptive/paper) that is currently being written.
207+
This paper provides a comprehensive overview of the concepts, algorithms, and applications of the Adaptive library.
208+
209+
## :sparkles: Credits
155210

156211
We would like to give credits to the following people:
157212

158213
- 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.
159214
- Pauli Virtanen for his `AdaptiveTriSampling` script (no longer available online since SciPy Central went down) which served as inspiration for the `adaptive.Learner2D`.
160215

161-
<!-- credits-end -->
162-
163-
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).
164-
165-
<!-- references-start -->
216+
<!-- rest-end -->
166217

167-
<!-- references-end -->
218+
For general discussion, we have a [Gitter chat channel](https://gitter.im/python-adaptive/adaptive).
219+
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).

docs/environment.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,4 @@ dependencies:
2424
- furo=2023.3.27
2525
- myst-parser=0.18.1
2626
- dask=2023.3.2
27+
- emoji=2.2.0

docs/source/_static/logo_docs.png

-1.68 KB
Loading

docs/source/algorithms_and_examples.md

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ kernelspec:
1010
name: python3
1111
---
1212

13-
```{include} ../../README.md
13+
```{include} ../README.md
1414
---
15-
start-after: <!-- summary-end -->
16-
end-before: <!-- not-in-documentation-start -->
15+
start-after: <!-- implemented-algorithms-start -->
16+
end-before: <!-- implemented-algorithms-end -->
1717
---
1818
```
1919

@@ -37,7 +37,7 @@ In addition to the learners, `adaptive` also provides primitives for running the
3737
[ipyparallel](https://ipyparallel.readthedocs.io/en/latest/), and
3838
[distributed](https://distributed.readthedocs.io/en/latest/).
3939

40-
# Examples
40+
# 💡 Examples
4141

4242
Here are some examples of how Adaptive samples vs. homogeneous sampling.
4343
Click on the *Play* {fa}`play` button or move the sliders.
@@ -59,6 +59,9 @@ hv.output(holomap="scrubber")
5959

6060
## {class}`adaptive.Learner1D`
6161

62+
The `Learner1D` class is designed for adaptively learning 1D functions of the form `f: ℝ → ℝ^N`. It focuses on sampling points where the function is less well understood to improve the overall approximation.
63+
This learner is well-suited for functions with localized features or varying degrees of complexity across the domain.
64+
6265
Adaptively learning a 1D function (the plot below) and live-plotting the process in a Jupyter notebook is as easy as
6366

6467
```python
@@ -86,6 +89,11 @@ runner.live_plot()
8689
```{code-cell} ipython3
8790
:tags: [hide-input]
8891
92+
from bokeh.models import WheelZoomTool
93+
94+
wheel_zoom = WheelZoomTool(zoom_on_axis=False)
95+
96+
8997
def f(x, offset=0.07357338543088588):
9098
a = 0.01
9199
return x + a**2 / (a**2 + (x - offset) ** 2)
@@ -115,11 +123,14 @@ def get_hm(loss_per_interval, N=101):
115123
plot_homo = get_hm(uniform_loss).relabel("homogeneous sampling")
116124
plot_adaptive = get_hm(default_loss).relabel("with adaptive")
117125
layout = plot_homo + plot_adaptive
118-
layout.opts(toolbar=None)
126+
layout.opts(hv.opts.Scatter(active_tools=["box_zoom", wheel_zoom]))
119127
```
120128

121129
## {class}`adaptive.Learner2D`
122130

131+
The `Learner2D` class is tailored for adaptively learning 2D functions of the form `f: ℝ^2 → ℝ^N`. Similar to `Learner1D`, it concentrates on sampling points with higher uncertainty to provide a better approximation.
132+
This learner is ideal for functions with complex features or varying behavior across a 2D domain.
133+
123134
```{code-cell} ipython3
124135
:tags: [hide-input]
125136
@@ -147,11 +158,15 @@ def plot_compare(learner, npoints):
147158
148159
learner = adaptive.Learner2D(ring, bounds=[(-1, 1), (-1, 1)])
149160
plots = {n: plot_compare(learner, n) for n in range(4, 1010, 20)}
150-
hv.HoloMap(plots, kdims=["npoints"]).collate()
161+
plot = hv.HoloMap(plots, kdims=["npoints"]).collate()
162+
plot.opts(hv.opts.Image(active_tools=[wheel_zoom]))
151163
```
152164

153165
## {class}`adaptive.AverageLearner`
154166

167+
The `AverageLearner` class is designed for situations where you want to average the result of a function over multiple evaluations.
168+
This is particularly useful when working with random variables or stochastic functions, as it helps to estimate the mean value of the function.
169+
155170
```{code-cell} ipython3
156171
:tags: [hide-input]
157172
@@ -172,11 +187,15 @@ def plot_avg(learner, npoints):
172187
173188
174189
plots = {n: plot_avg(learner, n) for n in range(10, 10000, 200)}
175-
hv.HoloMap(plots, kdims=["npoints"])
190+
hm = hv.HoloMap(plots, kdims=["npoints"])
191+
hm.opts(hv.opts.Histogram(active_tools=[wheel_zoom]))
176192
```
177193

178194
## {class}`adaptive.LearnerND`
179195

196+
The `LearnerND` class is intended for adaptively learning ND functions of the form `f: ℝ^N → ℝ^M`.
197+
It extends the adaptive learning capabilities of the 1D and 2D learners to functions with more dimensions, allowing for efficient exploration of complex, high-dimensional spaces.
198+
180199
```{code-cell} ipython3
181200
:tags: [hide-input]
182201

docs/source/conf.py

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,19 @@
22

33
import os
44
import sys
5+
from pathlib import Path
56

6-
package_path = os.path.abspath("../..")
7+
package_path = Path("../..").resolve()
78
# Insert into sys.path so that we can import adaptive here
8-
sys.path.insert(0, package_path)
9+
sys.path.insert(0, str(package_path))
910
# Insert into PYTHONPATH so that jupyter-sphinx will pick it up
10-
os.environ["PYTHONPATH"] = ":".join((package_path, os.environ.get("PYTHONPATH", "")))
11+
os.environ["PYTHONPATH"] = ":".join(
12+
(str(package_path), os.environ.get("PYTHONPATH", "")),
13+
)
1114
# Insert `docs/` such that we can run the logo scripts
12-
docs_path = os.path.abspath("..")
13-
sys.path.insert(1, docs_path)
15+
docs_path = Path("..").resolve()
16+
sys.path.insert(1, str(docs_path))
17+
1418

1519
import adaptive # noqa: E402, isort:skip
1620

@@ -79,5 +83,23 @@
7983
nb_execution_raise_on_error = True
8084

8185

86+
def replace_named_emojis(input_file: Path, output_file: Path) -> None:
87+
"""Replace named emojis in a file with unicode emojis."""
88+
import emoji
89+
90+
with input_file.open("r") as infile:
91+
content = infile.read()
92+
content_with_emojis = emoji.emojize(content, language="alias")
93+
94+
with output_file.open("w") as outfile:
95+
outfile.write(content_with_emojis)
96+
97+
98+
# Call the function to replace emojis in the README.md file
99+
input_file = package_path / "README.md"
100+
output_file = docs_path / "README.md"
101+
replace_named_emojis(input_file, output_file)
102+
103+
82104
def setup(app):
83105
app.add_css_file("custom.css") # For the `live_info` widget

0 commit comments

Comments
 (0)