Skip to main content

hyperopt_core/
value.rs

1use serde::{Deserialize, Serialize};
2use std::fmt;
3
4/// A concrete hyperparameter value suggested for a trial.
5///
6/// For v1 the categorical variant is restricted to string/enum-like values
7/// (`Categorical(String)`); arbitrary user types are intentionally out of scope
8/// to keep the sampler/storage plumbing simple. Callers that need richer
9/// categoricals should map their type to/from a stable string label.
10#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
11pub enum Value {
12    /// A continuous value (from a `Uniform`/`LogUniform` distribution).
13    Float(f64),
14    /// A discrete integer value (from an `IntUniform` distribution).
15    Int(i64),
16    /// A categorical choice, identified by its label.
17    Categorical(String),
18}
19
20impl Value {
21    /// Returns the inner `f64` if this is a [`Value::Float`].
22    pub fn as_float(&self) -> Option<f64> {
23        match self {
24            Value::Float(x) => Some(*x),
25            _ => None,
26        }
27    }
28
29    /// Returns the inner `i64` if this is a [`Value::Int`].
30    pub fn as_int(&self) -> Option<i64> {
31        match self {
32            Value::Int(x) => Some(*x),
33            _ => None,
34        }
35    }
36
37    /// Returns the inner label if this is a [`Value::Categorical`].
38    pub fn as_categorical(&self) -> Option<&str> {
39        match self {
40            Value::Categorical(s) => Some(s.as_str()),
41            _ => None,
42        }
43    }
44
45    /// Best-effort numeric projection, used by adaptive samplers and the
46    /// param-importance proxy. Categoricals have no meaningful scalar and
47    /// return `None`.
48    pub fn to_f64(&self) -> Option<f64> {
49        match self {
50            Value::Float(x) => Some(*x),
51            Value::Int(x) => Some(*x as f64),
52            Value::Categorical(_) => None,
53        }
54    }
55}
56
57impl fmt::Display for Value {
58    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
59        match self {
60            Value::Float(x) => write!(f, "{x}"),
61            Value::Int(x) => write!(f, "{x}"),
62            Value::Categorical(s) => write!(f, "{s}"),
63        }
64    }
65}