1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
[]
= "basin"
= "0.7.0"
= true
= true
= true
= true
= true
= "Numerical optimization in pure Rust, with pluggable linear-algebra backends and WASM support."
= "https://basin.bz"
= "https://docs.rs/basin"
= "README.md"
= ["optimization", "math", "numerics", "solver", "nonlinear"]
= ["mathematics", "science", "algorithms"]
# Build docs.rs with every backend enabled so the feature-gated solver and
# problem impls (nalgebra / ndarray / faer) render — not just the default
# `Vec<f64>` surface. `--cfg docsrs` turns on the `doc(auto_cfg)` attribute
# in `lib.rs` ("Available on crate feature `nalgebra` only").
[]
= true
= ["--cfg", "docsrs"]
[]
= "basin"
= "src/lib.rs"
[]
= ["problems"]
# Pin one version per backend (tenet 2 in AGENTS.md). A backend major bump
# becomes a basin major bump — do not introduce per-version features.
# `nalgebra-sparse` rides along on the same feature: it's a separate crate,
# but logically part of the nalgebra story (sparse Jacobians, sparse
# Cholesky). Folding it in keeps the manifest to one nalgebra feature.
= ["dep:nalgebra", "dep:nalgebra-sparse"]
= ["dep:ndarray"]
# Opt-in BLAS-backed ndarray. Off by default per the WASM hard constraint
# (cblas-sys is not wasm-compatible) and because BLAS wiring is a heavy
# toolchain story most basin users don't need. This feature only flips
# ndarray's `blas` switch; the consumer is still responsible for picking
# a BLAS source crate (`openblas-src`, `netlib-src`, `intel-mkl-src`,
# `accelerate-src`, ...) and adding it as a direct dependency. No analogue
# exists for nalgebra (0.34 has no `blas` feature; its BLAS path lives in
# the separate `nalgebra-lapack` crate) or for faer (pure-Rust by design).
= ["ndarray", "ndarray/blas"]
# `generativity` is a transitive dep of faer, surfaced here so it only enters
# the graph when `faer` is enabled.
= ["dep:faer", "dep:generativity"]
# Opt-in parallel evaluation (currently faer's rayon-backed linalg). Off by
# default because basin is typically embedded inside a caller that already
# manages parallelism (multi-start sweeps, R/Python schedulers, outer rayon
# loops) — a default-on thread pool causes oversubscription and fights the
# caller. WASM-incompatible: enabling this on wasm32-unknown-unknown will
# fail to compile. No-op unless a backend that hooks into it is also enabled.
= ["faer?/rayon"]
# Standard test-problem corpus (Rosenbrock, ...). Pure-Rust, no extra deps;
# default-on so plain `cargo test` keeps working without `--features problems`
# (integration tests can't see `cfg(test)` lib gating). Downstream can drop
# it via `default-features = false` to shrink the WASM bundle.
= []
[]
= { = "0.34", = true }
= { = "0.11", = true }
# Pure-Rust (no BLAS feature) so it stays wasm-compatible per the WASM hard
# constraint in AGENTS.md.
= { = "0.17", = true, = false }
# default-features off because faer's defaults pull in rayon (breaks wasm,
# tenet: no parallelism in default features) and npy (file I/O). We enable
# only `std` + `linalg` so the core dense types work on native and wasm.
# Rayon is reachable via the opt-in `parallel` feature above.
= { = "0.24", = true, = false, = [
"std",
"linalg",
] }
# Transitive dep of faer, surfaced as an optional dep so it only enters the
# graph behind the `faer` feature. basin doesn't use this crate directly.
= { = "1", = true }
# Re-exports `std::time::Instant` on native and a wasm-compatible shim on
# `wasm32-unknown-unknown`, so `MaxTime` works on both without feature gating.
# Tiny crate, MSRV 1.60, no transitive deps on native.
= "1"
# Seedable, wasm-safe RNG used by stochastic solvers (`RandomSearch`, CMA-ES,
# ...). `default-features = false` drops `std_rng` / `thread_rng` and the
# implicit `getrandom` JS-feature pull-in, so a
# `ChaCha8Rng::seed_from_u64(seed)` works on `wasm32-unknown-unknown` with
# no JS shim.
= { = "0.10", = false }
= { = "0.10", = false }
# Standard-normal sampling for CMA-ES. rand_distr 0.6 pairs with rand 0.10.
# default-features off to stay consistent with the wasm-safe rand setup.
= { = "0.6", = false }
[]
# Statistical bench harness. dev-dependency only — never enters the
# published or WASM dependency graph. `default-features = false` drops
# rayon (tenet: no parallelism by default) and plotters/html_reports
# (heavy tree, no value for CLI microbenchmarks), keeping just the
# `cargo bench` integration shim.
= { = "0.8", = false, = [
"cargo_bench_support",
] }
[[]]
= "rosenbrock"
= false
# Backend-vs-backend microbenchmark for the LM hot path (issue #9):
# nalgebra vs faer on the small dense ops LM runs each iteration. Needs
# both backends plus the test-problem corpus.
[[]]
= "lm_backends"
= false
= ["nalgebra", "faer", "problems"]
# Backend axis (axis 1): GD / Nelder-Mead / unconstrained L-BFGS on
# Rosenbrock across all four backends (Vec / nalgebra / ndarray / faer),
# isolating the cost of the linear-algebra layer. Needs every backend plus
# the test-problem corpus.
[[]]
= "solver_backends"
= false
= ["nalgebra", "ndarray", "faer", "problems"]
# Per-backend integration tests (`tests/rosenbrock_<backend>.rs`) gate
# themselves with `#![cfg(feature = "<backend>")]` rather than declaring
# `required-features` here — keeps the manifest free of one stanza per
# backend.