use super::Constraint;
#[derive(Copy, Clone)]
pub struct BallInf<'a> {
center: Option<&'a [f64]>,
radius: f64,
}
impl<'a> BallInf<'a> {
pub fn new(center: Option<&'a [f64]>, radius: f64) -> Self {
assert!(radius > 0.0);
BallInf { center, radius }
}
}
impl<'a> Constraint for BallInf<'a> {
fn project(&self, x: &mut [f64]) {
if let Some(center) = &self.center {
x.iter_mut()
.zip(center.iter())
.filter(|(&mut xi, &ci)| (xi - ci).abs() > self.radius)
.for_each(|(xi, ci)| *xi = ci + (*xi - ci).signum() * self.radius);
} else {
x.iter_mut()
.filter(|xi| xi.abs() > self.radius)
.for_each(|xi| *xi = xi.signum() * self.radius);
}
}
fn is_convex(&self) -> bool {
true
}
}