use scirs2_core::ndarray::{Array, Dimension, ScalarOperand};
use scirs2_core::numeric::{Float, ToPrimitive};
use std::fmt::Debug;
use crate::error::{OptimError, Result};
pub(crate) fn cast_scalar<A: Float, T: ToPrimitive>(value: T) -> Result<A> {
A::from(value).ok_or_else(|| {
OptimError::InvalidConfig(
"failed to convert a numeric value to the optimizer's scalar type".to_string(),
)
})
}
pub(crate) fn scalar_to_f64<A: Float>(value: A) -> Result<f64> {
value.to_f64().ok_or_else(|| {
OptimError::InvalidConfig(
"failed to convert the optimizer's scalar type to f64".to_string(),
)
})
}
pub trait Optimizer<A, D>
where
A: Float + ScalarOperand + Debug,
D: Dimension,
{
fn step(&mut self, params: &Array<A, D>, gradients: &Array<A, D>) -> Result<Array<A, D>>;
fn get_learning_rate(&self) -> A;
fn set_learning_rate(&mut self, learning_rate: A);
fn step_list(
&mut self,
params_list: &[&Array<A, D>],
gradients_list: &[&Array<A, D>],
) -> Result<Vec<Array<A, D>>> {
if params_list.len() != gradients_list.len() {
return Err(OptimError::InvalidConfig(format!(
"Number of parameter arrays ({}) does not match number of gradient arrays ({})",
params_list.len(),
gradients_list.len()
)));
}
let mut results = Vec::with_capacity(params_list.len());
for (params, grads) in params_list.iter().zip(gradients_list.iter()) {
results.push(self.step(params, grads)?);
}
Ok(results)
}
}
mod adabound;
mod adadelta;
mod adagrad;
mod adam;
mod adamw;
mod grouped_adam;
mod lamb;
mod lars;
mod lbfgs;
mod lion;
mod lookahead;
mod maml;
mod meta_sgd;
mod ntm_optimizer;
mod radam;
mod ranger;
mod reptile;
mod rmsprop;
mod sam;
mod sgd;
mod sgd_simd;
mod sparse_adam;
pub use adabound::AdaBound;
pub use adadelta::AdaDelta;
pub use adagrad::Adagrad;
pub use adam::Adam;
pub use adamw::AdamW;
pub use grouped_adam::GroupedAdam;
pub use lamb::LAMB;
pub use lars::LARS;
pub use lbfgs::LBFGS;
pub use lion::Lion;
pub use lookahead::Lookahead;
pub use maml::{MAMLVariant, TaskBatch, MAML};
pub use meta_sgd::MetaSGD;
pub use ntm_optimizer::{AddressingMode, NtmConfig, NtmOptimizer};
pub use radam::RAdam;
pub use ranger::Ranger;
pub use reptile::ReptileOptimizer;
pub use rmsprop::RMSprop;
pub use sam::SAM;
pub use sgd::SGD;
pub use sgd_simd::SimdSGD;
pub use sparse_adam::{SparseAdam, SparseGradient};