Skip to content

Commit

Permalink
Docs: add readme details about restricting variables to have integer …
Browse files Browse the repository at this point in the history
…values (#78)

* More details in README:
- add more detail on constraining variables to integer solutions
- show the `(integer)` qualifier syntax inside the `variables!` macro
- update documentation links to use `latest`

Add test in `variables.rs` showing `(integer)` qualifier

* - conditional config for test - integer variables not suppored by "clarabel" solver

---------

Co-authored-by: Niklas Smedemark-Margulies <niklas.smedemark-margulies@analog.com>
  • Loading branch information
nik-sm and Niklas Smedemark-Margulies authored Jan 2, 2025
1 parent cdff1bb commit a8112da
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 7 deletions.
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,18 +212,18 @@ If you want to use it with WASM targets, you must include the `clarabel-wasm` fe

## Variable types

`good_lp` internally represents all [variable](https://docs.rs/good_lp/1.4.0/good_lp/variable/struct.Variable.html) values and coefficients as `f64`.
It lets you express constraints using either `f64` or `i32` (in the latter case, the integer will be losslessly converted to a floating point number).
The solution's [values are `f64`](https://docs.rs/good_lp/1.4.0/good_lp/solvers/trait.Solution.html#tymethod.value) as well.
`good_lp` internally represents all [variable](https://docs.rs/good_lp/latest/good_lp/variable/struct.Variable.html) values and coefficients as `f64`.
It lets you express constraints on the range of possible values using either `f64` or `i32` (in the latter case, the integer will be losslessly converted to a floating point number).
The solution's [values are `f64`](https://docs.rs/good_lp/latest/good_lp/solvers/trait.Solution.html#tymethod.value) as well.

For instance:

```rust
// Correct use of f64 and i32 for Variable struct and constraints
// Correct use of f64 and i32 to specify feasible ranges for Variables
variables! {
problem:
a <= 10.0;
2 <= b <= 4;
2 <= b (integer) <= 4; // Variables can be restricted using qualifiers like (integer)
};
let model = problem
.maximise(b)
Expand All @@ -233,7 +233,9 @@ For instance:
```

Here, `a` and `b` are `Variable` instances that can take either continuous (floating-point) or [integer values](https://docs.rs/good_lp/latest/good_lp/variable/struct.VariableDefinition.html#method.integer).
Constraints can be expressed using either `f64` or `i32`, as shown in the example (but replacing for example `4.0` with a `usize` variable would fail, because an usize cannot be converted to an f64 losslessly).
Constraints on possible values can be expressed using either `f64` or `i32`, as shown in the example (but replacing for example `4.0` with a `usize` variable would fail, because an usize cannot be converted to an f64 losslessly).
The [`variables!` macro](https://docs.rs/good_lp/latest/good_lp/macro.variables.html) also allows constraining variables to integer values using qualifiers like `2 <= b (integer) <= 4` above.


Solution values will always be `f64`, regardless of whether the variables were defined with `f64` or `i32`.
So, even if you use integer variables, the solution object will store the integer variable values as `f64`.
Expand Down
23 changes: 22 additions & 1 deletion tests/variables.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use good_lp::{variables, Expression};
use good_lp::{constraint, default_solver, variables, Expression, Solution, SolverModel};

#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::*;

Expand Down Expand Up @@ -57,3 +58,23 @@ fn debug_format() {
expr_str
)
}

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
#[cfg(not(feature = "clarabel"))]
fn variables_macro_integer() {
variables! {
vars:
a <= 1;
2 <= b (integer) <= 4;
}
let solution = vars
.maximise(10 * (a - b / 5) - b)
.using(default_solver)
.with(constraint!(a + 2 <= b))
.with(constraint!(1 + a >= 4 - b))
.solve()
.expect("solve");
assert!((solution.value(a) - 1.).abs() < 1e-5);
assert!((solution.value(b) - 3.).abs() < 1e-5);
}

0 comments on commit a8112da

Please # to comment.