Skip to main content

Crate oximo_io

Crate oximo_io 

Source
Expand description

§oximo-io

Model I/O for oximo: MPS, LP, and NL writers/readers.

Converts an oximo oximo_core::Model to standard text formats for exchanging models with external solvers and tools.

§Usage

Enabled by default via the io feature on the umbrella oximo crate:

[dependencies]
oximo = "0.6.0" # io is on by default

To opt out:

[dependencies]
oximo = { version = "0.6.0", default-features = false, features = ["highs"] }

To use this crate directly:

[dependencies]
oximo-io   = "0.6.0"
oximo-core = "0.6.0"

§Quick example

use oximo::prelude::*;
use oximo::io::{to_mps_string, to_lp_string};

let m = Model::new("knapsack");
variable!(m, x >= 0.0);
variable!(m, 0.0 <= y <= 4.0);

constraint!(m, c1, x + 2.0 * y <= 14.0);
constraint!(m, c2, 3.0 * x - y >= 0.0);
objective!(m, Max, 3.0 * x + 4.0 * y);

let mps = to_mps_string(&m)?;
let lp  = to_lp_string(&m)?;
println!("{mps}");

§Formats

§MPS

Whitespace-delimited MPS, compatible with conventional fixed-column files whose names do not contain spaces. Widely supported by commercial and open-source solvers.

FeatureBehavior
Objective senseWritten with OBJSENSE
Linear modelsROWS, COLUMNS, RHS, RANGES, bounds, integer markers, binary and semi domains
Quadratic importQUADOBJ, QMATRIX, QCMATRIX, and QSECTION. Gurobi, CPLEX or MOSEK constraint scaling is selectable.
Quadratic exportQUADOBJ/QCMATRIX for Gurobi and CPLEX, QSECTION for MOSEK
Unsupported importSOS and indicator sections return IoError::UnsupportedMps
Constant termsObjective constants use RHS OBJ, constraint constants are folded into RHS
use oximo_io::{
    MpsQuadraticFormat, MpsReadOptions, MpsWriteOptions, read_mps_file, read_mps_with,
    to_mps_string, to_mps_string_with, write_mps,
};
use std::fs::File;
use std::io::BufWriter;

// To string
let s = to_mps_string(&model)?;

// To file
let mut f = BufWriter::new(File::create("model.mps")?);
write_mps(&model, &mut f)?;

// Read a file with the default Gurobi quadratic-constraint convention.
let imported = read_mps_file("model.mps")?;

// Serialize and import with matching CPLEX quadratic conventions.
let cplex_write_options = MpsWriteOptions { quadratic_format: MpsQuadraticFormat::Cplex };
let cplex_mps = to_mps_string_with(&model, &cplex_write_options)?;
let cplex_read_options = MpsReadOptions { quadratic_format: MpsQuadraticFormat::Cplex };
let imported_cplex = read_mps_with(cplex_mps.as_bytes(), &cplex_read_options)?;

// Export quadratic sections in a solver-compatible dialect.
let write_options = MpsWriteOptions { quadratic_format: MpsQuadraticFormat::Mosek };
let quadratic_mps = to_mps_string_with(&model, &write_options)?;

§LP (CPLEX LP format)

Human-readable CPLEX LP format. Sections emitted: header comment, Minimize/Maximize, Subject To, Bounds (non-default only), General, Binaries, Semi-Continuous, End.

FeatureBehavior
Objective senseMinimize / Maximize keyword, no negation needed
Quadratic termsCPLEX bracket notation: objective [Q]/2, constraints [q]
Integer variablesGeneral section (integer/semi-integer), Binaries section
Semicont variablesSemi-Continuous section, threshold emitted as the lower bound
BoundsFree variables declared with free; default lb=0, ub=+inf omitted
Objective constantWritten as a final numeric term if non-zero
use oximo_io::{write_lp, to_lp_string};
use std::fs::File;
use std::io::BufWriter;

// To string
let s = to_lp_string(&model)?;

// To file
let mut f = BufWriter::new(File::create("model.lp")?);
write_lp(&model, &mut f)?;

let imported = oximo_io::read_lp(s.as_bytes())?;

§NL

The standard format for sharing nonlinear and mixed-integer models. Unlike MPS/LP, it carries full nonlinear expressions, emitted as prefix (Polish) opcode trees.

FeatureBehavior
Nonlinear bodiesLinear part goes to J/G; nonlinear residual to C/O opcode trees
Supported operators+ - * /, negation, pow, abs, sin, cos, exp, log (natural)
Output encodingASCII (default) or binary, via WriteOptions::format
Precision / commentsprecision and comments knobs tune the ASCII output
Variable orderingStandard ASL order: nonlinear-first (by appearance), then linear
Name sidecarswrite_nl_files also writes .row / .col name files
Optional segmentsF/S/V/d/r segments supplied via WriteOptions
use oximo::prelude::*;
use oximo::io::{to_nl_string, write_nl_with, write_nl_files, WriteOptions};
use std::fs::File;
use std::io::BufWriter;
use std::path::Path;

// Rosenbrock: min (1 - x)^2 + 100 (y - x^2)^2
let m = Model::new("rosen");
variable!(m, -5.0 <= x <= 5.0);
variable!(m, -5.0 <= y <= 5.0);
objective!(m, Min, (1.0 - x).powi(2) + 100.0 * (y - x.powi(2)).powi(2));

// To string (ASCII only)
let nl = to_nl_string(&m)?;

// To <stub>.nl plus sibling .row / .col name files
let opts = WriteOptions { aux_files: true, ..Default::default() };
write_nl_files(&m, Path::new("rosen"), &opts)?;

// Binary output needs to be written to a byte sink
let mut f = BufWriter::new(File::create("rosen.nl")?);
write_nl_with(&m, &mut f, &WriteOptions::binary())?;

NL files can also be imported with read_nl (a stream) or read_nl_file (a path). The latter automatically uses sibling .row and .col sidecars when present, otherwise deterministic c0/x0 names are generated. Both ASCII and the binary encoding emitted by this crate are accepted. Imported functions, defined variables, logical constraints, and complementarity are reported as unsupported.

The reader preserves interval rows and initial values. Hollerith strings are malformed NL input and return IoError::InvalidNl. Parameter nodes are not reader input, so the writer-side Param behavior remains documented as IoError::UnsupportedNode. Defined-variable sections return IoError::UnsupportedNl. Imported functions and logical/network sections are also rejected with that variant because they are not representable by the core model.

§Errors

All functions return Result<_, IoError>:

VariantCause
IoError::NoObjectiveModel has no objective set
IoError::NonlinearUnsupported nonlinear node in an MPS/LP model (LP accepts degree <= 2)
IoError::UnsupportedNode(n)Node not representable in the target format, e.g. Param in NL
IoError::InvalidNumberNon-finite (NaN/Inf) constant while nonfinite_strings is off
IoError::BinaryToStringto_nl_string used with binary output; use write_nl_with to a byte sink
IoError::Io(e)Underlying std::io::Error from the writer
IoError::InvalidNlMalformed or truncated NL input
IoError::UnsupportedNlSemantics not representable by the core model
IoError::InvalidLpInvalid LP input, with line and column
IoError::UnsupportedLpLP semantics not representable by oximo’s core model
IoError::InvalidMpsInvalid MPS input, with line and column
IoError::UnsupportedMpsMPS semantics not representable by oximo’s core model

§License

MIT OR Apache-2.0

Re-exports§

pub use error::IoError;
pub use lp::read_lp;
pub use lp::read_lp_file;
pub use lp::to_lp_string;
pub use lp::write_lp;
pub use mps::MpsQuadraticFormat;
pub use mps::MpsReadOptions;
pub use mps::MpsWriteOptions;
pub use mps::read_mps;
pub use mps::read_mps_file;
pub use mps::read_mps_file_with;
pub use mps::read_mps_with;
pub use mps::to_mps_string;
pub use mps::to_mps_string_with;
pub use mps::write_mps;
pub use mps::write_mps_with;
pub use nl::Complementarity;
pub use nl::DefinedVar;
pub use nl::ImportedFunction;
pub use nl::NlFormat;
pub use nl::SuffixData;
pub use nl::SuffixFlavour;
pub use nl::SuffixKind;
pub use nl::WriteOptions;
pub use nl::read_nl;
pub use nl::read_nl_file;
pub use nl::to_nl_string;
pub use nl::to_nl_string_with;
pub use nl::write_nl;
pub use nl::write_nl_files;
pub use nl::write_nl_with;

Modules§

error
lp
CPLEX LP file format import and export.
mps
MPS file format import and export.
nl
AMPL .nl file format writer.