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
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
use crate::{
  dr_matrix::DrMatrixRowsConstructor,
  gp::{GpOrRef, GpOrsRef, NoCstrRslts},
};
use cl_traits::{Length, Push, Storage};
use core::iter::Extend;

pub type MpOrsConstructor<'a, ORS, SS> = GpOrsConstructor<'a, NoCstrRslts, ORS, NoCstrRslts, SS>;
pub type MphOrsConstructor<'a, HCRS, ORS, SS> = GpOrsConstructor<'a, HCRS, ORS, NoCstrRslts, SS>;
pub type MphsOrsConstructor<'a, HCRS, ORS, SCRS, SS> = GpOrsConstructor<'a, HCRS, ORS, SCRS, SS>;
pub type SpOrsConstructor<'a, ORS, SS> = GpOrsConstructor<'a, NoCstrRslts, ORS, NoCstrRslts, SS>;

/// Constructor for MPH-OR
///
/// # Types
///
/// * `ORS`: Objective Results Storage
/// * `S`: Solution
#[derive(Debug, PartialEq)]
pub struct GpOrsConstructor<'a, HCRS, ORS, SCRS, SS> {
  pub(crate) hard_cstr_rslts: DrMatrixRowsConstructor<'a, HCRS>,
  pub(crate) obj_rslts: DrMatrixRowsConstructor<'a, ORS>,
  pub(crate) soft_cstr_rslts: DrMatrixRowsConstructor<'a, SCRS>,
  pub(crate) solutions: &'a mut SS,
}

impl<'a, HCR, HCRS, OR, ORS, S, SCR, SCRS, SS> GpOrsConstructor<'a, HCRS, ORS, SCRS, SS>
where
  HCR: Clone,
  HCRS: Extend<HCR> + Storage<Item = HCR>,
  OR: Clone,
  ORS: Extend<OR> + Storage<Item = OR>,
  SCR: Clone,
  SCRS: Extend<SCR> + Storage<Item = SCR>,
  SS: Storage<Item = S>,
{
  pub fn or_ref(mut self, from: GpOrRef<'_, HCR, OR, S, SCR>) -> Option<Self>
  where
    S: Clone,
    SS: Push<Input = S>,
  {
    self.hard_cstr_rslts = self.hard_cstr_rslts.row_slice(from.hard_cstr_rslts)?;
    self.obj_rslts = self.obj_rslts.row_slice(from.obj_rslts)?;
    self.soft_cstr_rslts = self.soft_cstr_rslts.row_slice(from.soft_cstr_rslts)?;
    self.solutions.push(from.solution.clone());
    Some(self)
  }

  pub fn ors_ref(mut self, other: GpOrsRef<'_, HCR, OR, S, SCR>) -> Option<Self>
  where
    S: Clone,
    SS: Extend<S>,
  {
    self.hard_cstr_rslts = self.hard_cstr_rslts.matrix_ref(other.hard_cstr_rslts)?;
    self.obj_rslts = self.obj_rslts.matrix_ref(other.obj_rslts)?;
    self.soft_cstr_rslts = self.soft_cstr_rslts.matrix_ref(other.soft_cstr_rslts)?;
    self.solutions.extend(other.solutions.iter().cloned());
    Some(self)
  }

  pub fn ors_s_iter<E, SI>(mut self, si: SI) -> Option<Self>
  where
    HCR: Default,
    OR: Default,
    SCR: Default,
    SI: Iterator<Item = Result<S, E>>,
    SS: Push<Input = S>,
  {
    for solution in si {
      self.hard_cstr_rslts = self.hard_cstr_rslts.fill_row(HCR::default());
      self.obj_rslts = self.obj_rslts.fill_row(OR::default());
      self.soft_cstr_rslts = self.soft_cstr_rslts.fill_row(SCR::default());
      self.solutions.push(solution.ok()?);
    }
    Some(self)
  }
}

impl<'a, HCR, HCRS, OR, ORS, S, SCR, SCRS, SS> GpOrsConstructor<'a, HCRS, ORS, SCRS, SS>
where
  OR: Default,
  ORS: Extend<OR> + Length<Output = usize> + Storage<Item = OR>,
  SS: Push<Input = S> + Storage<Item = S>,
  HCR: Default,
  HCRS: Extend<HCR> + Length<Output = usize> + Storage<Item = HCR>,
  SCR: Default,
  SCRS: Extend<SCR> + Length<Output = usize> + Storage<Item = SCR>,
{
  pub fn or_hcos_iter<HCRI, ORI>(self, hcri: HCRI, ori: ORI, solution: S) -> Self
  where
    HCRI: Iterator<Item = HCR>,
    ORI: Iterator<Item = OR>,
  {
    let scri = (0..self.soft_cstr_rslts.cols).map(|_| Default::default());
    self.or_hcossc_iter(hcri, ori, solution, scri)
  }

  pub fn or_hcossc_iter<HCRI, ORI, SCRI>(mut self, hcri: HCRI, ori: ORI, s: S, scri: SCRI) -> Self
  where
    HCRI: Iterator<Item = HCR>,
    ORI: Iterator<Item = OR>,
    SCRI: Iterator<Item = SCR>,
  {
    self.hard_cstr_rslts = self.hard_cstr_rslts.row_iter(hcri);
    self.obj_rslts = self.obj_rslts.row_iter(ori);
    self.soft_cstr_rslts = self.soft_cstr_rslts.row_iter(scri);
    self.solutions.push(s);
    self
  }

  pub fn or_os_iter<ORI>(self, ori: ORI, solution: S) -> Self
  where
    ORI: Iterator<Item = OR>,
  {
    let hcri = (0..self.hard_cstr_rslts.cols).map(|_| Default::default());
    let scri = (0..self.soft_cstr_rslts.cols).map(|_| Default::default());
    self.or_hcossc_iter(hcri, ori, solution, scri)
  }
}