Crate simple_optimization
source · [−]Expand description
Optimization algorithms.
Crate status
I made this since alternatives in the Rust ecosystem seemed awkward. I’m just some random dude, don’t expect too much.
Currently looking into adding macros random_search!
, grid_search!
, etc.
These will allow you to optimize a tuple of ranges instead of an array, therefore allowing varying types. This is likely to come before gaussian optimization.
Basic guide
All the functions have the approximate form:
fn function<A,T,const N: usize>(
// The values you want to optimise and there respective ranges.
// E.g. Optimizing 2 `f32`s between 0..1 and 2..3 `[0f32..1f32, 2f32..3f32]`).
ranges: [Range<T>; N],
// The function you want to optimize (loss/cost/whatever).
// `&[T; N]` are the input parameters which the algorithm will adjust to
// minimize the function.
// `Option<Arc<A>>` is how you can pass additional data you might want to use.
f: fn(&[T; N], Option<Arc<A>>) -> f64,
// The additional data for the evaluation function.
evaluation_data: Option<Arc<A>>,
// Polling data, e.g. how often (if at all) you want to print progress, see `Polling`
// struct docs for more info.
polling: Option<Polling>,
// The number of threads to use, leaving this as `None` uses all available (recommended).
// If set it must be >=2.
threads: Option<usize>,
// ...
) -> [T;N] { /* ... */}
The typical use case will be run with --nocapture
(without this progress logging will not print), e.g.:
cargo run --nocapture
cargo run --release -- --nocapture
cargo test your_test --release -- --nocapture
The most thorough output of progress might look like:
2300
565 (24.57%) 00:00:11 / 00:00:47 [25.600657363049734] { [563.0ns, 561.3ms, 125.0ns, 110.0ns] [2.0µs, 361.8ms, 374.0ns, 405.0ns] [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] }
This output describes:
- The total number of iterations
2300
. - The total number of completed iterations
565
. - The percent of iterations completed
(24.57%)
(565/2300=0.2457...
). - The time running
00:00:11
(hh:mm:ss
). - The estimated time remaining
00:00:47
(hh:mm:ss
). - The current best value
[25.600657363049734]
. - The most recently measured times between execution positions (effectively time taken for thread to go from some line, to another line (defined specifically with
update_execution_position
in the code)[563.0ns, 561.3ms, 125.0ns, 110.0ns]
. - The averages times between execution positions (this is average across entire runtime rather than since last measured)
[2.0µs, 361.8ms, 374.0ns, 405.0ns]
. - The execution positions of threads (
0
is when a thread is completed, rest represent a thread having hit some line, which triggered this setting, but yet to hit next line which changes it, effectively being between 2 positions) ([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
). What these specifically refer to in code varies between functions.
The last 3 of these I wouldn’t expect you would ever use. But I use them for debugging this library and I think they could possibly in some rare circumstance be useful to you (so no harm having them as an option, well, only a few microseconds of harm).
Macros
Castes all given ranges to f64
values and calls grid_search()
.
Castes all given ranges to f64
values and calls random_search()
.
Castes all given ranges to f64
values and calls simulated_annealing()
.
Structs
The struct defining polling data.
Enums
Cooling schedule for simulated annealing.