rustyml 0.14.0

A high-performance machine learning & deep learning library in pure Rust, offering ML algorithms and neural network support
Documentation
//! Shared parameter validators for optimizer constructors

use crate::error::Error;

/// Validates that the learning rate is positive and finite
///
/// # Parameters
///
/// - `learning_rate` - The learning rate value to validate
///
/// # Errors
///
/// Returns `Error::InvalidParameter` if the learning rate is not positive or not finite
pub(super) fn validate_learning_rate(learning_rate: f32) -> Result<(), Error> {
    if !(learning_rate > 0.0 && learning_rate.is_finite()) {
        return Err(Error::invalid_parameter(
            "learning_rate",
            format!("must be positive and finite, got {}", learning_rate),
        ));
    }
    Ok(())
}

/// Validates that a decay rate (beta or rho) is in the range [0, 1) and finite
///
/// # Parameters
///
/// - `value` - The decay rate value to validate
/// - `param_name` - The name of the parameter (for error messages)
///
/// # Errors
///
/// Returns `Error::InvalidParameter` if the value is out of range or not finite
pub(super) fn validate_decay_rate(value: f32, param_name: &str) -> Result<(), Error> {
    if !((0.0..1.0).contains(&value) && value.is_finite()) {
        return Err(Error::invalid_parameter(
            param_name.to_string(),
            format!("must be in range [0, 1) and finite, got {}", value),
        ));
    }
    Ok(())
}

/// Validates that epsilon is positive and finite
///
/// # Parameters
///
/// - `epsilon` - The epsilon value to validate
///
/// # Errors
///
/// Returns `Error::InvalidParameter` if epsilon is not positive or not finite
pub(super) fn validate_epsilon(epsilon: f32) -> Result<(), Error> {
    if !(epsilon > 0.0 && epsilon.is_finite()) {
        return Err(Error::invalid_parameter(
            "epsilon",
            format!("must be positive and finite, got {}", epsilon),
        ));
    }
    Ok(())
}

/// Validates that a value is positive and finite
///
/// # Parameters
///
/// - `value` - The value to validate
/// - `param_name` - The name of the parameter (for error messages)
///
/// # Errors
///
/// Returns `Error::InvalidParameter` if the value is not positive or not finite
pub(super) fn validate_positive_finite(value: f32, param_name: &str) -> Result<(), Error> {
    if !(value > 0.0 && value.is_finite()) {
        return Err(Error::invalid_parameter(
            param_name.to_string(),
            format!("must be positive and finite, got {}", value),
        ));
    }
    Ok(())
}

/// Validates that a value is non-negative and finite (for example `momentum` or `weight_decay`,
/// where 0 disables the feature)
///
/// # Parameters
///
/// - `value` - The value to validate
/// - `param_name` - The name of the parameter (for error messages)
///
/// # Errors
///
/// Returns `Error::InvalidParameter` if the value is negative or not finite
pub(super) fn validate_non_negative_finite(value: f32, param_name: &str) -> Result<(), Error> {
    if !(value >= 0.0 && value.is_finite()) {
        return Err(Error::invalid_parameter(
            param_name.to_string(),
            format!("must be non-negative and finite, got {}", value),
        ));
    }
    Ok(())
}

/// Validates an optional clip-by-global-norm threshold
///
/// `None` disables clipping and is always valid. A `Some` value must be positive and finite
///
/// # Errors
///
/// Returns `Error::InvalidParameter` if `global_clipnorm` is `Some` and the value is not positive
/// and finite
pub(super) fn validate_global_clipnorm(global_clipnorm: Option<f32>) -> Result<(), Error> {
    if let Some(max_norm) = global_clipnorm {
        validate_positive_finite(max_norm, "global_clipnorm")?;
    }
    Ok(())
}