Skip to content

Commit 0f906f9

Browse files
authored
Prepare for 0.9.0 release (#678)
## Description <!-- Provide a brief description of the PR's purpose here. --> Preparation for pyribs 0.9.0 release! ## TODO <!-- Notable points that this PR has either accomplished or will accomplish. --> - [x] Add What's New - [x] Update version in `ribs/__init__.py` - [x] Update history ## Status - [x] I have read the guidelines in [CONTRIBUTING.md](https://github.com/icaros-usc/pyribs/blob/master/CONTRIBUTING.md) - [x] I have linted and formatted my code with `ruff` and `ty` - [x] I have tested my code by running `pytest` - [x] I have added a description of my change to the changelog in `HISTORY.md` - [x] This PR is ready to go
1 parent 54ecc26 commit 0f906f9

File tree

4 files changed

+279
-100
lines changed

4 files changed

+279
-100
lines changed

HISTORY.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# History
22

3-
## (Forthcoming)
3+
## 0.9.0
4+
5+
To learn about this release, see our page on What's New in v0.9.0:
6+
https://docs.pyribs.org/en/stable/whats-new.html
47

58
### Changelog
69

@@ -106,7 +109,7 @@ This release makes some minor updates to 0.8.0.
106109
## 0.8.0
107110

108111
To learn about this release, see our page on What's New in v0.8.0:
109-
https://docs.pyribs.org/en/stable/whats-new.html
112+
https://docs.pyribs.org/en/stable/whats-new/v0.8.0.html
110113

111114
### Changelog
112115

docs/whats-new.md

Lines changed: 163 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1,113 +1,178 @@
1-
# What's New in v0.8.0
2-
3-
Pyribs v0.8.0 adds support for several new algorithms while making it easier
4-
than ever to design new ones. Below we highlight some of the most notable
5-
updates. For the full list of changes, please refer to our History page.
6-
7-
## 🧠 New Algorithms
8-
9-
Pyribs v0.8.0 introduces implementations of several new algorithms:
10-
11-
- **Novelty Search**
12-
([Lehman 2011](https://web.archive.org/web/20220707041732/https://eplex.cs.ucf.edu/papers/lehman_ecj11.pdf))
13-
via the {class}`~ribs.archives.ProximityArchive`. We illustrate how to run
14-
Novelty Search in our new tutorial, {doc}`/tutorials/ns_maze`. Visualization
15-
is available via {func}`~ribs.visualize.proximity_archive_plot`.
16-
- Thanks to [@gresavage](https://github.com/gresavage) for helping with this
17-
implementation!
18-
- **Density Descent Search**
19-
([Lee 2024](https://dl.acm.org/doi/10.1145/3638529.3654001)) via the
20-
{class}`~ribs.archives.DensityArchive`. We illustrate how to run Density
21-
Descent Search in {doc}`examples/sphere`.
22-
- **BOP-Elites**
23-
([Kent 2024](https://ieeexplore.ieee.org/abstract/document/10472301)) via
24-
{class}`~ribs.emitters.BayesianOptimizationEmitter` and
25-
{class}`~ribs.schedulers.BayesianOptimizationScheduler`. An example of running
26-
BOP-Elites is available in the example here: {doc}`examples/bop_elites`.
27-
- As part of implementing BOP-Elites, a new
28-
{class}`~ribs.archives.GridArchive.retessellate` method has been added to
29-
GridArchive to allow changing the layout of the grid.
30-
- Thanks to [@szhaovas](https://github.com/szhaovas) for working on this
31-
implementation!
32-
33-
We have also added a {class}`~ribs.archives.CategoricalArchive` where the
34-
measures can be categorical values, e.g., `["Cat", "Dog", "Mouse"]`.
35-
36-
The {doc}`supported-algorithms` page now includes a list of algorithms supported
37-
in pyribs.
38-
39-
## 📜 Single-File Implementations for Archives
40-
41-
To make it easier to understand current archives and create new archives, we
42-
have made each archive into a "single-file implementation." Previously,
43-
{class}`~ribs.archives.ArchiveBase` contained a lot of archive logic. While this
44-
made it easier to share code between archives, it also made it harder to
45-
understand each archive's implementation. For instance, the implementation for
46-
{class}`~ribs.archives.GridArchive` was split between the GridArchive file and
47-
the ArchiveBase file. In addition, putting logic in ArchiveBase meant that new
48-
implementations often had to override that logic, which quickly became
49-
confusing. To overcome these issues, we have refactored ArchiveBase to be an
50-
interface that contains almost no logic. All logic for archive implementations
51-
is now placed in each archive's file, and to reduce repeated code, we have added
52-
various utility functions. We anticipate that it will now be much easier to
53-
understand how each archive operates.
54-
55-
## 🛠 Flexible Data Handling
56-
57-
Archives now support more flexible data specifications. Notably, solutions are
58-
no longer restricted to 1D arrays. They can now be scalars or multi-dimensional
59-
arrays; simply pass the appropriate shape as the
60-
{attr}`~ribs.archives.ArchiveBase.solution_dim` in the archive. Separate data
61-
types for the solutions, objectives, and measures are also supported by passing
62-
in a dict as the `dtype` argument for archives.
63-
64-
For example, the following creates a GridArchive where the solutions can be
65-
strings!
1+
# What's New in v0.9.0
2+
3+
We are excited to present pyribs 0.9.0, which introduces a host of new features
4+
intended to make the library more flexible than ever! This release supports
5+
Python 3.10 and up, with Python 3.9 being dropped due to being end-of-life.
6+
7+
## Overhauling CVTArchive
8+
9+
This release introduces a number of new features and (unfortunately) breaking
10+
changes to {class}`~ribs.archives.CVTArchive`. For most users, it should suffice
11+
to know that an initialization of CVTArchive that once looked like this:
12+
13+
```python
14+
from ribs.archives import CVTArchive
15+
16+
archive = CVTArchive(
17+
solution_dim=12,
18+
cells=10000,
19+
ranges=[(-1, 1), (-1, 1)],
20+
use_kd_tree=True,
21+
)
22+
```
23+
24+
Now looks like this. Note that `cells` has been replaced with `centroids`, and
25+
`use_kd_tree` has been replaced with `nearest_neighbors`.
6626

6727
```python
28+
from ribs.archives import CVTArchive
29+
30+
archive = CVTArchive(
31+
solution_dim=12,
32+
centroids=10000,
33+
ranges=[(-1, 1), (-1, 1)],
34+
nearest_neighbors="scipy_kd_tree",
35+
)
36+
```
37+
38+
Our new tutorial serves as a starting point for using the new archive:
39+
{doc}`/tutorials/cvt_centroids`.
40+
41+
### Detailed Changes
42+
43+
Below we provide further details on the changes, with even more detail available
44+
in {issue}`621`.
45+
46+
- **Centroid generation has been moved out of CVTArchive.** In the past,
47+
CVTArchive contained methods for generating centroids that could be specified
48+
via the `centroid_method` parameter. However, centroid generation is extremely
49+
customizable, and we believe it should be left to the user rather than handled
50+
in the archive initialization itself. As such, **we have removed the
51+
`centroid_method` parameter as well as these centroid generation methods,**
52+
and we have instead added a new tutorial that shows different options for
53+
specifying and generating centroids: {doc}`/tutorials/cvt_centroids`.
54+
55+
In a similar vein, it is now possible to generate centroids with the
56+
{func}`~ribs.archives.k_means_centroids` function, which samples points in a
57+
measure space and performs k-means clustering to identify the centroids. This
58+
function, as well as other workflows with centroids, are included in the above
59+
tutorial.
60+
61+
Finally, since we have separated centroid generation from CVTArchive, **the
62+
`samples` property is now deprecated, as is the `plot_samples` parameter** in
63+
{func}`~ribs.visualize.cvt_archive_heatmap` and
64+
{func}`~ribs.visualize.cvt_archive_3d_plot`.
65+
66+
- **`cells` and `custom_centroids` are now replaced with the `centroids`
67+
parameter.** We found that `cells` and `custom_centroids` were redundant with
68+
each other. Instead, the new `centroids` parameter can either be an int
69+
indicating the number of cells in the archive, or an array-like with the
70+
coordinates of the centroids. This supports the separation of centroid
71+
generation from CVTArchive by making it easier to specify centroids.
72+
Previously, both `cells` and `custom_centroids` had to be specified to use
73+
centroids created by the user, but now, only `centroids` is needed.
74+
75+
- **Nearest-neighbor lookup is now more flexible.** Previously, we only
76+
supported two methods for nearest-neighbor lookup, via brute-force and via
77+
scipy's {class}`~scipy.spatial.KDTree`. To support more methods, **we have
78+
deprecated the `use_kd_tree` parameter and replaced it with a new
79+
`nearest_neighbors` parameter.** This `nearest_neighbors` parameter can be set
80+
to `"scipy_kd_tree"`, `"brute_force"`, or the newest option, `"sklearn_nn"`,
81+
which uses scikit-learn's {class}`~sklearn.neighbors.NearestNeighbors`.
82+
83+
Correspondingly, we have added `sklearn_nn_kwargs` and `kdtree_query_kwargs`,
84+
which allow specifying more options to the internal objects used for
85+
nearest-neighbor search.
86+
87+
## New dtype Specifications for Archives
88+
89+
Previously, we found specifying separate dtypes for the solution, objective, and
90+
measures in an archive to be complicated due to requiring passing a dict.
91+
Instead, we now allow passing in individual dtypes: `solution_dtype`,
92+
`objective_dtype`, and `measures_dtype`. It is also still possible to pass in
93+
`dtype` to set all of these at once. For example, the following sets the
94+
solutions to be objects, while the objective and measures are float32:
95+
96+
```python
97+
import numpy as np
98+
99+
from ribs.archives import GridArchive
100+
68101
archive = GridArchive(
69102
solution_dim=(),
70-
dims=[10, 20],
71-
ranges=[(-1, 1), (-2, 2)],
72-
dtype={
73-
"solution": object,
74-
"objective": np.float32,
75-
"measures": np.float32
76-
},
103+
dims=[20, 20],
104+
ranges=[(1, 10), (1, 10)],
105+
solution_dtype=object,
106+
objective_dtype=np.float32,
107+
measures_dtype=np.float32,
77108
)
109+
```
110+
111+
(This example is taken from the tutorial {doc}`tutorials/qdaif`.) For more info,
112+
see {pr}`639`, {pr}`643`, and {pr}`661`.
113+
114+
## Multi-Dimensional Solutions in Emitters
115+
116+
This release improves support for multi-dimensional solutions in emitters. In
117+
particular, the {class}`~ribs.emitters.GaussianEmitter` and
118+
{class}`~ribs.emitters.IsoLineEmitter` can now generate multi-dimensional
119+
solutions ({pr}`650`). In a similar vein, it is now possible to specify the
120+
bounds of the solution space in emitters via `lower_bounds` and `upper_bounds`
121+
({pr}`649`, {pr}`657`). The original `bounds` parameter is still supported but
122+
cannot be used at the same time. Thus, the following creates a GaussianEmitter
123+
that generates solutions of shape `(5, 5)` bounded by -1.0 and 1.0 in each
124+
dimension:
78125

79-
add_info = archive.add(
80-
solution=["This is Bob", "Bob says hi", "Good job Bob"],
81-
objective=[1.0, 2.0, 3.0],
82-
measures=[[0, 0], [0.25, 0.25], [0.5, 0.5]],
126+
```python
127+
import numpy as np
128+
129+
from ribs.archives import GridArchive
130+
from ribs.emitters import GaussianEmitter
131+
132+
archive = GridArchive(
133+
solution_dim=(5, 5),
134+
dims=[20, 20],
135+
ranges=[(-2, 2), (-2, 2)],
83136
)
137+
138+
emitters = [
139+
GaussianEmitter(
140+
archive,
141+
sigma=0.1,
142+
x0=np.zeros((5, 5)),
143+
lower_bounds=np.full((5, 5), -1.0),
144+
upper_bounds=np.full((5, 5), 1.0),
145+
batch_size=64,
146+
)
147+
]
84148
```
85149

86-
## 🚨 Breaking Changes
150+
## 🚨 Additional Breaking Changes
151+
152+
- In {class}`~ribs.archives.CVTArchive` and
153+
{class}`~ribs.archives.ProximityArchive`, `ckdtree_kwargs` is now referred to
154+
as `kdtree_kwargs`, as we have stopped using scipy's cKDTree in favor of
155+
KDTree ({pr}`676`)
156+
- In {class}`~ribs.archives.ArrayStore`, `as_raw_dict` and `from_raw_dict` have
157+
been removed as they were not being used ({pr}`575`)
87158

88-
v0.8.0 includes several **backwards-incompatible changes**, most of which are
89-
part of an ongoing effort to streamline the library:
159+
## ✨ Additional Features
90160

91-
- `archive.dtype` has been replaced with a more expressive `archive.dtypes`
92-
dictionary, since solutions, objectives and measures can now have different
93-
dtypes.
94-
- {class}`~ribs.archives.cqd_score` is now a separate utility function, instead
95-
of being a method on the archives.
96-
- The {attr}`~ribs.archives.ArchiveBase.field_list` and
97-
{attr}`~ribs.archives.ArchiveBase.dtypes` properties on current archives
98-
include the `index` field, since `index` is no longer a required part of
99-
archives.
100-
- Archive `add` methods and the {class}`~ribs.archives.ArrayStore` have been
101-
simplified to no longer use "transforms," which significantly complicated the
102-
implementation.
161+
- In the archives, {meth}`~ribs.archives.ArchiveBase.sample_elites` now supports
162+
the `replace` parameter to indicate whether elites should be replaced when
163+
sampling ({pr}`682`)
164+
- {func}`~ribs.visualize.parallel_axes_plot` now supports plotting
165+
`ProximityArchive` ({pr}`647`)
166+
- {class}`~ribs.archives.ArrayStore` now supports backends such as torch and
167+
cupy, drawing from the
168+
[Python array API standard](https://data-apis.org/array-api/latest/)
169+
({issue}`570`, {pr}`645`)
103170

104-
## 🐛 Bug Fixes
171+
## Developer Workflow
105172

106-
In this release, we
107-
[fixed a bug in BanditScheduler](https://github.com/icaros-usc/pyribs/pull/489)
108-
thanks to [@Tekexa](https://github.com/Tekexa)! Now,
109-
{class}`~ribs.schedulers.BanditScheduler` correctly maintains a stable number of
110-
active emitters.
173+
Finally, in addition to the above library improvements, we have migrated from
174+
using yapf and pylint to using [ruff](https://docs.astral.sh/ruff/) and
175+
[ty](https://docs.astral.sh/ty/) for formatting, linting, and type checking.
111176

112177
## Past Editions
113178

@@ -116,6 +181,7 @@ Past editions of "What's New" are available below.
116181
```{toctree}
117182
:maxdepth: 1
118183
184+
whats-new/v0.8.0
119185
whats-new/v0.7.0
120186
whats-new/v0.5.0
121187
```

0 commit comments

Comments
 (0)