Skip to content

Commit 123d0cb

Browse files
committed
[skip ci] allow cp314
1 parent 36094f5 commit 123d0cb

5 files changed

Lines changed: 222 additions & 1 deletion

File tree

.github/workflows/wheel.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ jobs:
3030
env:
3131
# Select wheels
3232
CIBW_BUILD: "*-manylinux_x86_64 *-manylinux_aarch64 *-win_amd64 *-macosx_x86_64 *-macosx_arm64"
33-
CIBW_SKIP: "cp38-* cp314*"
33+
CIBW_SKIP: "cp38-* cp3??t-*"
3434
CIBW_ARCHS: "native"
3535
# use manylinux2014
3636
CIBW_MANYLINUX_X86_64_IMAGE: "quay.io/pypa/manylinux2014_x86_64"

GEMINI.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# PyOptInterface Modeling Guidelines
2+
3+
When modeling with `pyoptinterface_native`, adhere to these patterns.
4+
5+
## Solver Initialization
6+
- Use `pyoptinterface.<solver>.Model()`. Supported: `highs`, `gurobi`, `copt`, `ipopt`, `knitro`, `mosek`, `xpress`.
7+
- For Gurobi, you can manage environments with `poi.gurobi.Env()`.
8+
9+
## Variables
10+
- `model.add_variable(lb=None, ub=None, domain=poi.VariableDomain.Continuous, name="", start=None)`
11+
- `model.add_m_variables(shape, ...)` returns a NumPy array of variables.
12+
13+
## Constraints
14+
- Linear: `model.add_linear_constraint(expr, sense, rhs)` or `model.add_linear_constraint(lhs <= rhs)`.
15+
- Quadratic: `model.add_quadratic_constraint(expr, sense, rhs)`.
16+
- Matrix: `model.add_m_linear_constraints(A, x, sense, b)`.
17+
- Nonlinear: Wrap in `with nl.graph():` and use `model.add_nl_constraint(expr)`.
18+
19+
## Objective
20+
- `model.set_objective(expr, sense)`.
21+
- Nonlinear: `with nl.graph(): model.add_nl_objective(expr, sense)`.
22+
23+
## Attributes
24+
- Get: `model.get_model_attribute(poi.ModelAttribute.TerminationStatus)`.
25+
- Set: `model.set_variable_attribute(v, poi.VariableAttribute.LowerBound, 0.0)`.
26+
- Results: `model.get_variable_attribute(v, poi.VariableAttribute.Value)`.
27+
28+
## Common Utilities
29+
- `poi.quicksum(terms)`: Efficiently sum variables/expressions.
30+
- `poi.Eq`, `poi.Leq`, `poi.Geq`: Aliases for constraint senses.
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
---
2+
name: pyoptinterface-expert
3+
description: Specialized guidance for modeling mathematical optimization problems using the pyoptinterface_native library. Use when building optimization models (LP, QP, MIP, NLP), interfacing with solvers (Gurobi, HiGHS, Ipopt, etc.), and performing matrix-based or nonlinear modeling in Python.
4+
---
5+
6+
# PyOptInterface Expert Skill
7+
8+
This skill provides expert guidance for using `pyoptinterface` (POI), a high-performance Python modeling interface for mathematical optimization solvers.
9+
10+
## Core Concepts
11+
12+
POI follows a common modeling pattern:
13+
1. Create a solver-specific model (e.g., `poi.highs.Model()`).
14+
2. Add variables using `model.add_variable()` or `model.add_m_variables()`.
15+
3. Set the objective using `model.set_objective()`.
16+
4. Add constraints using `model.add_linear_constraint()`, `model.add_quadratic_constraint()`, or `model.add_nl_constraint()`.
17+
5. Call `model.optimize()` and retrieve results.
18+
19+
## Key Workflows
20+
21+
### 1. Basic Modeling
22+
```python
23+
import pyoptinterface as poi
24+
from pyoptinterface import highs
25+
26+
model = highs.Model()
27+
x = model.add_variable(lb=0, name="x")
28+
y = model.add_variable(lb=0, name="y")
29+
30+
model.set_objective(x + 2 * y, poi.ObjectiveSense.Minimize)
31+
model.add_linear_constraint(x + y >= 10, name="c1")
32+
33+
model.optimize()
34+
status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)
35+
if status == poi.TerminationStatusCode.OPTIMAL:
36+
print(f"x: {model.get_variable_attribute(x, poi.VariableAttribute.Value)}")
37+
```
38+
39+
### 2. Matrix-based Modeling
40+
Use `add_m_variables` and `add_m_linear_constraints` for performance with NumPy/SciPy.
41+
```python
42+
import numpy as np
43+
x = model.add_m_variables((10,), lb=0)
44+
A = np.random.rand(5, 10)
45+
b = np.ones(5)
46+
model.add_m_linear_constraints(A, x, poi.Leq, b)
47+
```
48+
49+
### 3. Nonlinear Modeling
50+
Nonlinear expressions must be wrapped in `nl.graph()` context.
51+
```python
52+
from pyoptinterface import nl
53+
with nl.graph():
54+
model.add_nl_objective(x * x + nl.sin(y))
55+
model.add_nl_constraint(x * y >= 5)
56+
```
57+
58+
## Reference Documentation
59+
- API Reference: [references/api.md](references/api.md)
60+
- Modeling Examples: [references/examples.md](references/examples.md)
61+
62+
## Best Practices
63+
- Use `poi.quicksum()` for large summations.
64+
- Check `TerminationStatus` before accessing variable values.
65+
- For large-scale models, prefer the Matrix API (`add_m_...`).
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# API Reference
2+
3+
## Model Classes
4+
Imported from solver submodules:
5+
- `pyoptinterface.highs.Model`
6+
- `pyoptinterface.gurobi.Model`
7+
- `pyoptinterface.copt.Model`
8+
- `pyoptinterface.ipopt.Model`
9+
- `pyoptinterface.knitro.Model`
10+
- `pyoptinterface.mosek.Model`
11+
- `pyoptinterface.xpress.Model`
12+
13+
## Core Methods
14+
### Model
15+
- `add_variable(lb, ub, domain, name, start)`: Add a single variable.
16+
- `add_m_variables(shape, lb, ub, domain, name, start)`: Add a NumPy array of variables.
17+
- `add_linear_constraint(expr, sense, rhs, name)`: Add a linear constraint.
18+
- `add_quadratic_constraint(expr, sense, rhs, name)`: Add a quadratic constraint.
19+
- `add_m_linear_constraints(A, x, sense, rhs)`: Add constraints in matrix form $Ax \sim b$.
20+
- `add_nl_constraint(expr)`: Add a nonlinear constraint (within `nl.graph()`).
21+
- `set_objective(expr, sense)`: Set objective function.
22+
- `set_nl_objective(expr, sense)`: Set nonlinear objective.
23+
- `optimize()`: Solve the model.
24+
- `get_model_attribute(attr)`: Get model information (Status, ObjVal, etc.).
25+
- `get_variable_attribute(v, attr)`: Get variable information (Value, ReducedCost, etc.).
26+
- `set_variable_attribute(v, attr, value)`: Set variable bounds, starts, etc.
27+
- `get_value(expr)`: Evaluate expression at the current solution.
28+
29+
## Enums
30+
### `poi.VariableDomain`
31+
- `Continuous`
32+
- `Integer`
33+
- `Binary`
34+
35+
### `poi.ConstraintSense`
36+
- `Equal` (or `poi.Eq`)
37+
- `LessEqual` (or `poi.Leq`)
38+
- `GreaterEqual` (or `poi.Geq`)
39+
40+
### `poi.ObjectiveSense`
41+
- `Minimize`
42+
- `Maximize`
43+
- `Feasibility`
44+
45+
### `poi.TerminationStatusCode`
46+
- `OPTIMAL`
47+
- `INFEASIBLE`
48+
- `UNBOUNDED`
49+
- `TIME_LIMIT`
50+
- `ITERATION_LIMIT`
51+
52+
### `poi.ModelAttribute`
53+
- `TerminationStatus`
54+
- `ObjectiveValue`
55+
- `SolveTimeSec`
56+
- `RelativeGap`
57+
- `Silent`
58+
59+
### `poi.VariableAttribute`
60+
- `Value`
61+
- `Name`
62+
- `LowerBound`
63+
- `UpperBound`
64+
- `Domain`
65+
- `PrimalStart`
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Modeling Examples
2+
3+
## 1. Knapsack Problem (MIP)
4+
Maximize total value given a weight limit.
5+
```python
6+
import pyoptinterface as poi
7+
from pyoptinterface import highs
8+
9+
values = [10, 15, 20, 8]
10+
weights = [2, 3, 5, 2]
11+
limit = 8
12+
13+
model = highs.Model()
14+
x = model.add_m_variables(len(values), domain=poi.VariableDomain.Binary)
15+
16+
model.set_objective(poi.quicksum(values[i] * x[i] for i in range(len(values))), poi.ObjectiveSense.Maximize)
17+
model.add_linear_constraint(poi.quicksum(weights[i] * x[i] for i in range(len(weights))) <= limit)
18+
19+
model.optimize()
20+
if model.get_model_attribute(poi.ModelAttribute.TerminationStatus) == poi.TerminationStatusCode.OPTIMAL:
21+
print("Selected items:", [i for i in range(len(values)) if model.get_variable_attribute(x[i], poi.VariableAttribute.Value) > 0.5])
22+
```
23+
24+
## 2. Sparse Matrix Model (LP)
25+
Solve $Ax \le b$ using the matrix API.
26+
```python
27+
import numpy as np
28+
from scipy import sparse
29+
import pyoptinterface as poi
30+
from pyoptinterface import highs
31+
32+
m, n = 100, 500
33+
A = sparse.random(m, n, density=0.1)
34+
b = np.random.rand(m)
35+
c = np.random.rand(n)
36+
37+
model = highs.Model()
38+
x = model.add_m_variables(n, lb=0)
39+
40+
model.set_objective(poi.quicksum(c[i] * x[i] for i in range(n)))
41+
model.add_m_linear_constraints(A, x, poi.Leq, b)
42+
43+
model.optimize()
44+
```
45+
46+
## 3. Nonlinear Rosenbrock Function (NLP)
47+
Minimize $f(x, y) = (1-x)^2 + 100(y-x^2)^2$.
48+
```python
49+
import pyoptinterface as poi
50+
from pyoptinterface import ipopt, nl
51+
52+
model = ipopt.Model()
53+
x = model.add_variable(lb=-5, ub=5)
54+
y = model.add_variable(lb=-5, ub=5)
55+
56+
with nl.graph():
57+
model.add_nl_objective((1 - x)**2 + 100 * (y - x**2)**2, poi.ObjectiveSense.Minimize)
58+
59+
model.optimize()
60+
print(f"Optimal x: {model.get_value(x)}, y: {model.get_value(y)}")
61+
```

0 commit comments

Comments
 (0)