1use pounce_linalg::Vector;
24use std::rc::Rc;
25
26#[derive(Clone)]
28pub struct IteratesVector {
29 pub x: Rc<dyn Vector>,
30 pub s: Rc<dyn Vector>,
31 pub y_c: Rc<dyn Vector>,
32 pub y_d: Rc<dyn Vector>,
33 pub z_l: Rc<dyn Vector>,
34 pub z_u: Rc<dyn Vector>,
35 pub v_l: Rc<dyn Vector>,
36 pub v_u: Rc<dyn Vector>,
37}
38
39impl std::fmt::Debug for IteratesVector {
40 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41 f.debug_struct("IteratesVector")
42 .field("x_dim", &self.x.dim())
43 .field("s_dim", &self.s.dim())
44 .field("y_c_dim", &self.y_c.dim())
45 .field("y_d_dim", &self.y_d.dim())
46 .field("z_l_dim", &self.z_l.dim())
47 .field("z_u_dim", &self.z_u.dim())
48 .field("v_l_dim", &self.v_l.dim())
49 .field("v_u_dim", &self.v_u.dim())
50 .finish()
51 }
52}
53
54impl IteratesVector {
55 #[allow(clippy::too_many_arguments)]
57 pub fn new(
58 x: Rc<dyn Vector>,
59 s: Rc<dyn Vector>,
60 y_c: Rc<dyn Vector>,
61 y_d: Rc<dyn Vector>,
62 z_l: Rc<dyn Vector>,
63 z_u: Rc<dyn Vector>,
64 v_l: Rc<dyn Vector>,
65 v_u: Rc<dyn Vector>,
66 ) -> Self {
67 Self {
68 x,
69 s,
70 y_c,
71 y_d,
72 z_l,
73 z_u,
74 v_l,
75 v_u,
76 }
77 }
78
79 pub fn with_x(&self, x: Rc<dyn Vector>) -> Self {
84 Self { x, ..self.clone() }
85 }
86
87 pub fn dim(&self) -> i32 {
89 self.x.dim()
90 + self.s.dim()
91 + self.y_c.dim()
92 + self.y_d.dim()
93 + self.z_l.dim()
94 + self.z_u.dim()
95 + self.v_l.dim()
96 + self.v_u.dim()
97 }
98
99 pub fn amax(&self) -> pounce_common::types::Number {
103 let mut m = self.x.amax();
104 for v in [
105 &self.s, &self.y_c, &self.y_d, &self.z_l, &self.z_u, &self.v_l, &self.v_u,
106 ] {
107 let a = v.amax();
108 if a > m {
109 m = a;
110 }
111 }
112 m
113 }
114
115 pub fn make_new_zeroed(&self) -> IteratesVectorMut {
118 IteratesVectorMut {
119 x: self.x.make_new(),
120 s: self.s.make_new(),
121 y_c: self.y_c.make_new(),
122 y_d: self.y_d.make_new(),
123 z_l: self.z_l.make_new(),
124 z_u: self.z_u.make_new(),
125 v_l: self.v_l.make_new(),
126 v_u: self.v_u.make_new(),
127 }
128 }
129
130 pub fn deep_copy(&self) -> IteratesVectorMut {
132 let mut out = self.make_new_zeroed();
133 out.x.copy(&*self.x);
134 out.s.copy(&*self.s);
135 out.y_c.copy(&*self.y_c);
136 out.y_d.copy(&*self.y_d);
137 out.z_l.copy(&*self.z_l);
138 out.z_u.copy(&*self.z_u);
139 out.v_l.copy(&*self.v_l);
140 out.v_u.copy(&*self.v_u);
141 out
142 }
143}
144
145pub struct IteratesVectorMut {
149 pub x: Box<dyn Vector>,
150 pub s: Box<dyn Vector>,
151 pub y_c: Box<dyn Vector>,
152 pub y_d: Box<dyn Vector>,
153 pub z_l: Box<dyn Vector>,
154 pub z_u: Box<dyn Vector>,
155 pub v_l: Box<dyn Vector>,
156 pub v_u: Box<dyn Vector>,
157}
158
159impl IteratesVectorMut {
160 pub fn freeze(self) -> IteratesVector {
162 IteratesVector::new(
163 Rc::from(self.x),
164 Rc::from(self.s),
165 Rc::from(self.y_c),
166 Rc::from(self.y_d),
167 Rc::from(self.z_l),
168 Rc::from(self.z_u),
169 Rc::from(self.v_l),
170 Rc::from(self.v_u),
171 )
172 }
173
174 pub fn amax(&self) -> pounce_common::types::Number {
175 let mut m = self.x.amax();
176 for v in [
177 &self.s, &self.y_c, &self.y_d, &self.z_l, &self.z_u, &self.v_l, &self.v_u,
178 ] {
179 let a = v.amax();
180 if a > m {
181 m = a;
182 }
183 }
184 m
185 }
186
187 pub fn scal(&mut self, alpha: pounce_common::types::Number) {
189 self.x.scal(alpha);
190 self.s.scal(alpha);
191 self.y_c.scal(alpha);
192 self.y_d.scal(alpha);
193 self.z_l.scal(alpha);
194 self.z_u.scal(alpha);
195 self.v_l.scal(alpha);
196 self.v_u.scal(alpha);
197 }
198
199 pub fn axpy(&mut self, alpha: pounce_common::types::Number, other: &IteratesVector) {
201 self.x.axpy(alpha, &*other.x);
202 self.s.axpy(alpha, &*other.s);
203 self.y_c.axpy(alpha, &*other.y_c);
204 self.y_d.axpy(alpha, &*other.y_d);
205 self.z_l.axpy(alpha, &*other.z_l);
206 self.z_u.axpy(alpha, &*other.z_u);
207 self.v_l.axpy(alpha, &*other.v_l);
208 self.v_u.axpy(alpha, &*other.v_u);
209 }
210
211 pub fn add_one_vector(
214 &mut self,
215 a: pounce_common::types::Number,
216 other: &IteratesVector,
217 b: pounce_common::types::Number,
218 ) {
219 self.x.add_one_vector(a, &*other.x, b);
220 self.s.add_one_vector(a, &*other.s, b);
221 self.y_c.add_one_vector(a, &*other.y_c, b);
222 self.y_d.add_one_vector(a, &*other.y_d, b);
223 self.z_l.add_one_vector(a, &*other.z_l, b);
224 self.z_u.add_one_vector(a, &*other.z_u, b);
225 self.v_l.add_one_vector(a, &*other.v_l, b);
226 self.v_u.add_one_vector(a, &*other.v_u, b);
227 }
228}
229
230#[cfg(test)]
231mod tests {
232 use super::*;
233 use pounce_linalg::dense_vector::DenseVectorSpace;
234
235 fn zero_vec(n: i32) -> Rc<dyn Vector> {
236 let space = DenseVectorSpace::new(n);
237 Rc::new(space.make_new_dense())
238 }
239
240 #[test]
241 fn iterates_vector_dim_sums_components() {
242 let iv = IteratesVector::new(
243 zero_vec(4),
244 zero_vec(1),
245 zero_vec(1),
246 zero_vec(1),
247 zero_vec(4),
248 zero_vec(4),
249 zero_vec(1),
250 zero_vec(1),
251 );
252 assert_eq!(iv.dim(), 4 + 1 + 1 + 1 + 4 + 4 + 1 + 1);
253 }
254}