Source code for cplex._internal._pwl

# --------------------------------------------------------------------------
# File: _pwl.py
# ---------------------------------------------------------------------------
# Licensed Materials - Property of IBM
# 5725-A06 5725-A29 5724-Y48 5724-Y49 5724-Y54 5724-Y55 5655-Y21
# Copyright IBM Corporation 2008, 2024. All Rights Reserved.
#
# US Government Users Restricted Rights - Use, duplication or
# disclosure restricted by GSA ADP Schedule Contract with
# IBM Corp.
# ------------------------------------------------------------------------
"""Piecewise Linear API"""
from ._baseinterface import BaseInterface
from . import _procedural as _proc
from . import _aux_functions as _aux


[docs] class PWLConstraintInterface(BaseInterface): """Methods for adding, querying, and modifying PWL constraints. A PWL constraint describes a piecewise linear relationship between two variables: vary=pwl(varx). The PWL constraint is described by specifying the index of the vary and varx variables involved and by providing the breakpoints of the PWL function (specified by the (breakx[i],breaky[i]) coordinate pairs). Before the first segment of the PWL function there may be a half-line; its slope is specified by preslope. After the last segment of the the PWL function there may be a half-line; its slope is specified by postslope. Two consecutive breakpoints may have the same x coordinate, in such cases there is a discontinuity in the PWL function. Three consecutive breakpoints may not have the same x coordinate. """
[docs] def __init__(self, cpx): """Creates a new PWLConstraintInterface. The PWL constraint interface is exposed by the top-level `Cplex` class as `Cplex.pwl_constraints`. This constructor is not meant to be used externally. """ super().__init__(cplex=cpx, getindexfunc=_proc.getpwlindex)
[docs] def get_num(self): """Returns the number of PWL constraints in the problem. Example usage: >>> import cplex >>> c = cplex.Cplex() >>> c.pwl_constraints.get_num() 0 >>> indices = c.variables.add(names=['y', 'x']) >>> idx = c.pwl_constraints.add(vary='y', varx='x', ... preslope=0.5, postslope=2.0, ... breakx=[0.0, 1.0, 2.0], ... breaky=[0.0, 1.0, 4.0], ... name='pwl1') >>> c.pwl_constraints.get_num() 1 """ return _proc.getnumpwl(self._env._e, self._cplex._lp)
[docs] def add(self, vary, varx, preslope, postslope, breakx, breaky, name=""): """Adds a PWL constraint to the problem. vary: the index of the 'y' variable in the vary=pwl(varx) function. varx: the index of the 'x' variable in the vary=pwl(varx) function. preslope: before the first segment of the PWL function there is a half-line; its slope is specified by preslope. postslope: after the last segment of the the PWL function there is a half-line; its slope is specified by postslope. breakx: A list containing the indices of the 'x' variables involved. breaky: A list containing the indices of the 'y' variables involved. name: the name of the PWL constraint; defaults to the empty string. Returns the index of the PWL constraint. Example usage: >>> import cplex >>> c = cplex.Cplex() >>> indices = c.variables.add(names=['y', 'x']) >>> idx = c.pwl_constraints.add(vary='y', varx='x', ... preslope=0.5, postslope=2.0, ... breakx=[0.0, 1.0, 2.0], ... breaky=[0.0, 1.0, 4.0], ... name='pwl1') >>> c.pwl_constraints.get_num() 1 """ # FIXME: Should we provide defaults for any of the other arguments? yidx = self._cplex.variables._conv(vary) xidx = self._cplex.variables._conv(varx) arg_list = [breakx, breaky] nbreaks = _aux.max_arg_length(arg_list) _aux.validate_arg_lengths( arg_list, allow_empty=False, extra_msg=": breakx, breaky" ) def _add(vary, varx, preslope, postslope, breakx, breaky, name): _proc.addpwl(self._env._e, self._cplex._lp, vary, varx, preslope, postslope, nbreaks, breakx, breaky, name) return self._add_single(self.get_num, _add, yidx, xidx, preslope, postslope, breakx, breaky, name)
[docs] def delete(self, *args): """Deletes PWL constraints from the problem. There are four forms by which pwl_constraints.delete may be called. pwl_constraints.delete() deletes all PWL constraints from the problem. pwl_constraints.delete(i) i must be a PWL constraint name or index. Deletes the PWL constraint whose index or name is i. pwl_constraints.delete(seq) seq must be a sequence of PWL constraint names or indices. Deletes the PWL constraints with names or indices contained within s. Equivalent to [pwl_constraints.delete(i) for i in s]. pwl_constraints.delete(begin, end) begin and end must be PWL constraint indices or PWL constraint names. Deletes the PWL constraints with indices between begin and end, inclusive of end. Equivalent to pwl_constraints.delete(range(begin, end + 1)). This will give the best performance when deleting batches of PWL constraints. See CPXdelpwl in the Callable Library Reference Manual for more detail. Example usage: >>> import cplex >>> c = cplex.Cplex() >>> indices = c.variables.add(names=['y', 'x']) >>> idx = c.pwl_constraints.add(vary='y', varx='x', ... preslope=0.5, postslope=2.0, ... breakx=[0.0, 1.0, 2.0], ... breaky=[0.0, 1.0, 4.0], ... name='pwl1') >>> c.pwl_constraints.get_num() 1 >>> c.pwl_constraints.delete(idx) >>> c.pwl_constraints.get_num() 0 """ def _delete(begin, end=None): _proc.delpwl(self._env._e, self._cplex._lp, begin, end) _aux.delete_set_by_range(_delete, self._conv, self.get_num(), *args)
[docs] def get_names(self, *args): """Returns the names of a set of PWL constraints. May be called by four forms. pwl_constraints.get_names() return the names of all PWL constraints in the problem. pwl_constraints.get_names(i) i must be a PWL constraint name or index. Returns the name of PWL constraint i. pwl_constraints.get_names(seq) seq must be a sequence of PWL constraint names or indices. Returns the names of PWL constraints with names or indices in s. Equivalent to [pwl_constraints.get_names(i) for i in s] pwl_constraints.get_names(begin, end) begin and end must be PWL constraint indices or PWL constraint names. Returns the names of PWL constraints with indices between begin and end, inclusive of end. Equivalent to pwl_constraints.get_names(range(begin, end + 1)) Example usage: >>> import cplex >>> c = cplex.Cplex() >>> indices = c.variables.add(names=['y', 'x']) >>> idx = c.pwl_constraints.add(vary='y', varx='x', ... preslope=0.5, postslope=2.0, ... breakx=[0.0, 1.0, 2.0], ... breaky=[0.0, 1.0, 4.0], ... name='pwl1') >>> c.pwl_constraints.get_names(idx) 'pwl1' """ def _get_names(idx): return _proc.getpwlname( self._env._e, self._cplex._lp, idx) return _aux.apply_freeform_one_arg( _get_names, self._conv, self.get_num(), args)
[docs] def get_definitions(self, *args): """Returns the definitions of a set of PWL constraints. Returns a list of PWL definitions, where each definition is a list containing the following components: vary, varx, preslope, postslope, breakx, breaky (see `add`). May be called by four forms. pwl_constraints.get_definitions() return the definitions of all PWL constraints in the problem. pwl_constraints.get_definitions(i) i must be a PWL constraint name or index. Returns the definition of PWL constraint i. pwl_constraints.get_definitions(seq) seq must be a sequence of PWL constraint names or indices. Returns the definitions of PWL constraints with names or indices in s. Equivalent to [pwl_constraints.get_definitions(i) for i in s] pwl_constraints.get_definitions(begin, end) begin and end must be PWL constraint indices or PWL constraint names. Returns the definitions of PWL constraints with indices between begin and end, inclusive of end. Equivalent to pwl_constraints.get_definitions(list(range(begin, end + 1))) Example usage: >>> import cplex >>> c = cplex.Cplex() >>> indices = c.variables.add(names=['y', 'x']) >>> idx = c.pwl_constraints.add(vary='y', varx='x', ... preslope=0.5, postslope=2.0, ... breakx=[0.0, 1.0, 2.0], ... breaky=[0.0, 1.0, 4.0], ... name='pwl1') >>> c.pwl_constraints.get_definitions(idx) [0, 1, 0.5, 2.0, [0.0, 1.0, 2.0], [0.0, 1.0, 4.0]] """ def _getpwl(idx): return _proc.getpwl(self._env._e, self._cplex._lp, idx) return _aux.apply_freeform_one_arg(_getpwl, self._conv, self.get_num(), args)