use pounce_linalg::Vector;
use std::rc::Rc;
#[derive(Clone)]
pub struct IteratesVector {
pub x: Rc<dyn Vector>,
pub s: Rc<dyn Vector>,
pub y_c: Rc<dyn Vector>,
pub y_d: Rc<dyn Vector>,
pub z_l: Rc<dyn Vector>,
pub z_u: Rc<dyn Vector>,
pub v_l: Rc<dyn Vector>,
pub v_u: Rc<dyn Vector>,
}
impl std::fmt::Debug for IteratesVector {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("IteratesVector")
.field("x_dim", &self.x.dim())
.field("s_dim", &self.s.dim())
.field("y_c_dim", &self.y_c.dim())
.field("y_d_dim", &self.y_d.dim())
.field("z_l_dim", &self.z_l.dim())
.field("z_u_dim", &self.z_u.dim())
.field("v_l_dim", &self.v_l.dim())
.field("v_u_dim", &self.v_u.dim())
.finish()
}
}
impl IteratesVector {
#[allow(clippy::too_many_arguments)]
pub fn new(
x: Rc<dyn Vector>,
s: Rc<dyn Vector>,
y_c: Rc<dyn Vector>,
y_d: Rc<dyn Vector>,
z_l: Rc<dyn Vector>,
z_u: Rc<dyn Vector>,
v_l: Rc<dyn Vector>,
v_u: Rc<dyn Vector>,
) -> Self {
Self {
x,
s,
y_c,
y_d,
z_l,
z_u,
v_l,
v_u,
}
}
pub fn dim(&self) -> i32 {
self.x.dim()
+ self.s.dim()
+ self.y_c.dim()
+ self.y_d.dim()
+ self.z_l.dim()
+ self.z_u.dim()
+ self.v_l.dim()
+ self.v_u.dim()
}
pub fn amax(&self) -> pounce_common::types::Number {
let mut m = self.x.amax();
for v in [
&self.s, &self.y_c, &self.y_d, &self.z_l, &self.z_u, &self.v_l, &self.v_u,
] {
let a = v.amax();
if a > m {
m = a;
}
}
m
}
pub fn make_new_zeroed(&self) -> IteratesVectorMut {
IteratesVectorMut {
x: self.x.make_new(),
s: self.s.make_new(),
y_c: self.y_c.make_new(),
y_d: self.y_d.make_new(),
z_l: self.z_l.make_new(),
z_u: self.z_u.make_new(),
v_l: self.v_l.make_new(),
v_u: self.v_u.make_new(),
}
}
pub fn deep_copy(&self) -> IteratesVectorMut {
let mut out = self.make_new_zeroed();
out.x.copy(&*self.x);
out.s.copy(&*self.s);
out.y_c.copy(&*self.y_c);
out.y_d.copy(&*self.y_d);
out.z_l.copy(&*self.z_l);
out.z_u.copy(&*self.z_u);
out.v_l.copy(&*self.v_l);
out.v_u.copy(&*self.v_u);
out
}
}
pub struct IteratesVectorMut {
pub x: Box<dyn Vector>,
pub s: Box<dyn Vector>,
pub y_c: Box<dyn Vector>,
pub y_d: Box<dyn Vector>,
pub z_l: Box<dyn Vector>,
pub z_u: Box<dyn Vector>,
pub v_l: Box<dyn Vector>,
pub v_u: Box<dyn Vector>,
}
impl IteratesVectorMut {
pub fn freeze(self) -> IteratesVector {
IteratesVector::new(
Rc::from(self.x),
Rc::from(self.s),
Rc::from(self.y_c),
Rc::from(self.y_d),
Rc::from(self.z_l),
Rc::from(self.z_u),
Rc::from(self.v_l),
Rc::from(self.v_u),
)
}
pub fn amax(&self) -> pounce_common::types::Number {
let mut m = self.x.amax();
for v in [
&self.s, &self.y_c, &self.y_d, &self.z_l, &self.z_u, &self.v_l, &self.v_u,
] {
let a = v.amax();
if a > m {
m = a;
}
}
m
}
pub fn scal(&mut self, alpha: pounce_common::types::Number) {
self.x.scal(alpha);
self.s.scal(alpha);
self.y_c.scal(alpha);
self.y_d.scal(alpha);
self.z_l.scal(alpha);
self.z_u.scal(alpha);
self.v_l.scal(alpha);
self.v_u.scal(alpha);
}
pub fn axpy(&mut self, alpha: pounce_common::types::Number, other: &IteratesVector) {
self.x.axpy(alpha, &*other.x);
self.s.axpy(alpha, &*other.s);
self.y_c.axpy(alpha, &*other.y_c);
self.y_d.axpy(alpha, &*other.y_d);
self.z_l.axpy(alpha, &*other.z_l);
self.z_u.axpy(alpha, &*other.z_u);
self.v_l.axpy(alpha, &*other.v_l);
self.v_u.axpy(alpha, &*other.v_u);
}
pub fn add_one_vector(
&mut self,
a: pounce_common::types::Number,
other: &IteratesVector,
b: pounce_common::types::Number,
) {
self.x.add_one_vector(a, &*other.x, b);
self.s.add_one_vector(a, &*other.s, b);
self.y_c.add_one_vector(a, &*other.y_c, b);
self.y_d.add_one_vector(a, &*other.y_d, b);
self.z_l.add_one_vector(a, &*other.z_l, b);
self.z_u.add_one_vector(a, &*other.z_u, b);
self.v_l.add_one_vector(a, &*other.v_l, b);
self.v_u.add_one_vector(a, &*other.v_u, b);
}
}
#[cfg(test)]
mod tests {
use super::*;
use pounce_linalg::dense_vector::DenseVectorSpace;
fn zero_vec(n: i32) -> Rc<dyn Vector> {
let space = DenseVectorSpace::new(n);
Rc::new(space.make_new_dense())
}
#[test]
fn iterates_vector_dim_sums_components() {
let iv = IteratesVector::new(
zero_vec(4),
zero_vec(1),
zero_vec(1),
zero_vec(1),
zero_vec(4),
zero_vec(4),
zero_vec(1),
zero_vec(1),
);
assert_eq!(iv.dim(), 4 + 1 + 1 + 1 + 4 + 4 + 1 + 1);
}
}