1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
use crate::dual::dual_problem::DualPhase2;
use crate::error::EllPError;
use crate::problem::Constraint;
use crate::standard_form::{BasicPoint, Point, StandardForm};

pub type EllPResult = Result<SolverResult, EllPError>;

#[derive(Debug)]
pub enum SolverResult {
    Optimal(Solution),
    Infeasible,
    Unbounded,
    MaxIter { obj: f64 },
}

#[derive(Debug)]
pub enum SolutionStatus {
    Optimal,
    Infeasible,
    Unbounded,
    MaxIter,
}

#[derive(Debug)]
pub struct Solution {
    std_form: StandardForm,
    point: OptimalPoint,
}

impl Solution {
    pub fn new(std_form: StandardForm, point: OptimalPoint) -> Self {
        Self { std_form, point }
    }

    #[inline]
    pub fn obj(&self) -> f64 {
        self.std_form.obj(&self.point.x)
    }

    pub fn x(&self) -> nalgebra::DVectorSlice<f64> {
        self.std_form.extract_solution(&self.point)
    }

    pub fn add_constraint(self, _constraint: Constraint) -> DualPhase2 {
        todo!()
    }
}

#[derive(Debug)]
pub struct OptimalPoint(Point);

impl OptimalPoint {
    pub fn new(point: Point) -> Self {
        Self(point)
    }
}

impl BasicPoint for OptimalPoint {
    #[inline]
    fn into_pt(self) -> Point {
        self.0
    }
}

impl std::ops::Deref for OptimalPoint {
    type Target = Point;

    #[inline]
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl std::ops::DerefMut for OptimalPoint {
    #[inline]
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}