GeLineq

Struct GeLineq 

Source
pub struct GeLineq {
    pub id: Option<u32>,
    pub coeffs: Vec<i64>,
    pub bounds: Vec<(i64, i64)>,
    pub bias: i64,
    pub indices: Vec<u32>,
}
Expand description

Data structure for linear inequalities on the following form $$ c_0 * v_0 + c_1 * v_1 + … + c_n * v_n + bias \ge 0 $$ for $ c \in $ coeffs and $ v $ are variables which can take on the values given by bounds. Indices represents the global indices of the variables. Note that the length of coeffs, bounds and indices must be the same.

Fields§

§id: Option<u32>

id may be used as a reference for later purposes

§coeffs: Vec<i64>

Coefficients of the linear inequality

§bounds: Vec<(i64, i64)>

Bounds for every variable

§bias: i64

d in a linear inequality $ ax+by+cz+d >= 0 $

§indices: Vec<u32>

Id of each index

Implementations§

Source§

impl GeLineq

Source

pub fn merge_disj(ge_lineq1: &GeLineq, ge_lineq2: &GeLineq) -> Option<GeLineq>

Takes two GeLineqs and merge those into one GeLineq under the condition that one of the GeLineqs must be satisfied. If it’s not possible to merge the inequalities, i.e. it’s impossible to preserve the logic, none is returned.

§Example:

If atleast one of the two linear inequalities $ x + y - 1 \ge 0 $ where $ x, y \in \{0, 1 \}$ and $ a + b - 1 \ge 0 $ where $ a, b \in \{0, 1\}$ must hold, then they can be merged into one linear inequality as $ x + y + a + b - 1 \ge 0$ where $ x, y, a, b \in \{0, 1\}$. Note that the logic is preserved, i.e the merged inequality will be valid if at least one of the two original inequalities are valid. Likewise, the merged constraint will not be valid if none of the original inequalites are.

use puanrs::polyopt::GeLineq;
let ge_lineq1:GeLineq = GeLineq {
   id      : None,
   coeffs  : vec![1, 1],
   bounds  : vec![(0, 1), (0, 1)],
   bias    : -1,
   indices : vec![1, 2]
   };
let ge_lineq2: GeLineq = GeLineq {
   id      : None,
   coeffs  : vec![1, 1],
   bounds  : vec![(0, 1), (0, 1)],
   bias    : -1,
   indices : vec![3, 4]
 };
let expected: GeLineq = GeLineq {
   id      : None,
   coeffs  : vec![1, 1, 1, 1],
   bounds  : vec![(0, 1), (0, 1), (0, 1), (0, 1)],
   bias    : -1,
   indices : vec![1, 2, 3, 4]
 };
let actual = GeLineq::merge_disj(&ge_lineq1, &ge_lineq2);
assert_eq!(actual.as_ref().expect("Not possible to merge lineqs").coeffs, expected.coeffs);
assert_eq!(actual.as_ref().expect("Not possible to merge lineqs").bounds, expected.bounds);
assert_eq!(actual.as_ref().expect("Not possible to merge lineqs").bias, expected.bias);
assert_eq!(actual.as_ref().expect("Not possible to merge lineqs").indices, expected.indices);
Source

pub fn merge_conj(ge_lineq1: &GeLineq, ge_lineq2: &GeLineq) -> Option<GeLineq>

Takes two GeLineqs and merge those into one GeLineq under the condition that both of the GeLineqs must be valid. If it’s not possible to merge the inequalities, i.e. it’s impossible to preserve the logic, none is returned.

Source

pub fn substitution( main_gelineq: &GeLineq, variable_index: u32, sub_gelineq: &GeLineq, ) -> Option<GeLineq>

Takes a GeLineq, referred to as main GeLineq which has a variable (given by variable index) which in turn is a GeLineq, referred to as the sub GeLineq. The function substitutes the variable with the sub GeLineq into the main GeLineq if possible.

§Example

Given the lineq x + Y - 2 >= 0 where Y: a + b - 1 >= 0 a substitution would give 2x + a + b - 3 >= 0. Lets see it in code:

use puanrs::polyopt::GeLineq;
let main_gelineq:GeLineq = GeLineq {
   id      : None,
   coeffs  : vec![1, 1],
   bounds  : vec![(0, 1), (0, 1)],
   bias    : -2,
   indices : vec![1, 2]
};
let sub_gelineq: GeLineq = GeLineq {
   id      : None,
   coeffs  : vec![1, 1],
   bounds  : vec![(0, 1), (0, 1)],
   bias    : -1,
   indices : vec![3, 4]
};
let result = GeLineq::substitution(&main_gelineq, 2, &sub_gelineq);
assert_eq!(vec![2, 1, 1], result.as_ref().expect("No result generated").coeffs);
assert_eq!(vec![(0,1), (0,1), (0,1)], result.as_ref().expect("No result generated").bounds);
assert_eq!(-3, result.as_ref().expect("No result generated").bias);
assert_eq!(vec![1, 3, 4], result.as_ref().expect("No result generated").indices);
Source

pub fn min_max_coefficients(gelineq: &GeLineq) -> Option<GeLineq>

Takes a GeLineq and minimizes/maximizes the coefficients while preserving the logic

§Example

Consider the GeLineq 2x + y + z >= 1 where x, y, z takes values between 0 and 1. This inequlity can be written as x + y + z >= 1 while preserving the logic.

use puanrs::polyopt::GeLineq;
let gelineq: GeLineq = GeLineq {
    id      : None,
    coeffs  : vec![2, 1, 1],
    bounds  : vec![(0,1), (0,1), (0,1)],
    bias    : -1,
    indices : vec![0, 1, 2]
  };
let result = GeLineq::min_max_coefficients(&gelineq);
assert_eq!(vec![1, 1, 1], result.as_ref().expect("").coeffs);

Trait Implementations§

Source§

impl Clone for GeLineq

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Hash for GeLineq

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.