Skip to main content

A type-safe, IDE-friendly wrapper for optimization solvers with automatic data-driven modeling

Project description

LumiX Logo

LumiX

Python Version License Documentation

A modern, type-safe wrapper for optimization solvers with automatic data-driven modeling

LumiX makes mathematical programming accessible, maintainable, and enjoyable by providing a unified, type-safe interface to multiple optimization solvers.

โœจ Key Features

  • ๐ŸŽฏ Type-Safe & IDE-Friendly โ€” Full type hints and autocomplete support for a superior development experience
  • ๐Ÿ”Œ Multi-Solver Support โ€” Seamlessly switch between OR-Tools, Gurobi, CPLEX, GLPK, and CP-SAT
  • ๐Ÿ“Š Data-Driven Modeling โ€” Build models directly from your data with automatic indexing and mapping
  • ๐Ÿ”„ Automatic Linearization โ€” Automatically linearize non-linear constraints (bilinear, absolute value, piecewise)
  • ๐Ÿ“ˆ Advanced Analysis โ€” Built-in sensitivity analysis, scenario analysis, and what-if analysis tools
  • ๐ŸŽฏ Goal Programming โ€” Native support for multi-objective optimization with priorities and weights
  • โšก ORM Integration โ€” Map solutions directly to your ORM models for seamless data flow

๐Ÿš€ Quick Start

Installation

# Install core library
pip install lumix

# Install with a solver (e.g., OR-Tools - free and open-source)
pip install lumix[ortools]

# Or install with multiple solvers
pip install lumix[ortools,gurobi,cplex]

Simple Example

from dataclasses import dataclass
from lumix import (
    LXModel,
    LXVariable,
    LXConstraint,
    LXLinearExpression,
    LXOptimizer,
)

# Define your data
@dataclass
class Product:
    id: str
    name: str
    profit: float
    resource_usage: float

products = [
    Product("A", "Product A", profit=30, resource_usage=2),
    Product("B", "Product B", profit=40, resource_usage=3),
]

# Define decision variables
production = (
    LXVariable[Product, float]("production")
    .continuous()
    .bounds(lower=0)
    .indexed_by(lambda p: p.id)
    .from_data(products)
)

# Build the model
model = (
    LXModel("production_plan")
    .add_variable(production)
    .maximize(
        LXLinearExpression()
        .add_term(production, lambda p: p.profit)
    )
)

# Add constraints
model.add_constraint(
    LXConstraint("resource_limit")
    .expression(
        LXLinearExpression()
        .add_term(production, lambda p: p.resource_usage)
    )
    .le()
    .rhs(100)  # Resource capacity
)

# Solve
optimizer = LXOptimizer().use_solver("ortools")
solution = optimizer.solve(model)

# Access results
if solution.is_optimal():
    print(f"Optimal profit: ${solution.objective_value:,.2f}")
    for product in products:
        qty = solution.variables["production"][product.id]
        print(f"Produce {qty:.2f} units of {product.name}")

๐Ÿ”ง Supported Solvers

LumiX provides a unified interface to multiple solvers:

Solver Linear Integer Quadratic Advanced Features License Best For
OR-Tools โœ“ โœ“ โœ— SOS, Indicator Apache 2.0 (Free) General LP/MIP, Learning
Gurobi โœ“ โœ“ โœ“ SOCP, PWL, Callbacks Commercial/Academic Large-scale, Production
CPLEX โœ“ โœ“ โœ“ SOCP, PWL, Callbacks Commercial/Academic Large-scale, Production
GLPK โœ“ โœ“ โœ— Basic GPL (Free) Small problems, Teaching
CP-SAT โœ— โœ“ โœ— Constraint Programming Apache 2.0 (Free) Scheduling, Assignment

Switching Solvers

# Just change one line to switch solvers
optimizer = LXOptimizer().use_solver("ortools")   # Free
optimizer = LXOptimizer().use_solver("gurobi")    # Requires license
optimizer = LXOptimizer().use_solver("cplex")     # Requires license
optimizer = LXOptimizer().use_solver("glpk")      # Free
optimizer = LXOptimizer().use_solver("cpsat")     # Free

๐Ÿ“š Core Capabilities

Variables with Automatic Indexing

# Single-dimension indexing
production = (
    LXVariable[Product, float]("production")
    .continuous()
    .indexed_by(lambda p: p.id)
    .from_data(products)
)

# Multi-dimension indexing
from lumix import LXCartesianProduct

assignment = (
    LXVariable[tuple[Driver, Date, Shift], int]("assignment")
    .binary()
    .indexed_by(lambda t: (t[0].id, t[1].id, t[2].id))
    .from_data(LXCartesianProduct(drivers, dates, shifts))
)

Type-Safe Expressions

# Linear expressions with automatic coefficient extraction
profit_expr = (
    LXLinearExpression()
    .add_term(production, lambda p: p.profit)
)

# Quadratic expressions
quadratic_expr = (
    LXQuadraticExpression()
    .add_quadratic_term(x, y, coefficient=0.5)
)

Automatic Linearization

LumiX can automatically linearize non-linear terms:

from lumix import LXBilinearTerm, LXAbsoluteTerm, LXPiecewiseLinearTerm

# Bilinear products (x * y)
bilinear = LXBilinearTerm(x, y, bounds_x=(0, 10), bounds_y=(0, 5))

# Absolute values |x|
absolute = LXAbsoluteTerm(x)

# Piecewise-linear functions
piecewise = LXPiecewiseLinearTerm(
    variable=x,
    breakpoints=[0, 10, 20, 30],
    slopes=[1.0, 0.5, 0.2]
)

Advanced Analysis

from lumix import (
    LXSensitivityAnalyzer,
    LXScenarioAnalyzer,
    LXWhatIfAnalyzer,
)

# Sensitivity analysis
sens = LXSensitivityAnalyzer(model, solution)
report = sens.generate_report()
print(report)

# Scenario analysis
scenario_analyzer = LXScenarioAnalyzer(model, optimizer)
scenario_analyzer.add_scenario("base", {})
scenario_analyzer.add_scenario("high_demand", {"demand": 150})
results = scenario_analyzer.solve_all()

# What-if analysis
whatif = LXWhatIfAnalyzer(model, optimizer)
result = whatif.increase_constraint_rhs("capacity", by=10)
print(f"Impact: ${result.delta_objective:,.2f}")

Goal Programming

from lumix import (
    LXGoal,
    LXGoalMode,
    solve_goal_programming,
)

# Define multiple goals with priorities
goals = [
    LXGoal(
        name="profit",
        target=1000,
        priority=1,
        weight=1.0,
        is_minimization=False,
    ),
    LXGoal(
        name="quality",
        target=95,
        priority=2,
        weight=0.8,
    ),
]

# Solve with goal programming
solution = solve_goal_programming(
    model,
    goals,
    mode=LXGoalMode.SEQUENTIAL,
    solver="gurobi",
)

๐Ÿ“– Documentation

Examples

The repository includes 11 examples demonstrating various features:

  1. Production Planning โ€” Single-model indexing, data-driven modeling
  2. Driver Scheduling โ€” Multi-dimensional indexing, scheduling
  3. Facility Location โ€” Binary variables, fixed costs
  4. Basic LP โ€” Simple linear programming
  5. CP-SAT Assignment โ€” Constraint programming solver
  6. McCormick Bilinear โ€” Bilinear term linearization
  7. Piecewise Functions โ€” Piecewise-linear approximations
  8. Scenario Analysis โ€” Multiple scenario comparison
  9. Sensitivity Analysis โ€” Parameter sensitivity
  10. What-If Analysis โ€” Decision support
  11. Goal Programming โ€” Multi-objective optimization

๐ŸŽฏ Why LumiX?

Before (Traditional Approach)

# Manual indexing, no type safety
x = {}
for i in range(len(products)):
    x[i] = model.addVar(name=f"x_{i}")

# String-based error-prone expressions
model.addConstr(
    sum(x[i] * data[i] for i in range(len(products))) <= capacity
)

After (LumiX)

# Type-safe, data-driven, IDE-friendly
production = (
    LXVariable[Product, float]("production")
    .continuous()
    .indexed_by(lambda p: p.id)
    .from_data(products)
)

model.add_constraint(
    LXConstraint("capacity")
    .expression(
        LXLinearExpression()
        .add_term(production, lambda p: p.usage)
    )
    .le()
    .rhs(capacity)
)

Benefits:

  • โœ“ Full IDE autocomplete
  • โœ“ Type checking catches errors early
  • โœ“ No manual indexing
  • โœ“ Data-driven coefficients
  • โœ“ Readable, maintainable code
  • โœ“ Easy to refactor

๐Ÿ› ๏ธ Development

Setup Development Environment

git clone https://github.com/tdelphi1981/LumiX.git
cd LumiX
pip install -e .[dev]

Run Tests

pytest

Type Checking

mypy src/lumix

Code Formatting

black src/lumix
ruff check src/lumix

๐Ÿ“ฆ Project Structure

lumix/
โ”œโ”€โ”€ src/lumix/
โ”‚   โ”œโ”€โ”€ core/              # Core model building (variables, constraints, expressions)
โ”‚   โ”œโ”€โ”€ solvers/           # Solver interfaces (OR-Tools, Gurobi, CPLEX, GLPK, CP-SAT)
โ”‚   โ”œโ”€โ”€ analysis/          # Analysis tools (sensitivity, scenario, what-if)
โ”‚   โ”œโ”€โ”€ linearization/     # Automatic linearization engine
โ”‚   โ”œโ”€โ”€ goal_programming/  # Goal programming support
โ”‚   โ”œโ”€โ”€ indexing/          # Multi-dimensional indexing
โ”‚   โ”œโ”€โ”€ nonlinear/         # Non-linear terms
โ”‚   โ”œโ”€โ”€ solution/          # Solution handling and mapping
โ”‚   โ””โ”€โ”€ utils/             # Utilities (logger, ORM, rational converter)
โ”œโ”€โ”€ examples/              # 11 comprehensive examples
โ”œโ”€โ”€ tests/                 # Test suite
โ””โ”€โ”€ docs/                  # Sphinx documentation

๐Ÿค Contributing

Contributions are welcome! Please:

  1. Open an issue to discuss your idea
  2. Fork the repository
  3. Create a feature branch
  4. Add tests for new functionality
  5. Ensure all tests pass
  6. Submit a pull request

๐Ÿ“„ License

LumiX is licensed under the Academic Free License v3.0.

This is a permissive open-source license that:

  • โœ“ Allows commercial use
  • โœ“ Allows modification and distribution
  • โœ“ Provides patent protection
  • โœ“ Is OSI-approved

๐Ÿ™ Acknowledgments

LumiX builds upon the excellent work of:

๐Ÿ“ž Support

๐Ÿ—บ๏ธ Roadmap

  • Additional solver support (HiGHS, SCIP)
  • Jupyter notebook integration
  • Interactive visualization tools
  • Cloud solver integration
  • Extended ORM support (SQLAlchemy, Django)
  • Advanced constraint programming features
  • Parallel scenario evaluation
  • Model versioning and serialization

Authors

This project is maintained by:

For a complete list of contributors, see AUTHORS.


Made with โค๏ธ by the LumiX Contributors

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

lumix_opt-0.1.1.tar.gz (124.2 kB view details)

Uploaded Source

Built Distribution

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

lumix_opt-0.1.1-py3-none-any.whl (145.7 kB view details)

Uploaded Python 3

File details

Details for the file lumix_opt-0.1.1.tar.gz.

File metadata

  • Download URL: lumix_opt-0.1.1.tar.gz
  • Upload date:
  • Size: 124.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.5.25

File hashes

Hashes for lumix_opt-0.1.1.tar.gz
Algorithm Hash digest
SHA256 6c098ca656c8d5a63f7e62e9afc460b3ecf7571b650d7aa83ff0ab99d87e351c
MD5 b0de42ed2dbfbbcf492273d22ac2378f
BLAKE2b-256 67795264878e85ada4245cd944ffed50f6253a358a3938b9f7ea8aea33e9ed95

See more details on using hashes here.

File details

Details for the file lumix_opt-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: lumix_opt-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 145.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.5.25

File hashes

Hashes for lumix_opt-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 1a8683a244a689b5934431345788670e6a24ab26bc43de7ff577aebbdf859c01
MD5 03fcd6136439120b19afb7b2532443c1
BLAKE2b-256 26e152be83e3d733c292a7221b7b0bf4e4934f59f40d103f86a7e30ba36c08d6

See more details on using hashes here.

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