Skip to content

Commit b6c26fe

Browse files
committed
Fixed more typing issues.
1 parent c49a2b8 commit b6c26fe

1 file changed

Lines changed: 28 additions & 18 deletions

File tree

linopy/dual.py

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ def _con_lookup(m: Model) -> dict:
131131
return con_lookup
132132

133133

134-
def bounds_to_constraints(self) -> None:
134+
def bounds_to_constraints(m) -> None:
135135
"""
136136
Add explicit bound constraints for variables with bounds set directly
137137
in the variable rather than via explicit constraints.
@@ -141,45 +141,50 @@ def bounds_to_constraints(self) -> None:
141141
142142
Also resets variable bounds to [-inf, inf] after adding constraints,
143143
to avoid double-counting in the dual.
144+
145+
Parameters
146+
----------
147+
m : Model
148+
Linopy model to convert variable bounds to constraints. Mutates the model in-place.
144149
"""
145150
logger.debug("Converting variable bounds to explicit constraints.")
146151
logger.debug("Relaxing variable bounds to [-inf, inf].")
147-
for var_name, var in self.variables.items():
152+
for var_name, var in m.variables.items():
148153
mask = var.labels != -1
149154
lb = var.lower
150155
ub = var.upper
151156

152157
# lower bound
153-
if f"{var_name}-bound-lower" not in self.constraints:
158+
if f"{var_name}-bound-lower" not in m.constraints:
154159
has_finite_lb = np.isfinite(lb.values[mask.values]).any()
155160
if has_finite_lb:
156-
self.add_constraints(
161+
m.add_constraints(
157162
var >= lb,
158163
name=f"{var_name}-bound-lower",
159164
mask=mask,
160165
)
161166
logger.debug(f"Added lower bound constraint for '{var_name}'.")
162167
var.lower.values[mask.values] = -np.inf
163168
# Remove bounds to avoid double-counting in the dual. Rely on the new constraints instead.
164-
self.variables[var_name].lower.values[mask.values] = -np.inf
169+
m.variables[var_name].lower.values[mask.values] = -np.inf
165170
else:
166171
logger.debug(
167172
f"Variable '{var_name}' has no finite lower bound, skipping."
168173
)
169174

170175
# upper bound
171-
if f"{var_name}-bound-upper" not in self.constraints:
176+
if f"{var_name}-bound-upper" not in m.constraints:
172177
has_finite_ub = np.isfinite(ub.values[mask.values]).any()
173178
if has_finite_ub:
174-
self.add_constraints(
179+
m.add_constraints(
175180
var <= ub,
176181
name=f"{var_name}-bound-upper",
177182
mask=mask,
178183
)
179184
logger.debug(f"Added upper bound constraint for '{var_name}'.")
180185
var.upper.values[mask.values] = np.inf
181186
# Remove bounds to avoid double-counting in the dual. Rely on the new constraints instead.
182-
self.variables[var_name].upper.values[mask.values] = np.inf
187+
m.variables[var_name].upper.values[mask.values] = np.inf
183188
else:
184189
logger.debug(
185190
f"Variable '{var_name}' has no finite upper bound, skipping."
@@ -303,7 +308,7 @@ def _build_dual_feas_terms(
303308
A = m.matrices.A
304309
if A is None:
305310
raise ValueError("Constraint matrix is None, model has no constraints.")
306-
A_csc = m.matrices.A.tocsc()
311+
A_csc = A.tocsc()
307312
c = m.matrices.c
308313
indptr = A_csc.indptr
309314
indices = A_csc.indices
@@ -466,7 +471,7 @@ def _add_dual_objective(
466471
a primal objective constant excluded via include_objective_constant=False
467472
during model creation. Default is 0.0.
468473
"""
469-
dual_obj = LinearExpression(None, m2)
474+
dual_obj: LinearExpression = LinearExpression(None, m2)
470475
sense = "max" if m.objective.sense == "min" else "min"
471476

472477
for name, con in m.constraints.items():
@@ -487,7 +492,7 @@ def _add_dual_objective(
487492

488493

489494
def dualize(
490-
self,
495+
m,
491496
add_objective_constant: float = 0.0,
492497
) -> Model:
493498
"""
@@ -521,6 +526,9 @@ def dualize(
521526
522527
Parameters
523528
----------
529+
m : Model
530+
Primal linopy model to dualize. Must have a linear objective and linear constraints.
531+
524532
add_objective_constant : float, optional
525533
Constant term to add to the dual objective. Use this to pass through
526534
a primal objective constant. Default is 0.0.
@@ -539,7 +547,7 @@ def dualize(
539547
"""
540548
from linopy.model import Model
541549

542-
m = self.copy()
550+
m1 = m.copy()
543551
m2 = Model()
544552

545553
if not m.variables or not m.constraints:
@@ -548,10 +556,12 @@ def dualize(
548556
)
549557
return m2
550558

551-
m.bounds_to_constraints()
552-
var_lup = _var_lookup(m)
553-
con_lup = _con_lookup(m)
554-
dual_vars = _add_dual_variables(m, m2)
555-
_add_dual_feasibility_constraints(m, m2, dual_vars, var_lup, con_lup)
556-
_add_dual_objective(m, m2, dual_vars, add_objective_constant=add_objective_constant)
559+
m1.bounds_to_constraints()
560+
var_lup = _var_lookup(m1)
561+
con_lup = _con_lookup(m1)
562+
dual_vars = _add_dual_variables(m1, m2)
563+
_add_dual_feasibility_constraints(m1, m2, dual_vars, var_lup, con_lup)
564+
_add_dual_objective(
565+
m1, m2, dual_vars, add_objective_constant=add_objective_constant
566+
)
557567
return m2

0 commit comments

Comments
 (0)