use crate::bspline::BSpline;
use scirs2_core::numeric::{Float, FromPrimitive};
use std::fmt::{Debug, Display};
use std::ops::{Add, Div, Mul, Sub};
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum ConstraintType {
MonotoneIncreasing,
MonotoneDecreasing,
Convex,
Concave,
Positive,
UpperBound,
LowerBound,
}
#[derive(Debug, Clone)]
pub struct Constraint<T: Float + FromPrimitive + Debug + Display> {
pub(crate) constraint_type: ConstraintType,
pub(crate) x_min: Option<T>,
pub(crate) x_max: Option<T>,
pub(crate) parameter: Option<T>,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum ConstraintRegion {
Global,
Interval { start: f64, end: f64 },
Points(usize),
}
impl<T: Float + FromPrimitive + Debug + Display> Constraint<T> {
pub fn monotone_increasing(x_min: Option<T>, x_max: Option<T>) -> Self {
Constraint {
constraint_type: ConstraintType::MonotoneIncreasing,
x_min,
x_max,
parameter: None,
}
}
pub fn monotone_decreasing(x_min: Option<T>, x_max: Option<T>) -> Self {
Constraint {
constraint_type: ConstraintType::MonotoneDecreasing,
x_min,
x_max,
parameter: None,
}
}
pub fn convex(x_min: Option<T>, x_max: Option<T>) -> Self {
Constraint {
constraint_type: ConstraintType::Convex,
x_min,
x_max,
parameter: None,
}
}
pub fn concave(x_min: Option<T>, x_max: Option<T>) -> Self {
Constraint {
constraint_type: ConstraintType::Concave,
x_min,
x_max,
parameter: None,
}
}
pub fn positive(x_min: Option<T>, x_max: Option<T>) -> Self {
Constraint {
constraint_type: ConstraintType::Positive,
x_min,
x_max,
parameter: None,
}
}
pub fn upper_bound(x_min: Option<T>, x_max: Option<T>, upperbound: T) -> Self {
Constraint {
constraint_type: ConstraintType::UpperBound,
x_min,
x_max,
parameter: Some(upperbound),
}
}
pub fn lower_bound(x_min: Option<T>, x_max: Option<T>, lowerbound: T) -> Self {
Constraint {
constraint_type: ConstraintType::LowerBound,
x_min,
x_max,
parameter: Some(lowerbound),
}
}
}
#[derive(Debug, Clone)]
pub struct ConstrainedSpline<T>
where
T: Float
+ FromPrimitive
+ Debug
+ Display
+ Add<Output = T>
+ Sub<Output = T>
+ Mul<Output = T>
+ Div<Output = T>
+ std::ops::AddAssign
+ std::ops::SubAssign
+ std::ops::MulAssign
+ std::ops::DivAssign
+ std::ops::RemAssign
+ 'static,
{
pub(crate) bspline: BSpline<T>,
pub(crate) constraints: Vec<Constraint<T>>,
pub(crate) method: super::builder::FittingMethod,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum BoundaryCondition {
None,
FirstDerivative(f64),
SecondDerivative(f64),
Natural,
Periodic,
}