77from __future__ import annotations
88
99import logging
10- from typing import TYPE_CHECKING
10+ from typing import TYPE_CHECKING , Any
1111
1212import numpy as np
1313import pandas as pd
@@ -300,6 +300,9 @@ def _build_dual_feas_terms(
300300 Nested dict: {var_name: {flat_label: (var_coords, terms, obj_coeff)}}
301301 where terms is a list of (con_name, con_coords, coeff) tuples.
302302 """
303+ A = m .matrices .A
304+ if A is None :
305+ raise ValueError ("Constraint matrix is None, model has no constraints." )
303306 A_csc = m .matrices .A .tocsc ()
304307 c = m .matrices .c
305308 indptr = A_csc .indptr
@@ -308,7 +311,9 @@ def _build_dual_feas_terms(
308311 vlabels = m .matrices .vlabels
309312 clabels = m .matrices .clabels
310313
311- dual_feas_terms = {var_name : {} for var_name in m .variables }
314+ dual_feas_terms : dict [str , dict [int , tuple ]] = {
315+ var_name : {} for var_name in m .variables
316+ }
312317
313318 logger .debug ("Building dual feasibility terms for each primal variable." )
314319
@@ -379,7 +384,6 @@ def _add_dual_feasibility_constraints(
379384 Mapping from flat constraint label to (con_name, coord_dict),
380385 as returned by _con_lookup().
381386 """
382-
383387 dual_feas_terms = _build_dual_feas_terms (m , dual_vars , var_lookup , con_lookup )
384388
385389 c = m .matrices .c
@@ -401,7 +405,12 @@ def _add_dual_feasibility_constraints(
401405 coords = var .labels .coords ,
402406 )
403407
404- def rule (m , * coord_vals , vname = var_name , vdims = var .labels .dims ):
408+ def rule (
409+ m : Model ,
410+ * coord_vals : Any ,
411+ vname : str = var_name ,
412+ vdims : tuple = var .labels .dims ,
413+ ) -> LinearExpression | None :
405414 coord_dict = dict (zip (vdims , coord_vals ))
406415 flat = var .labels .sel (** coord_dict ).item ()
407416 if flat == - 1 :
@@ -457,7 +466,7 @@ def _add_dual_objective(
457466 a primal objective constant excluded via include_objective_constant=False
458467 during model creation. Default is 0.0.
459468 """
460- dual_obj = 0
469+ dual_obj = LinearExpression ( None , m2 )
461470 sense = "max" if m .objective .sense == "min" else "min"
462471
463472 for name , con in m .constraints .items ():
0 commit comments