optimization_engine/constraints/
ball2.rs1use super::Constraint;
2
3#[derive(Copy, Clone)]
4pub struct Ball2<'a> {
7 center: Option<&'a [f64]>,
8 radius: f64,
9}
10
11impl<'a> Ball2<'a> {
12 pub fn new(center: Option<&'a [f64]>, radius: f64) -> Self {
15 assert!(radius > 0.0);
16
17 Ball2 { center, radius }
18 }
19}
20
21impl<'a> Constraint for Ball2<'a> {
22 fn project(&self, x: &mut [f64]) {
23 if let Some(center) = &self.center {
24 assert_eq!(
25 x.len(),
26 center.len(),
27 "x and xc have incompatible dimensions"
28 );
29 let mut norm_difference = 0.0;
30 x.iter().zip(center.iter()).for_each(|(a, b)| {
31 let diff_ = *a - *b;
32 norm_difference += diff_ * diff_
33 });
34
35 norm_difference = norm_difference.sqrt();
36
37 if norm_difference > self.radius {
38 x.iter_mut().zip(center.iter()).for_each(|(x, c)| {
39 *x = *c + self.radius * (*x - *c) / norm_difference;
40 });
41 }
42 } else {
43 let norm_x = crate::matrix_operations::norm2(x);
44 if norm_x > self.radius {
45 let norm_over_radius = norm_x / self.radius;
46 x.iter_mut().for_each(|x_| *x_ /= norm_over_radius);
47 }
48 }
49 }
50
51 fn is_convex(&self) -> bool {
52 true
53 }
54}