@@ -6809,6 +6809,169 @@ cdef class Model:
68096809
68106810 return pyCons
68116811
6812+
6813+ def addMatrixConsIndicator (self , cons: MatrixExprCons , binvar: Union[Variable , MatrixVariable] = None ,
6814+ activeone: Union[bool , np.ndarray] = True , name: Union[str , np.ndarray] = "",
6815+ initial: Union[bool , np.ndarray] = True , separate: Union[bool , np.ndarray] = True ,
6816+ enforce: Union[bool , np.ndarray] = True , check: Union[bool , np.ndarray] = True ,
6817+ propagate: Union[bool , np.ndarray] = True , local: Union[bool , np.ndarray] = False ,
6818+ dynamic: Union[bool , np.ndarray] = False , removable: Union[bool , np.ndarray] = False ,
6819+ stickingatnode: Union[bool , np.ndarray] = False ) -> MatrixConstraint:
6820+ """Add an indicator matrix constraint for the linear inequality `cons`.
6821+
6822+ The `binvar` argument models the redundancy of the linear constraint. A solution
6823+ for which `binvar` is 1 must satisfy the constraint.
6824+
6825+ Parameters
6826+ ----------
6827+ cons : MatrixExprCons
6828+ a linear inequality of the form "<=".
6829+ binvar : Variable or MatrixVariable , optional
6830+ binary indicator variable / matrix variable , or None if it should be created. (Default value = None )
6831+ activeone : bool or np.ndarray , optional
6832+ the matrix constraint should be active if binvar is 1 (0 if activeone = False ).
6833+ name : str or np.ndarray , optional
6834+ name of the matrix constraint. (Default value = " " )
6835+ initial : bool or np.ndarray , optional
6836+ should the LP relaxation of matrix constraint be in the initial LP? (Default value = True )
6837+ separate : bool or np.ndarray , optional
6838+ should the matrix constraint be separated during LP processing? (Default value = True )
6839+ enforce : bool or np.ndarray , optional
6840+ should the matrix constraint be enforced during node processing? (Default value = True )
6841+ check : bool or np.ndarray , optional
6842+ should the matrix constraint be checked for feasibility? (Default value = True )
6843+ propagate : bool or np.ndarray , optional
6844+ should the matrix constraint be propagated during node processing? (Default value = True )
6845+ local : bool or np.ndarray , optional
6846+ is the matrix constraint only valid locally? (Default value = False )
6847+ dynamic : bool or np.ndarray , optional
6848+ is the matrix constraint subject to aging? (Default value = False )
6849+ removable : bool or np.ndarray , optional
6850+ should the relaxation be removed from the LP due to aging or cleanup? (Default value = False )
6851+ stickingatnode : bool or np.ndarray , optional
6852+ should the matrix constraint always be kept at the node where it was added ,
6853+ even if it may be moved to a more global node? (Default value = False )
6854+
6855+ Returns
6856+ -------
6857+ MatrixConstraint
6858+ The newly created Indicator MatrixConstraint object.
6859+ """
6860+
6861+ assert isinstance(cons , MatrixExprCons ), (
6862+ f"given constraint is not MatrixExprCons but {cons.__class__.__name__}"
6863+ )
6864+
6865+ shape = cons.shape
6866+
6867+ if isinstance(binvar , MatrixVariable ):
6868+ assert binvar.shape == shape
6869+ if isinstance (activeone, np.ndarray):
6870+ assert activeone.shape == shape
6871+ if isinstance (name, np.ndarray):
6872+ assert name.shape == shape
6873+ if isinstance (initial, np.ndarray):
6874+ assert initial.shape == shape
6875+ if isinstance (separate, np.ndarray):
6876+ assert separate.shape == shape
6877+ if isinstance (enforce, np.ndarray):
6878+ assert enforce.shape == shape
6879+ if isinstance (check, np.ndarray):
6880+ assert check.shape == shape
6881+ if isinstance (propagate, np.ndarray):
6882+ assert propagate.shape == shape
6883+ if isinstance (local, np.ndarray):
6884+ assert local.shape == shape
6885+ if isinstance (dynamic, np.ndarray):
6886+ assert dynamic.shape == shape
6887+ if isinstance (removable, np.ndarray):
6888+ assert removable.shape == shape
6889+ if isinstance (stickingatnode, np.ndarray):
6890+ assert stickingatnode.shape == shape
6891+
6892+ if not isinstance (binvar, MatrixVariable):
6893+ matrix_binvar = np.full(shape, binvar, dtype = Variable)
6894+ else :
6895+ matrix_binvar = binvar
6896+
6897+ if not isinstance (activeone, np.ndarray):
6898+ matrix_activeone = np.full(shape, activeone, dtype = bool )
6899+ else :
6900+ matrix_activeone = activeone
6901+
6902+ if isinstance (name, str ):
6903+ matrix_names = np.full(shape, name, dtype = object )
6904+ if name != " " :
6905+ for idx in np.ndindex(shape):
6906+ matrix_names[idx] = f" {name}_{'_'.join(map(str, idx))}"
6907+ else :
6908+ matrix_names = name
6909+
6910+ if not isinstance (initial, np.ndarray):
6911+ matrix_initial = np.full(shape, initial, dtype = bool )
6912+ else :
6913+ matrix_initial = initial
6914+
6915+ if not isinstance (enforce, np.ndarray):
6916+ matrix_enforce = np.full(shape, enforce, dtype = bool )
6917+ else :
6918+ matrix_enforce = enforce
6919+
6920+ if not isinstance (separate, np.ndarray):
6921+ matrix_separate = np.full(shape, separate, dtype = bool )
6922+ else :
6923+ matrix_separate = separate
6924+
6925+ if not isinstance (check, np.ndarray):
6926+ matrix_check = np.full(shape, check, dtype = bool )
6927+ else :
6928+ matrix_check = check
6929+
6930+ if not isinstance (propagate, np.ndarray):
6931+ matrix_propagate = np.full(shape, propagate, dtype = bool )
6932+ else :
6933+ matrix_propagate = propagate
6934+
6935+ if not isinstance (local, np.ndarray):
6936+ matrix_local = np.full(shape, local, dtype = bool )
6937+ else :
6938+ matrix_local = local
6939+
6940+ if not isinstance (dynamic, np.ndarray):
6941+ matrix_dynamic = np.full(shape, dynamic, dtype = bool )
6942+ else :
6943+ matrix_dynamic = dynamic
6944+
6945+ if not isinstance (removable, np.ndarray):
6946+ matrix_removable = np.full(shape, removable, dtype = bool )
6947+ else :
6948+ matrix_removable = removable
6949+
6950+ if not isinstance (stickingatnode, np.ndarray):
6951+ matrix_stickingatnode = np.full(shape, stickingatnode, dtype = bool )
6952+ else :
6953+ matrix_stickingatnode = stickingatnode
6954+
6955+ matrix_cons = np.empty(shape, dtype = object )
6956+ for idx in np.ndindex(shape):
6957+ matrix_cons[idx] = self .addConsIndicator(
6958+ cons[idx],
6959+ binvar = matrix_binvar[idx],
6960+ activeone = matrix_activeone[idx],
6961+ name = matrix_names[idx],
6962+ initial = matrix_initial[idx],
6963+ separate = matrix_separate[idx],
6964+ enforce = matrix_enforce[idx],
6965+ check = matrix_check[idx],
6966+ propagate = matrix_propagate[idx],
6967+ local = matrix_local[idx],
6968+ dynamic = matrix_dynamic[idx],
6969+ removable = matrix_removable[idx],
6970+ stickingatnode = matrix_stickingatnode[idx],
6971+ )
6972+
6973+ return matrix_cons.view(MatrixConstraint)
6974+
68126975 def getLinearConsIndicator (self , Constraint cons ):
68136976 """
68146977 Get the linear constraint corresponding to the indicator constraint.
0 commit comments