use crate::error::QpError;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BoundStatus {
Inactive,
AtLower,
AtUpper,
Fixed,
}
impl BoundStatus {
pub fn is_active(self) -> bool {
!matches!(self, BoundStatus::Inactive)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ConsStatus {
Inactive,
AtLower,
AtUpper,
Equality,
}
impl ConsStatus {
pub fn is_active(self) -> bool {
!matches!(self, ConsStatus::Inactive)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct WorkingSet {
pub bounds: Vec<BoundStatus>,
pub constraints: Vec<ConsStatus>,
}
impl WorkingSet {
pub fn cold(n: usize, m: usize) -> Self {
Self {
bounds: vec![BoundStatus::Inactive; n],
constraints: vec![ConsStatus::Inactive; m],
}
}
pub fn n(&self) -> usize {
self.bounds.len()
}
pub fn m(&self) -> usize {
self.constraints.len()
}
pub fn active_count(&self) -> usize {
self.bounds.iter().filter(|s| s.is_active()).count()
+ self.constraints.iter().filter(|s| s.is_active()).count()
}
pub fn validate_dims(&self, n: usize, m: usize) -> Result<(), QpError> {
if self.bounds.len() != n {
return Err(QpError::WarmStartDimensionMismatch(format!(
"bounds.len() = {} but problem n = {n}",
self.bounds.len()
)));
}
if self.constraints.len() != m {
return Err(QpError::WarmStartDimensionMismatch(format!(
"constraints.len() = {} but problem m = {m}",
self.constraints.len()
)));
}
Ok(())
}
}