use std::{
fmt::Debug,
ops::{Div, Mul, Sub},
};
use derive_more::Display;
use derive_num_bounded::{
derive_into_inner, derive_new_from_bounded_partial_ord,
derive_new_from_lower_bounded_partial_ord,
};
use num_traits::{
bounds::{LowerBounded, UpperBounded},
real::Real,
AsPrimitive, One,
};
pub use optimal_core::prelude::*;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, Debug, Display, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
pub struct SufficientDecreaseParameter<A>(A);
derive_new_from_bounded_partial_ord!(SufficientDecreaseParameter<A: Real>);
derive_into_inner!(SufficientDecreaseParameter<A>);
impl<A> Default for SufficientDecreaseParameter<A>
where
A: 'static + Copy,
f64: AsPrimitive<A>,
{
fn default() -> Self {
Self(0.5.as_())
}
}
impl<A> LowerBounded for SufficientDecreaseParameter<A>
where
A: Real,
{
fn min_value() -> Self {
Self(A::epsilon())
}
}
impl<A> UpperBounded for SufficientDecreaseParameter<A>
where
A: Real,
{
fn max_value() -> Self {
Self(A::one() - A::epsilon())
}
}
#[derive(Clone, Copy, Debug, Display, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
pub struct BacktrackingRate<A>(A);
derive_new_from_bounded_partial_ord!(BacktrackingRate<A: Real>);
derive_into_inner!(BacktrackingRate<A>);
impl<A> Default for BacktrackingRate<A>
where
A: 'static + Copy,
f64: AsPrimitive<A>,
{
fn default() -> Self {
Self(0.5.as_())
}
}
impl<A> LowerBounded for BacktrackingRate<A>
where
A: Real,
{
fn min_value() -> Self {
Self(A::epsilon())
}
}
impl<A> UpperBounded for BacktrackingRate<A>
where
A: Real,
{
fn max_value() -> Self {
Self(A::one() - A::epsilon())
}
}
#[derive(Clone, Copy, Debug, Display, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
pub struct IncrRate<A>(A);
derive_new_from_lower_bounded_partial_ord!(IncrRate<A: Real>);
derive_into_inner!(IncrRate<A>);
impl<A> IncrRate<A>
where
A: 'static + Copy + One + Sub<Output = A> + Div<Output = A>,
f64: AsPrimitive<A>,
{
pub fn from_backtracking_rate(x: BacktrackingRate<A>) -> IncrRate<A> {
Self(2.0.as_() / x.into_inner() - A::one())
}
}
impl<A> LowerBounded for IncrRate<A>
where
A: Real,
{
fn min_value() -> Self {
Self(A::one() + A::epsilon())
}
}
impl<A> Mul<A> for IncrRate<A>
where
A: Mul<Output = A>,
{
type Output = A;
fn mul(self, rhs: A) -> Self::Output {
self.0 * rhs
}
}