somatize_study/sampler/random.rs
1//! Drawn from the space, looking at nothing else.
2
3use super::Sampler;
4use super::drawing::{draw, stream, unit};
5use crate::{Point, Space};
6
7/// Uniform in every knob, independently.
8///
9/// The baseline and not a straw man: over a space where few knobs matter, random
10/// search beats a grid, which spends its budget re-testing the ones that do not
11/// (Bergstra and Bengio, 2012). It is what [`Tpe`](super::Tpe) falls back to
12/// before it has anything to learn from. Its point is a function of the **seed
13/// and the index**, so two machines drawing trial 7 draw the same point.
14#[derive(Debug, Clone, PartialEq, Eq, Hash)]
15pub struct Random {
16 /// The seed. There is no "unseeded": a search you cannot re-run is a result
17 /// you cannot check.
18 pub seed: u64,
19}
20
21impl Random {
22 /// The `trial`-th point. It never runs out, and it never looks at what the
23 /// finished trials did — which is the whole of what it is.
24 pub fn ask(
25 &self,
26 space: &Space,
27 trial: usize,
28 _seen: &[(Point, Option<f64>)],
29 ) -> Option<Point> {
30 if space.is_empty() {
31 return None;
32 }
33 let mut state = stream(self.seed, trial);
34 Some(Point::of(
35 space
36 .dimensions()
37 .iter()
38 .map(|(name, dimension)| (name.clone(), draw(dimension, unit(&mut state))))
39 .collect(),
40 ))
41 }
42}
43
44impl From<Random> for Sampler {
45 fn from(how: Random) -> Self {
46 Self::Random(how)
47 }
48}