Skip to main content

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
  • 📊 Interactive Visualization — Plotly-based charts for solutions, sensitivity, scenarios, and Gantt schedules
  • 🎯 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-opt

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

# Or install with multiple solvers
pip install "lumix-opt[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 LXIndexDimension

assignment = (
    LXVariable[Tuple[Driver, Date, Shift], int]("assignment")
    .binary()
    .indexed_by_product(
        LXIndexDimension(Driver, lambda d: d.id).from_data(drivers),
        LXIndexDimension(Date, lambda dt: dt.id).from_data(dates),
        LXIndexDimension(Shift, lambda s: s.id).from_data(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 LXConstraint, LXLinearExpression

# Mark constraints as goals with priorities
model.add_constraint(
    LXConstraint("profit_goal")
    .expression(profit_expr)
    .ge()
    .rhs(1000)
    .as_goal(priority=1, weight=1.0)  # Highest priority
)

model.add_constraint(
    LXConstraint("quality_goal")
    .expression(quality_expr)
    .ge()
    .rhs(95)
    .as_goal(priority=2, weight=0.8)  # Lower priority
)

# Set goal programming mode and prepare
model.set_goal_mode("weighted")
model.prepare_goal_programming()

# Solve with standard optimizer
optimizer = LXOptimizer().use_solver("gurobi")
solution = optimizer.solve(model)

Interactive Visualization

LumiX includes Plotly-based visualization tools for analyzing optimization results:

# Install visualization dependencies
pip install "lumix-opt[viz]"
from lumix.visualization import (
    LXSolutionVisualizer,    # Variable values, constraint utilization
    LXSensitivityPlot,       # Tornado charts, shadow prices
    LXScenarioCompare,       # Multi-scenario comparison
    LXGoalProgressChart,     # Goal achievement gauges
    LXScheduleGantt,         # Gantt charts for scheduling
    LXAssignmentMatrix,      # Assignment problem heatmaps
    LXSpatialMap,            # Facility location maps
    LXModelGraph,            # Variable-constraint network
    LXDashboard,             # Combined overview dashboards
)

# Visualize solution
viz = LXSolutionVisualizer(solution, model)
viz.show()  # Opens in browser/Jupyter

# Sensitivity tornado chart
sens_plot = LXSensitivityPlot(sensitivity_analyzer)
sens_plot.plot_tornado(top_n=10).show()

# Export to HTML
viz.to_html("solution.html")

📖 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

Jupyter Notebooks

Interactive tutorials are available in the notebooks/ directory:

Notebook Topic
01-11 Tutorial notebooks covering all example topics above
12-15 High School Timetabling — Comprehensive case study

The High School Timetabling series (notebooks 12-15) demonstrates:

  • 3D multi-model indexing (Lecture × TimeSlot × Classroom)
  • SQLAlchemy ORM integration with from_model(session)
  • Goal programming for teacher preferences
  • Production-ready configuration patterns

🎯 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
│   ├── visualization/     # Plotly-based interactive charts
│   └── utils/             # Utilities (logger, ORM, rational converter)
├── examples/              # 11 comprehensive examples
├── notebooks/             # 15 Jupyter tutorial notebooks
├── 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
  • SQLAlchemy ORM support
  • Django ORM support
  • 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

Metadata

Release files for lumix-opt 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for lumix-opt 0.1.2
File Size Uploaded Provenance
lumix_opt-0.1.2.tar.gz 156.2 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for lumix-opt 0.1.2
File Interpreter ABI Platform
lumix_opt-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 341.1 kB

Release files / lumix_opt-0.1.2.tar.gz

Download URL lumix_opt-0.1.2.tar.gz
Size 156.2 kB
Tags Source
SHA-256 checksum
How to use checksums
9c7f5c8ead8cb1315be303e573b5821c2370c96066d8111963b360c7a3a5ef6a
BLAKE2b-256 checksum
How to use checksums
e2a315c4b5682d5c7ece65661aefd69c3b7dbe1d4107f5b2bf7c1619206679d8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / lumix_opt-0.1.2-py3-none-any.whl

Download URL lumix_opt-0.1.2-py3-none-any.whl
Size 184.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0c8044082d5760c228dab5ff66ded6d91e7afc8ece4b9e0170314cd05598ee81
BLAKE2b-256 checksum
How to use checksums
0adb8435f49e882831cb3237f701a9b58e6362ce8e618c9be552265bf60c8bba
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for lumix-opt 0.1.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page