Rust API Reference¶
This section provides complete documentation for the MaxPro Rust crate.
Installation¶
Add to your Cargo.toml:
Or via command line:
Crate Features¶
| Feature | Description |
|---|---|
pyo3-bindings |
Build Python bindings |
debug |
Enable plotting utilities |
Modules¶
enums - Metrics Enum¶
Defines available metrics for optimization.
Functions¶
generate_lhd¶
Generates an LHD by taking in a number of samples and a number of dimensions. Creates a non-centered Latin Hypercube Design.
Arguments:
| Parameter | Type | Description |
|---|---|---|
n_samples |
u64 |
Number of samples for the LHD |
n_dim |
u64 |
Number of dimensions for the LHD |
rng |
&mut StdRng |
Random number generator |
Returns:
Vec<Vec<f64>> - A Latin Hypercube Design
Panics:
- If
n_samples == 0 - If
n_dim == 0 - If
n_samplesorn_dimis too large to index
Example:
use maxpro::lhd::generate_lhd;
use rand::{SeedableRng, rngs::StdRng};
let seed = 42u64;
let mut rng = StdRng::seed_from_u64(seed);
let lhd = generate_lhd(100, 5, &mut rng);
build_lhd¶
Using many iterations, selects an LHD that optimizes an allowed metric.
pub fn build_lhd(
n_samples: u64,
n_dim: u64,
n_iterations: u64,
metric: Option<enums::Metrics>,
seed: u64
) -> Vec<Vec<f64>>
Arguments:
| Parameter | Type | Description |
|---|---|---|
n_samples |
u64 |
Number of samples |
n_dim |
u64 |
Number of dimensions |
n_iterations |
u64 |
Number of iterations |
metric |
Option<enums::Metrics> |
Metric to consider (MaxPro or MaxiMin) |
seed |
u64 |
Random number seed |
Returns:
Vec<Vec<f64>> - Latin Hypercube Design that optimizes a metric using random sampling
Example:
use maxpro::{build_lhd, enums::Metrics};
let lhd = build_lhd(
100, // n_samples
10, // n_dim
500, // n_iterations
Some(Metrics::MaxPro), // metric
42 // seed
);
maxpro_criterion¶
Calculates the full, complete MaxPro criterion.
Arguments:
| Parameter | Type | Description |
|---|---|---|
design |
&Vec<Vec<f64>> |
Design for which to calculate the criterion |
Returns:
f64 - Value of the maximum projection criterion (lower is better)
Panics:
- If
design.len() == 0
Mathematical Background:
The MaxPro criterion is:
maximin_criterion¶
Calculates the minimum pairwise distance between points.
Arguments:
| Parameter | Type | Description |
|---|---|---|
design |
&Vec<Vec<f64>> |
Collection of input coordinates |
Returns:
f64 - Minimum pairwise distance between points (higher is better)
Panics:
- If
design.len() == 0
anneal_lhd¶
Simulated annealing for improving (maximizing or minimizing) a given metric. Supports two annealing strategies: coordinate swap (faster convergence) or jitter (fine-grained exploration).
pub fn anneal_lhd<F>(
design: &Vec<Vec<f64>>,
n_iterations: u64,
initial_temp: f64,
cooling_rate: f64,
metric: F,
minimize: bool,
seed: u64,
swap: bool
) -> Vec<Vec<f64>>
where
F: Fn(&Vec<Vec<f64>>) -> f64,
Arguments:
| Parameter | Type | Description |
|---|---|---|
design |
&Vec<Vec<f64>> |
Initial design of points |
n_iterations |
u64 |
Number of iterations for annealing |
initial_temp |
f64 |
Initial temperature for Metropolis algorithm |
cooling_rate |
f64 |
Cooling rate for annealing |
metric |
F |
A callable function that maps &Vec<Vec<f64>> to f64 |
minimize |
bool |
Whether to minimize or maximize the metric |
seed |
u64 |
Random seed |
swap |
bool |
Use coordinate swap annealing (true) or jitter annealing (false) |
Returns:
Vec<Vec<f64>> - A metric-optimized collection of points (not necessarily a Latin Hypercube)
Example:
use maxpro::anneal::anneal_lhd;
use maxpro::maxpro_utils::maxpro_criterion;
// Coordinate swap annealing (faster convergence)
let optimized = anneal_lhd(
&lhd,
5000, // n_iterations
1.0, // initial_temp
0.99, // cooling_rate
maxpro_criterion,
true, // minimize
42, // seed
true // use coordinate swap
);
// Jitter annealing (fine-grained exploration)
let optimized = anneal_lhd(
&lhd,
5000,
1.0,
0.99,
maxpro_criterion,
true,
42,
false // use jitter
);
Recommended Strategy
A good rule of thumb is to use 20% of iterations for coordinate swap annealing and 80% for jitter annealing. Coordinate swap annealing should always be performed before jitter annealing - swap first to quickly converge toward a good solution, then use jitter for fine-grained refinement.
For example, with 100,000 total annealing iterations:
let swap_annealed = anneal_lhd(&lhd, 20000, 1.0, 0.99, metric_fn, true, seed, true);
let final_annealed = anneal_lhd(&swap_annealed, 80000, 1.0, 0.99, metric_fn, true, seed + 1, false);
Important: It is only possible to achieve state-of-the-art performance using at least some coordinate swap annealing steps. Using jitter annealing alone (without coordinate swap) will not achieve competitive results.
CLI Usage¶
Build and run:
Options¶
| Option | Description |
|---|---|
--iterations <ITERATIONS> |
Number of iterations for optimization |
--samples <SAMPLES> |
Number of samples in the design |
--ndims <NDIMS> |
Number of dimensions |
--metric <METRIC> |
Metric to use: max-pro or maxi-min |
--seed <SEED> |
Random seed for reproducibility |
--anneal-iterations <ANNEAL_ITERATIONS> |
Number of annealing iterations (default: 100000) |
--anneal-t <ANNEAL_T> |
Initial temperature for annealing (default: 1.0) |
--anneal-cooling <ANNEAL_COOLING> |
Cooling rate for annealing (default: 0.99) |
--output-path <OUTPUT_PATH> |
Path to save output design |
--plot |
Enable plotting (requires debug feature) |
Examples¶
Generate MaxPro design:
Generate Maximin design:
Debug Feature¶
When the debug feature is enabled, you can use plotting utilities:
#[cfg(feature = "debug")]
pub fn plot_x_vs_y(
data: &Vec<Vec<f64>>,
output_path: &std::path::Path
) -> Result<(), Box<dyn std::error::Error>>
Plots a scatter plot of the first two dimensions of a design for diagnostics.
Raises:
- Err if data has fewer than 2 columns or 1 sample