Thanks to visit codestin.com
Credit goes to docs.rs

optimization_engine/constraints/
hyperplane.rs

1use super::Constraint;
2use crate::matrix_operations;
3
4#[derive(Clone)]
5/// A hyperplane is a set given by $H = \\{x \in \mathbb{R}^n {}:{} \langle c, x\rangle = b\\}$.
6pub struct Hyperplane<'a> {
7    /// normal vector
8    normal_vector: &'a [f64],
9    /// offset
10    offset: f64,
11    /// squared Euclidean norm of the normal vector (computed once upon construction)
12    normal_vector_squared_norm: f64,
13}
14
15impl<'a> Hyperplane<'a> {
16    /// A hyperplane is a set given by $H = \\{x \in \mathbb{R}^n {}:{} \langle c, x\rangle = b\\}$,
17    /// where $c$ is the normal vector of the hyperplane and $b$ is an offset.
18    ///
19    /// This method constructs a new instance of `Hyperplane` with a given normal
20    /// vector and bias
21    ///
22    /// # Arguments
23    ///
24    /// - `normal_vector`: the normal vector, $c$, as a slice
25    /// - `offset`: the offset parameter, $b$
26    ///
27    /// # Returns
28    ///
29    /// New instance of `Hyperplane`
30    ///
31    /// # Panics
32    ///
33    /// Does not panic. Note: it does not panic if you provide an empty slice as `normal_vector`,
34    /// but you should avoid doing that.
35    ///
36    /// # Example
37    ///
38    /// ```
39    /// use optimization_engine::constraints::{Constraint, Hyperplane};
40    ///
41    /// let normal_vector = [1., 2.];
42    /// let offset = 1.0;
43    /// let hyperplane = Hyperplane::new(&normal_vector, offset);
44    /// let mut x = [-1., 3.];
45    /// hyperplane.project(&mut x);
46    /// ```
47    ///
48    pub fn new(normal_vector: &'a [f64], offset: f64) -> Self {
49        let normal_vector_squared_norm = matrix_operations::norm2_squared(normal_vector);
50        Hyperplane {
51            normal_vector,
52            offset,
53            normal_vector_squared_norm,
54        }
55    }
56}
57
58impl<'a> Constraint for Hyperplane<'a> {
59    /// Projects on the hyperplane using the formula:
60    ///
61    /// $$\begin{aligned}
62    /// \mathrm{proj}_{H}(x) =
63    /// x - \frac{\langle c, x\rangle - b}
64    ///          {\\|c\\|}c.
65    /// \end{aligned}$$
66    ///
67    /// where $H = \\{x \in \mathbb{R}^n {}:{} \langle c, x\rangle = b\\}$
68    ///
69    /// # Arguments
70    ///
71    /// - `x`: (in) vector to be projected on the current instance of a hyperplane,
72    ///    (out) projection on the second-order cone
73    ///
74    /// # Panics
75    ///
76    /// This method panics if the length of `x` is not equal to the dimension
77    /// of the hyperplane.
78    ///
79    fn project(&self, x: &mut [f64]) {
80        let inner_product = matrix_operations::inner_product(x, self.normal_vector);
81        let factor = (inner_product - self.offset) / self.normal_vector_squared_norm;
82        x.iter_mut()
83            .zip(self.normal_vector.iter())
84            .for_each(|(x, nrm_vct)| *x -= factor * nrm_vct);
85    }
86
87    /// Hyperplanes are convex sets
88    ///
89    /// # Returns
90    ///
91    /// Returns `true`
92    fn is_convex(&self) -> bool {
93        true
94    }
95}