Skip to content

Commit 53e1717

Browse files
authored
Merge pull request #109 from Axect/release-v0.43.0
Release v0.43.0
2 parents 4f6114a + c9b063e commit 53e1717

29 files changed

Lines changed: 428 additions & 60 deletions

File tree

‎.github/workflows/Github.yml‎

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,14 @@ jobs:
3030
- uses: actions/checkout@v4
3131
- name: Install OpenBLAS / LAPACK
3232
run: sudo apt-get update && sudo apt-get install -y libopenblas-dev liblapack-dev gfortran
33-
- name: Build
33+
- name: Build (OpenBLAS from source)
3434
run: cargo build --verbose --features O3-openblas
35-
- name: Run tests
35+
- name: Run tests (OpenBLAS from source)
3636
run: cargo test --verbose --features O3-openblas
37+
- name: Build (system OpenBLAS via pkg-config)
38+
run: cargo build --verbose --features O3-openblas-system
39+
- name: Run tests (system OpenBLAS via pkg-config)
40+
run: cargo test --verbose --features O3-openblas-system
3741

3842
pure-rust:
3943
name: Pure-Rust feature set
@@ -45,6 +49,20 @@ jobs:
4549
- name: Run tests
4650
run: cargo test --verbose --features "arrow complex csv indexmap json num-complex parallel parquet rayon rkyv serde"
4751

52+
# The deterministic core (no `rand` stack) must keep building for sandboxed
53+
# targets such as Typst / wasm plugins (#88).
54+
no-rand-wasm:
55+
name: No-rand core (wasm32)
56+
runs-on: ubuntu-latest
57+
steps:
58+
- uses: actions/checkout@v4
59+
- name: Add wasm32 target
60+
run: rustup target add wasm32-unknown-unknown
61+
- name: Test without the rand stack
62+
run: cargo test --verbose --no-default-features
63+
- name: Build for wasm32
64+
run: cargo build --verbose --no-default-features --target wasm32-unknown-unknown
65+
4866
feature-combinations:
4967
name: Feature combinations (cargo-hack)
5068
runs-on: ubuntu-latest
@@ -61,17 +79,19 @@ jobs:
6179
# HDF5 features (nc / netcdf) are excluded because they need an external
6280
# toolchain (vendor BLAS, HDF5 headers) or a non-Linux platform rather than
6381
# being a code problem; plot / pyo3 are exercised by the dedicated plot job.
82+
# openblas-src alone (default-features = false) has no TLS backend for its
83+
# source download, so it is only meaningful through O3-openblas-system.
6484
- name: Each feature builds on its own
6585
run: >
6686
cargo hack build --each-feature --optional-deps --keep-going
67-
--exclude-features O3-accelerate,O3-mkl,O3-netlib,nc,netcdf,plot,pyo3,blas-src,lapack-src
87+
--exclude-features O3-accelerate,O3-mkl,O3-netlib,nc,netcdf,plot,pyo3,blas-src,lapack-src,openblas-src
6888
# Pairwise (depth 2) coverage over the pure-Rust / numerical features. The
6989
# heavy compile units (arrow / parquet) and the backend / HDF5 / Python
7090
# features are excluded so the target dir does not blow up on a CI runner.
7191
- name: Pairwise feature powerset (pure-Rust / numerical)
7292
run: >
7393
cargo hack build --feature-powerset --depth 2 --optional-deps --keep-going
74-
--exclude-features O3,O3-openblas,O3-accelerate,O3-mkl,O3-netlib,nc,netcdf,plot,pyo3,blas-src,lapack-src,arrow,parquet
94+
--exclude-features O3,O3-openblas,O3-openblas-system,O3-accelerate,O3-mkl,O3-netlib,nc,netcdf,plot,pyo3,blas-src,lapack-src,openblas-src,arrow,parquet
7595
7696
plot:
7797
name: plot (pyo3 + matplotlib)

‎CONTRIBUTING.md‎

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,21 +41,8 @@ Peroxide follows the [Gitflow workflow]. A few practical rules:
4141

4242
## Source layout
4343

44-
A high-level map of `src/`; see each module's `mod.rs` and the [API docs](https://docs.rs/peroxide) for details.
45-
46-
| Module | Purpose |
47-
| ------------------ | ------------------------------------------------------------------ |
48-
| [`structure`](src/structure) | Core data structures: `Matrix`, `Vec<f64>` extensions, `DataFrame`, `Polynomial`, `Jet<N>` forward AD |
49-
| [`numerical`](src/numerical) | Numerical algorithms: ODE solvers, integration, interpolation, splines, root finding, optimization, eigenvalues |
50-
| [`statistics`](src/statistics) | Probability distributions, RNG wrappers, ordered statistics |
51-
| [`complex`](src/complex) | Complex vectors, matrices, and integrals (`complex` feature) |
52-
| [`special`](src/special) | Special functions (wrapper of `puruspe`) |
53-
| [`traits`](src/traits) | Shared trait definitions (math, functional programming, pointers) |
54-
| [`macros`](src/macros) | R / MATLAB / Julia style macros |
55-
| [`fuga`](src/fuga), [`prelude`](src/prelude) | The two user-facing import styles (explicit vs simple) |
56-
| [`util`](src/util) | Constructors, printing, plotting, low-level helpers |
57-
| [`ml`](src/ml) | Basic machine learning tools (beta) |
58-
| [`grave`](src/grave) | Retired implementations kept for reference; not compiled |
44+
The directories under `src/` map one-to-one to the public modules, so the module index in the [API docs](https://docs.rs/peroxide) doubles as the source map; start from a module's documentation and its `mod.rs`.
45+
The only exception is `src/grave/`, which holds retired implementations kept for reference and is excluded from compilation.
5946

6047
## Code of conduct
6148

‎Cargo.toml‎

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "peroxide"
3-
version = "0.42.0"
3+
version = "0.43.0"
44
authors = ["axect <axect@outlook.kr>"]
55
edition = "2018"
66
description = "Rust comprehensive scientific computation library contains linear algebra, numerical analysis, statistics and machine learning tools with familiar syntax"
@@ -30,8 +30,8 @@ criterion = { version = "0.5.1", features = ["html_reports"] }
3030

3131
[dependencies]
3232
csv = { version = "1.3", optional = true, default-features = false }
33-
rand = { version = "0.9", features = ["small_rng"] }
34-
rand_distr = "0.5"
33+
rand = { version = "0.9", features = ["small_rng"], optional = true }
34+
rand_distr = { version = "0.5", optional = true }
3535
order-stat = "0.1"
3636
puruspe = "0.4"
3737
matrixmultiply = { version = "0.3", features = ["threading"] }
@@ -47,13 +47,17 @@ blas = { version = "0.22", optional = true }
4747
lapack = { version = "0.19", optional = true }
4848
blas-src = { version = "0.14", optional = true, default-features = false }
4949
lapack-src = { version = "0.13", optional = true, default-features = false }
50+
# Only used to forward the `system` feature to the `openblas-src` instance
51+
# that `blas-src` / `lapack-src` already pull in (see `O3-openblas-system`).
52+
openblas-src = { version = "0.10", optional = true, default-features = false }
5053
serde = { version = "1.0", features = ["derive"], optional = true }
5154
rkyv = { version = "0.8", optional = true }
5255
json = { version = "0.12", optional = true }
5356
parquet = { version = "55", features = ["arrow", "snap"], optional = true }
5457
arrow = { version = "55", optional = true }
5558
indexmap = { version = "1", optional = true }
5659
num-complex = { version = "0.4", optional = true }
60+
num-traits = { version = "0.2", optional = true }
5761
rayon = { version = "1.10", optional = true }
5862

5963
[package.metadata.docs.rs]
@@ -75,18 +79,44 @@ features = [
7579
"serde",
7680
]
7781

82+
# Examples that exercise the random sampling stack are skipped when the
83+
# `rand` feature is disabled.
84+
[[example]]
85+
name = "dist"
86+
required-features = ["rand"]
87+
88+
[[example]]
89+
name = "matmul"
90+
required-features = ["rand"]
91+
92+
[[example]]
93+
name = "optim"
94+
required-features = ["rand"]
95+
96+
[[example]]
97+
name = "clippy_verify"
98+
required-features = ["rand"]
99+
78100
[features]
79-
default = []
101+
default = ["rand"]
102+
# Random sampling stack (`rand` / `rand_distr`): probability distributions,
103+
# RNG wrappers, and random constructors. Enabled by default; disable with
104+
# `default-features = false` for the deterministic core (ODE, integration,
105+
# splines, linear algebra), e.g. for wasm32 sandboxes without IO.
106+
rand = ["dep:rand", "dep:rand_distr"]
80107
# Bare BLAS / LAPACK FFI; downstream binary must also pull in a
81108
# `blas-src` / `lapack-src` backend to resolve the link symbols.
82109
O3 = ["blas", "lapack"]
83110
# Convenience flags that bundle a backend choice for `O3`.
84111
O3-openblas = ["O3", "blas-src/openblas", "lapack-src/openblas"]
112+
# Same as `O3-openblas`, but links the OpenBLAS already installed on the
113+
# system (found via pkg-config) instead of compiling OpenBLAS from source.
114+
O3-openblas-system = ["O3-openblas", "openblas-src/system"]
85115
O3-accelerate = ["O3", "blas-src/accelerate", "lapack-src/accelerate"]
86116
O3-mkl = ["O3", "blas-src/intel-mkl-dynamic-parallel", "lapack-src/intel-mkl-dynamic-parallel"]
87117
O3-netlib = ["O3", "blas-src/netlib", "lapack-src/netlib"]
88118
plot = ["pyo3"]
89119
nc = ["netcdf"]
90120
parquet = ["dep:parquet", "arrow", "indexmap"]
91-
complex = ["num-complex", "matrixmultiply/cgemm"]
121+
complex = ["num-complex", "num-traits", "matrixmultiply/cgemm"]
92122
parallel = ["rayon"]

‎README.md‎

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ For accelerated linear algebra, plotting, or DataFrame I/O, enable the matching
6666
Peroxide provides various features.
6767

6868
- `default` - Pure Rust (No dependencies of architecture - Perfect cross compilation)
69-
- `O3` - BLAS & LAPACK (Perfect performance but little bit hard to set-up - Strongly recommend to look [Peroxide with BLAS](https://github.com/Axect/Peroxide_BLAS))
69+
- `O3-openblas` / `O3-openblas-system` / `O3-accelerate` / `O3-mkl` / `O3-netlib` - BLAS & LAPACK accelerated linear algebra; pick one backend flag (see [Pre-requisite](#pre-requisite))
7070
- `plot` - With matplotlib of python, we can draw any plots.
7171
- `complex` - With complex numbers (vector, matrix and integral)
7272
- `parallel` - With some parallel functions
@@ -76,7 +76,7 @@ Peroxide provides various features.
7676
- `serde` - serialization with [Serde](https://serde.rs/).
7777
- `rkyv` - serialization with [rkyv](https://rkyv.org).
7878

79-
If you want to do high performance computation and more linear algebra, then choose `O3` feature.
79+
If you want to do high performance computation and more linear algebra, then choose one of the `O3-*` backend features.
8080
If you don't want to depend C/C++ or Fortran libraries, then choose `default` feature.
8181
If you want to draw plot with some great templates, then choose `plot` feature.
8282

@@ -267,25 +267,27 @@ The three groups below depend on external libraries or runtimes; install the rel
267267
Those crates only provide function signatures, so the link backend that supplies the actual `dgemv_` / `dpotrf_` / ... symbols must be selected separately.
268268
The simplest path is to enable one of the convenience flags below; each pulls in [`blas-src`](https://crates.io/crates/blas-src) and [`lapack-src`](https://crates.io/crates/lapack-src) with the matching backend.
269269

270-
| Convenience flag | Backend | Typical platform / use case |
271-
| ----------------- | ------------------ | --------------------------------------- |
272-
| `O3-openblas` | OpenBLAS | Linux, Windows, macOS via Homebrew |
273-
| `O3-accelerate` | Apple Accelerate | macOS (no extra system install) |
274-
| `O3-mkl` | Intel MKL | Intel CPUs, vendor-tuned performance |
275-
| `O3-netlib` | Netlib reference | Portability, lowest performance |
270+
| Convenience flag | Backend | Build-time requirements |
271+
| -------------------- | ----------------------------- | ------------------------------------------------ |
272+
| `O3-openblas` | OpenBLAS, compiled from source | C + Fortran toolchain, `make`, network access |
273+
| `O3-openblas-system` | System-installed OpenBLAS | `pkg-config` + the OpenBLAS system package |
274+
| `O3-accelerate` | Apple Accelerate | macOS only (no extra system install) |
275+
| `O3-mkl` | Intel MKL | Intel's redistributable (fetched automatically) |
276+
| `O3-netlib` | Netlib reference, compiled from source | `cmake` + Fortran toolchain (lowest performance) |
276277

277-
If you need a backend not in the list above (for example BLIS or R's BLAS), enable the bare `O3` flag and add `blas-src` / `lapack-src` to your downstream binary's `Cargo.toml` with the appropriate features yourself.
278+
`O3-openblas` does **not** use a system-installed OpenBLAS: the [`openblas-src`](https://crates.io/crates/openblas-src) crate downloads the OpenBLAS source tarball during the cargo build and compiles it, so it needs `gcc`, `gfortran`, `make`, and network access, but no BLAS system package.
279+
The download happens over HTTPS through `openblas-src`'s default `rustls` TLS backend; if you depend on `openblas-src` directly with `default-features = false` (as some older guides suggest), you must re-enable one of its `rustls` / `native-tls` features yourself or the build will fail.
278280

279-
System libraries still need to be present on the host for `O3-openblas` and `O3-netlib`; install them with:
281+
`O3-openblas-system` skips the source build and links the OpenBLAS already installed on the host, discovered via `pkg-config`:
280282

281283
| Platform | Install |
282284
| --------------------- | ---------------------------------------------------- |
283-
| Debian / Ubuntu | `sudo apt install libopenblas-dev liblapack-dev` |
284-
| Fedora / RHEL | `sudo dnf install openblas-devel lapack-devel` |
285-
| Arch Linux | `sudo pacman -S openblas lapack` |
286-
| macOS (Homebrew) | `brew install openblas lapack` |
285+
| Debian / Ubuntu | `sudo apt install libopenblas-dev` |
286+
| Fedora / RHEL | `sudo dnf install openblas-devel` |
287+
| Arch Linux | `sudo pacman -S openblas` |
288+
| macOS (Homebrew) | `brew install openblas` |
287289

288-
`O3-accelerate` and `O3-mkl` ship their own backend (Apple's framework and Intel's redistributable, respectively), so they need no further system packages.
290+
If you need a backend not in the list above (for example BLIS or R's BLAS), enable the bare `O3` flag and add `blas-src` / `lapack-src` to your downstream binary's `Cargo.toml` with the appropriate features yourself.
289291

290292
> **Note:** `O3-accelerate` only builds on Apple targets. Enabling it on Linux or Windows fails while compiling `accelerate-src` with ``error: library kind `framework` is only supported on Apple targets``; pick `O3-openblas`, `O3-mkl`, or `O3-netlib` instead. For the same reason, exclude `O3-accelerate` (and `O3-mkl` / `O3-netlib` unless their toolchains are installed) when running tools like `cargo hack --each-feature` on Linux.
291293
@@ -335,6 +337,7 @@ cargo add peroxide --features "<FEATURES>" # opt-in features
335337
| Goal | Command |
336338
| ------------------------------------------------- | ------------------------------------------------------------------------- |
337339
| Linear algebra on Linux / Windows | `cargo add peroxide --features O3-openblas` |
340+
| Linear algebra with system OpenBLAS | `cargo add peroxide --features O3-openblas-system` |
338341
| Linear algebra on macOS | `cargo add peroxide --features O3-accelerate` |
339342
| Plotting via Python / matplotlib | `cargo add peroxide --features plot` |
340343
| DataFrame + Parquet I/O | `cargo add peroxide --features parquet` |
@@ -350,7 +353,8 @@ The remaining single-crate flags exist so advanced users can pull in just one op
350353

351354
| Flag | Requires | Purpose |
352355
| ---------------- | ----------------------- | ------------------------------------------------------------- |
353-
| `O3-openblas` | OpenBLAS | BLAS / LAPACK accelerated linear algebra (Linux / Windows) |
356+
| `O3-openblas` | OpenBLAS (from source) | BLAS / LAPACK accelerated linear algebra (Linux / Windows) |
357+
| `O3-openblas-system` | OpenBLAS (system) | Same, linking the system-installed OpenBLAS via pkg-config |
354358
| `O3-accelerate` | Apple Accelerate | Same, using the Accelerate framework on macOS |
355359
| `O3-mkl` | Intel MKL | Same, using Intel MKL |
356360
| `O3-netlib` | Netlib | Same, using the reference Netlib BLAS |
@@ -363,6 +367,7 @@ The remaining single-crate flags exist so advanced users can pull in just one op
363367
| `json` | (pure Rust) | JSON I/O for `DataFrame` |
364368
| `serde` | (pure Rust) | `serde` (de)serialization |
365369
| `rkyv` | (pure Rust) | `rkyv` zero-copy (de)serialization |
370+
| `rand` | (pure Rust) | Random sampling stack: distributions, RNG wrappers, `rand()` constructors. **On by default**; disable with `default-features = false` to get the deterministic core (ODE, integration, splines, linear algebra) for sandboxed targets like wasm32 |
366371

367372
<details>
368373
<summary><b>Advanced: single-crate flags</b></summary>

‎RELEASES.md‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,28 @@
1+
# Release 0.43.0 (2026-07-11)
2+
3+
## Breaking changes
4+
5+
- Make the `rand` / `rand_distr` sampling stack optional behind the default-on `rand` feature ([#88](https://github.com/Axect/Peroxide/issues/88), [#104](https://github.com/Axect/Peroxide/pull/104))
6+
- Existing default-feature users are unchanged.
7+
- `default-features = false` now provides a deterministic core without RNG dependencies; sampling APIs require the `rand` feature.
8+
- This is a breaking change for users who already disabled default features and relied on sampling APIs.
9+
10+
## New features
11+
12+
- Add the `Dirichlet(α)` probability distribution ([#95](https://github.com/Axect/Peroxide/pull/95))
13+
- Add `O3-openblas-system` for linking a system-installed OpenBLAS through `pkg-config` ([#98](https://github.com/Axect/Peroxide/issues/98), [#107](https://github.com/Axect/Peroxide/pull/107))
14+
15+
## Documentation
16+
17+
- Clarify BLAS/LAPACK backend selection, OpenBLAS source versus system builds, TLS prerequisites, and HDF5 constraints ([#98](https://github.com/Axect/Peroxide/issues/98))
18+
- Remove the stale `Peroxide_BLAS` setup link from the main README; the archived repository is retained for historical reference
19+
- Replace the hand-maintained source-layout table with module-level docs.rs pointers and improve module descriptions ([#99](https://github.com/Axect/Peroxide/issues/99), [#108](https://github.com/Axect/Peroxide/pull/108))
20+
21+
## CI / Lint
22+
23+
- Add cargo-hack coverage for individual features and pairwise pure-Rust feature combinations ([#98](https://github.com/Axect/Peroxide/issues/98))
24+
- Add dedicated CI coverage for system/source OpenBLAS, no-rand `wasm32`, plotting, formatting, and clippy
25+
126
# Release 0.42.0 (2026-07-06)
227

328
## Breaking changes

‎TODO.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
- [x] Bernoulli
2222
- [x] Beta
2323
- [x] Binomial
24-
- [ ] Dirichlet
24+
- [x] Dirichlet
2525
- [x] Gamma
2626
- [x] Student's t
2727
- [x] Uniform

‎src/complex/matrix.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use std::{
77
use anyhow::{bail, Result};
88
use matrixmultiply::CGemmOption;
99
use num_complex::Complex;
10+
use num_traits::{One, Zero};
1011
use peroxide_num::{ExpLogOps, PowOps, TrigOps};
11-
use rand_distr::num_traits::{One, Zero};
1212

1313
use crate::{
1414
complex::C64,

‎src/complex/mod.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! Complex vectors, matrices, and integrals, enabled by the `complex` feature
2+
13
use num_complex::Complex;
24

35
pub type C64 = Complex<f64>;

‎src/fuga/mod.rs‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,10 +183,17 @@ pub use crate::complex::{integral::*, matrix::*, vector::*, C64};
183183
#[allow(ambiguous_glob_reexports)]
184184
pub use crate::structure::{ad::*, dataframe::*, matrix::*, polynomial::*, vector::*};
185185

186-
pub use crate::util::{api::*, low_level::*, non_macro::*, print::*, useful::*, wrapper::*};
186+
pub use crate::util::{api::*, low_level::*, non_macro::*, print::*, useful::*};
187187

188+
#[cfg(feature = "rand")]
189+
pub use crate::util::wrapper::*;
190+
191+
#[allow(unused_imports)]
192+
pub use crate::statistics::{ops::*, stat::*};
193+
194+
#[cfg(feature = "rand")]
188195
#[allow(unused_imports)]
189-
pub use crate::statistics::{dist::*, ops::*, rand::*, stat::*};
196+
pub use crate::statistics::{dist::*, rand::*};
190197

191198
#[allow(unused_imports)]
192199
pub use crate::special::function::*;
@@ -205,6 +212,7 @@ pub use crate::util::plot::*;
205212

206213
pub use anyhow;
207214
pub use paste;
215+
#[cfg(feature = "rand")]
208216
pub use rand::prelude::*;
209217

210218
// =============================================================================

0 commit comments

Comments
 (0)