pounce_algorithm/eq_mult/
least_square.rs1use crate::eq_mult::r#trait::EqMultCalculator;
20use crate::ipopt_cq::IpoptCqHandle;
21use crate::ipopt_data::IpoptDataHandle;
22use crate::ipopt_nlp::IpoptNlp;
23use crate::kkt::aug_system_solver::{AugSysCoeffs, AugSysRhs, AugSysSol, AugSystemSolver};
24use pounce_linalg::Vector;
25use pounce_linsol::ESymSolverStatus;
26use std::cell::RefCell;
27use std::rc::Rc;
28
29pub struct LeastSquareMults;
30
31impl LeastSquareMults {
32 pub fn new() -> Self {
33 Self
34 }
35}
36
37impl Default for LeastSquareMults {
38 fn default() -> Self {
39 Self::new()
40 }
41}
42
43impl EqMultCalculator for LeastSquareMults {
44 fn calculate_y_eq(
45 &mut self,
46 data: &IpoptDataHandle,
47 cq: &IpoptCqHandle,
48 nlp: &Rc<RefCell<dyn IpoptNlp>>,
49 aug_solver: &mut dyn AugSystemSolver,
50 y_c: &mut dyn Vector,
51 y_d: &mut dyn Vector,
52 ) -> bool {
53 let curr = match data.borrow().curr.clone() {
54 Some(c) => c,
55 None => return false,
56 };
57
58 let cq_ref = cq.borrow();
62 let grad_f = cq_ref.curr_grad_f();
63 let j_c = cq_ref.curr_jac_c();
64 let j_d = cq_ref.curr_jac_d();
65 let zero_w = cq_ref.curr_exact_hessian();
71 drop(cq_ref);
72
73 let nlp_ref = nlp.borrow();
74
75 let mut rhs_x = grad_f.make_new();
78 rhs_x.copy(&*grad_f);
79 nlp_ref
80 .px_l()
81 .mult_vector(1.0, &*curr.z_l, -1.0, &mut *rhs_x);
82 nlp_ref
83 .px_u()
84 .mult_vector(-1.0, &*curr.z_u, 1.0, &mut *rhs_x);
85
86 let mut rhs_s = curr.s.make_new();
89 nlp_ref
90 .pd_l()
91 .mult_vector(1.0, &*curr.v_l, 0.0, &mut *rhs_s);
92 nlp_ref
93 .pd_u()
94 .mult_vector(-1.0, &*curr.v_u, 1.0, &mut *rhs_s);
95
96 let mut rhs_c = curr.y_c.make_new();
98 rhs_c.set(0.0);
99 let mut rhs_d = curr.y_d.make_new();
100 rhs_d.set(0.0);
101
102 let mut sol_x = rhs_x.make_new();
104 let mut sol_s = rhs_s.make_new();
105
106 let coeffs = AugSysCoeffs {
107 w: Some(&*zero_w),
108 w_factor: 0.0,
109 d_x: None,
110 delta_x: 1.0,
111 d_s: None,
112 delta_s: 1.0,
113 j_c: &*j_c,
114 d_c: None,
115 delta_c: 0.0,
116 j_d: &*j_d,
117 d_d: None,
118 delta_d: 0.0,
119 };
120 let aug_rhs = AugSysRhs {
121 rhs_x: &*rhs_x,
122 rhs_s: &*rhs_s,
123 rhs_c: &*rhs_c,
124 rhs_d: &*rhs_d,
125 };
126 let mut sol = AugSysSol {
127 sol_x: &mut *sol_x,
128 sol_s: &mut *sol_s,
129 sol_c: y_c,
130 sol_d: y_d,
131 };
132
133 let num_eq = aug_rhs.rhs_c.dim() + aug_rhs.rhs_d.dim();
134 let check_neg = aug_solver.provides_inertia();
135 let status = aug_solver.solve(&coeffs, &aug_rhs, &mut sol, check_neg, num_eq);
136 matches!(status, ESymSolverStatus::Success)
137 }
138}