Skip to main content

Hybrid MINLP solver combining Rust and JAX

Project description

discopt

CI codecov

discopt

A hybrid Mixed-Integer Nonlinear Programming (MINLP) solver combining a Rust backend, JAX automatic differentiation, and Python orchestration. Solves MINLP problems via NLP-based spatial Branch and Bound with JIT-compiled objective/gradient/Hessian evaluation.

Features

  • Algebraic modeling API -- continuous, binary, and integer variables with operator overloading
  • Spatial Branch and Bound -- Rust-powered node pool, branching, and pruning
  • JIT-compiled NLP evaluation -- objective, gradient, Hessian, and constraint Jacobian via JAX
  • Three NLP backends -- pure-JAX interior-point method (default, vmap-batched), ripopt (Rust IPM via PyO3), cyipopt (Ipopt)
  • Convex relaxations -- McCormick envelopes (21 functions including sigmoid/softplus/tanh), piecewise McCormick, alphaBB underestimators
  • Neural network embedding -- embed trained feedforward networks (ReLU, sigmoid, tanh, softplus) as MINLP constraints via big-M, full-space, and reduced-space strategies; interval arithmetic bound propagation; ONNX import (pip install discopt[nn])
  • Generalized disjunctive programming -- BooleanVar, propositional logic operators (land, lor, lnot, atleast, atmost, exactly), either_or(), if_then(); reformulated via big-M, multiple big-M (LP-tightened), hull, or Logic-based Outer Approximation (gdp_method="loa")
  • Presolve -- FBBT (interval arithmetic, probing, Big-M simplification), OBBT with LP warm-start
  • Cutting planes -- reformulation-linearization (RLT) and outer approximation (OA)
  • GNN branching policy -- bipartite graph neural network trained on strong branching data
  • Primal heuristics -- multi-start NLP, feasibility pump
  • Differentiable optimization -- parameter sensitivity via envelope theorem and KKT implicit differentiation
  • .nl file import -- read AMPL-format models via Rust parser
  • Dynamic optimization -- DAE collocation (Radau/Legendre) and finite differences for optimal control, parameter estimation, and PDE-constrained optimization
  • CUTEst interface -- NLP benchmarking against the CUTEst test set
  • LLM integration (optional) -- conversational model building, diagnostics, and reformulation suggestions
  • 1650+ tests -- 141 Rust + 1510+ Python

Quick Start

from discopt import Model

m = Model("example")
x = m.continuous("x", lb=0, ub=5)
y = m.continuous("y", lb=0, ub=5)
z = m.binary("z")

m.minimize(x**2 + y**2 + z)
m.subject_to(x + y >= 1)
m.subject_to(x**2 + y <= 3)

result = m.solve()
print(result.status)     # "optimal"
print(result.objective)  # 0.5
print(result.x)          # {"x": 0.5, "y": 0.5, "z": 0.0}

Architecture

Model.solve()  -->  Python orchestrator  -->  Rust TreeManager (B&B engine)
                        |                          |
                  JAX NLPEvaluator           Node pool / branching / pruning
                  NLP backends:              Zero-copy numpy arrays (PyO3)
                    ripopt  (Rust IPM, PyO3)
                    ipm     (pure-JAX, vmap batch)  [default]
                    cyipopt (Ipopt)

Rust backend (crates/discopt-core): Expression IR, Branch and Bound tree (node pool, branching, pruning), .nl file parser, FBBT/presolve (interval arithmetic, probing, Big-M simplification).

Rust-Python bindings (crates/discopt-python): PyO3 bindings with zero-copy numpy array transfer for the B&B tree manager, expression IR, batch dispatch, and .nl parser.

JAX layer (python/discopt/_jax): DAG compiler mapping modeling expressions to JAX primitives, JIT-compiled NLP evaluator (objective, gradient, Hessian, constraint Jacobian), McCormick convex/concave relaxations (21 functions), and a relaxation compiler with vmap support.

Solver wrappers (python/discopt/solvers): ripopt (Rust IPM via PyO3), cyipopt NLP wrapper for Ipopt, HiGHS LP and MILP wrappers with warm-start support.

CUTEst interface (python/discopt/interfaces/cutest.py): PyCUTEst-based evaluator for NLP benchmarking against the CUTEst test set.

Orchestrator (python/discopt/solver.py): End-to-end Model.solve() connecting all components. At each B&B node: solve continuous NLP relaxation with tightened bounds, prune infeasible nodes, fathom integer-feasible solutions, branch on most fractional variable.

NLP Backends

Backend Implementation Use Case
ipm (default) Pure-JAX IPM B&B inner loop; GPU-batched via jax.vmap
ripopt Rust IPM via PyO3 Single-problem NLP; fastest wall-clock
cyipopt Ipopt via cyipopt Single-problem NLP; most robust
result = model.solve(nlp_solver="ipm")      # Pure-JAX (default)
result = model.solve(nlp_solver="ripopt")   # Rust IPM
result = model.solve(nlp_solver="cyipopt")  # Ipopt

Benchmarks

Performance measured on Apple M4 Pro (CPU, JAX 0.8.2). "Warm" times exclude JIT compilation. All solvers produce matching objective values.

Problem Class discopt Comparison Notes
LP (n=100) 0.015s warm HiGHS 0.002s, scipy 0.002s Algebraic extraction, no autodiff
QP (n=100) 0.04s warm scipy SLSQP 0.02s Was 66s before algebraic extraction
MILP (n=25) 0.002s HiGHS MIP 0.002s B&B + LP relaxation, correct objectives
MIQP (n=10) 0.004s NLP path 4.9s QP-specialized path: 1000x+ speedup
NLP (n=20, Rosenbrock) IPM 1.1s warm, ripopt 0.42s, Ipopt 0.43s -- ripopt fastest single-solve; IPM best for batched B&B
MINLP (n=10) 0.9s (batch=1) 0.9s (batch=16) vmap batching helps with deeper B&B trees

See the benchmark notebooks for full scaling plots and details:

Installation

Requires Rust 1.84+, Python 3.10+, and Ipopt.

# Install Ipopt (macOS)
brew install ipopt

# Clone ripopt alongside discopt (path dependency at ../ripopt)
git clone <ripopt-repo-url> ../ripopt

# Build Rust-Python bindings (includes ripopt PyO3 bindings)
cd crates/discopt-python && maturin develop && cd ../..

# Run tests
cargo test -p discopt-core
JAX_PLATFORMS=cpu JAX_ENABLE_X64=1 pytest python/tests/ -v

Command-Line Interface

After installation, the discopt command is available on your PATH:

# Search arXiv for recent papers
discopt search-arxiv 'all:"spatial branch and bound"' --max-results 10 --start-date 2026-01-01

# Search OpenAlex
discopt search-openalex "McCormick relaxation" --from-date 2026-01-01 --to-date 2026-03-31

# Write a report from stdin
echo "report content" | discopt write-report reports/output.md

All subcommands output structured JSON, making them suitable for scripting and integration with other tools. The discoptbot literature scanner skill uses these subcommands to automatically find and summarize relevant new papers from arXiv and OpenAlex.

Documentation

Tutorial notebooks are available in docs/notebooks/:

  • Quickstart -- basic modeling and solving
  • MINLP Examples -- mixed-integer nonlinear programs
  • Advanced Features -- relaxations, presolve, cutting planes, branching policies
  • IPM vs Ipopt -- backend comparison
  • Batch IPM -- vmap-batched interior-point solving
  • Dynamic Optimization -- DAE collocation for optimal control, parameter estimation, and PDEs
  • Neural Network Embedding -- optimize over trained ML surrogates as MINLP constraints
  • Decision-Focused Learning -- differentiable optimization in ML pipelines
  • GDP Tutorial -- disjunctive programming, logical constraints, big-M/hull/LOA reformulations

Full documentation is built with Jupyter Book: jupyter-book build docs/

Project Statistics

Last updated: 2026-02-16

Category Count
Python source (python/discopt/) 65 files, ~27,200 lines
Rust source (crates/) 19 files, ~10,700 lines
Test code (python/tests/) 41 files, ~24,500 lines
Total source + tests 125 files, ~62,400 lines
Python tests 1,510+
Rust tests 141
Tutorial notebooks (docs/notebooks/) 21
Git commits 99

Development History

See ROADMAP.md for the full development roadmap and task history.

License

Eclipse Public License 2.0 (EPL-2.0)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

discopt-0.2.4.tar.gz (372.9 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

discopt-0.2.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.3 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

discopt-0.2.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (2.2 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ ARM64

discopt-0.2.4-cp312-cp312-win_amd64.whl (2.2 MB view details)

Uploaded CPython 3.12Windows x86-64

discopt-0.2.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.3 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

discopt-0.2.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (2.2 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64

discopt-0.2.4-cp312-cp312-macosx_11_0_arm64.whl (2.1 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

discopt-0.2.4-cp312-cp312-macosx_10_12_x86_64.whl (2.2 MB view details)

Uploaded CPython 3.12macOS 10.12+ x86-64

discopt-0.2.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.3 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

discopt-0.2.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (2.2 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ ARM64

discopt-0.2.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.3 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

discopt-0.2.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (2.2 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ ARM64

File details

Details for the file discopt-0.2.4.tar.gz.

File metadata

  • Download URL: discopt-0.2.4.tar.gz
  • Upload date:
  • Size: 372.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for discopt-0.2.4.tar.gz
Algorithm Hash digest
SHA256 85c79f7fb2a6ba636c36da13d17a6637169fe1bc2e12ee54d7973eedd600e277
MD5 6b1b674af715880bb2fdf49c4ef8b827
BLAKE2b-256 bf1d014b691784053b86dea7db2c3e67aca37eed4c66101eed3066492c7ee6d7

See more details on using hashes here.

Provenance

The following attestation bundles were made for discopt-0.2.4.tar.gz:

Publisher: release.yml on jkitchin/discopt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file discopt-0.2.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for discopt-0.2.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 c0a6afb3db414e3a64764c1fbfafe48735cee69765f35e6f665f3189ed371925
MD5 d9c24c8339f9039643211f70d83b5673
BLAKE2b-256 b4d8fa1473565a94fb6cf6de3b4a9ee918e21a35733c5477866576b4e8eda21e

See more details on using hashes here.

Provenance

The following attestation bundles were made for discopt-0.2.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on jkitchin/discopt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file discopt-0.2.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for discopt-0.2.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 b403753fff4601c65415c3be7211ecd5bfd3591752f92bf828d22c219b6ed3c9
MD5 793c8cb50d975eb8eeab330ee338d973
BLAKE2b-256 ed54ed8f8a69dca4a45611cb05b6b3fa00871b4e8ac4dfc89b911f6f4fb3792c

See more details on using hashes here.

Provenance

The following attestation bundles were made for discopt-0.2.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on jkitchin/discopt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file discopt-0.2.4-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: discopt-0.2.4-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 2.2 MB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for discopt-0.2.4-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 f265d8b191e9332d772f439afdb55bcdaecddb45ea51976e23ac07b8e13ed746
MD5 892fbd2861de27e01634713e322549e8
BLAKE2b-256 00722609e9d85181f84e145ec70bbc313aefcf27a52ecb41d7f5f1e3b0921aa1

See more details on using hashes here.

Provenance

The following attestation bundles were made for discopt-0.2.4-cp312-cp312-win_amd64.whl:

Publisher: release.yml on jkitchin/discopt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file discopt-0.2.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for discopt-0.2.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 09a6d53b0b414b88de961a412e16d173389d67ae31e1fa15aaa3c3a21226fdec
MD5 e062c97821d631733c9caf5a18a5a77d
BLAKE2b-256 caf1cf6f55fd5e5ce03e2cd9155ef15ce7cc30280c40d5bff02234679faab624

See more details on using hashes here.

Provenance

The following attestation bundles were made for discopt-0.2.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on jkitchin/discopt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file discopt-0.2.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for discopt-0.2.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 de8d7d1b97bd2652660238a30549d2ba7c146075c6a2740d5ae289290116c7ea
MD5 39d6f6d52fdb4e932d2d5a77e6e86634
BLAKE2b-256 2e70016e480313ec257307ca28dfb162d9d1e4a96fd6fcc452bff03763bba0ef

See more details on using hashes here.

Provenance

The following attestation bundles were made for discopt-0.2.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on jkitchin/discopt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file discopt-0.2.4-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for discopt-0.2.4-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 01b09270a5167b0578fb350401b3677a3ca6526ab079a8cd338cfea0e0540370
MD5 93316ba49ef4a05a17e1f12b8bf250af
BLAKE2b-256 e674007c29d009d206ae9966f91866b1108d8e73ffaf1c33a16816537b78c2c7

See more details on using hashes here.

Provenance

The following attestation bundles were made for discopt-0.2.4-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: release.yml on jkitchin/discopt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file discopt-0.2.4-cp312-cp312-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for discopt-0.2.4-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 f8c1b2fbb453e6b6850c18e0785023816920bd867896d8ed6f3d8f933519adfd
MD5 b364ccba6567fcc2c839d4c664582793
BLAKE2b-256 cba9190b179e95b68e0b3c049c81303e0d0dd98ca94d60165e159808ad9add0b

See more details on using hashes here.

Provenance

The following attestation bundles were made for discopt-0.2.4-cp312-cp312-macosx_10_12_x86_64.whl:

Publisher: release.yml on jkitchin/discopt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file discopt-0.2.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for discopt-0.2.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 04c547e744426cd0b54f5fdabbed2eaaeeb09bbf806337b6473df41082712fa1
MD5 16d2f0fc44c4025b8dc4871a61673d69
BLAKE2b-256 267c161b31d968202b46f8fc9ff02bca1de14ed9ecc5580209a746495d841cdc

See more details on using hashes here.

Provenance

The following attestation bundles were made for discopt-0.2.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on jkitchin/discopt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file discopt-0.2.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for discopt-0.2.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 af1a16c53eb38d93c243b367cde95bdee7179fab8fa5e9fe346715357507d03e
MD5 a564fb64e1137c4242dcc96b35183574
BLAKE2b-256 a1ee75663bb2a5f9dad8b562f89813383d3ac608a422a365c913fbbf0bcdfc5c

See more details on using hashes here.

Provenance

The following attestation bundles were made for discopt-0.2.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on jkitchin/discopt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file discopt-0.2.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for discopt-0.2.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 5af98d3694e2feaf287bcebc3c8495cbec72a7722f0aabcc7ad23ff792fef12a
MD5 81b82eec7be409bb55fe58bed66e33df
BLAKE2b-256 8e755ad1f65d17a82cd849893cc4d42ac5efb2cee2a1fa2a4562a7280db72df3

See more details on using hashes here.

Provenance

The following attestation bundles were made for discopt-0.2.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on jkitchin/discopt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file discopt-0.2.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for discopt-0.2.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 c8a2db1c909fafcfd6dd16d00d217af6e074c1ca144cef1943050281791682ce
MD5 c5fd2cda30f9d92ad0e17fca6fda820f
BLAKE2b-256 2ce1f686f0c8f6338e9d60ed1a8617d67257291885b92988e4117862fe4d2f8c

See more details on using hashes here.

Provenance

The following attestation bundles were made for discopt-0.2.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on jkitchin/discopt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page