Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1.4.3 #185

Merged
merged 119 commits into from
Aug 9, 2018
Merged

1.4.3 #185

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
119 commits
Select commit Hold shift + click to select a range
87a3483
Merge branch 'master' into devel
KristianJensen Jan 4, 2017
264e848
Merge branch 'master' into devel
phantomas1234 Jan 20, 2017
efbce6e
Merge branch 'master' into devel
KristianJensen Jan 27, 2017
1716264
fix: bug when changing variable names
KristianJensen Jan 30, 2017
7e41760
feat: allow infeasible primals to be retrieved
KristianJensen Feb 2, 2017
417dcf0
feat: add a tolerance option to scipy_interface
KristianJensen Feb 6, 2017
93fca6d
Merge branch 'master' into devel
KristianJensen Feb 6, 2017
fdb5aba
fix: support all numeric types
KristianJensen Feb 10, 2017
e56efc8
chore: exception types
KristianJensen Feb 10, 2017
2dc50a7
fix: set problem attribute on objectives in new models
KristianJensen Feb 14, 2017
fb4408f
fix: updated in Model __init__ breaks gurobi
KristianJensen Feb 16, 2017
25d6c69
Get linear coefficients from solver (#72)
KristianJensen Feb 17, 2017
0e08556
fix: objective.value should return None if not in model
KristianJensen Feb 22, 2017
5f019e6
fix: get correct primal values from glpk MIPs
KristianJensen Feb 22, 2017
48bd039
test: add test for obj value without model
KristianJensen Feb 23, 2017
fc7f002
fix: allow older versions of cplex
KristianJensen Mar 13, 2017
7872400
Merge branch 'master' into devel
KristianJensen Mar 13, 2017
8cfed1f
test: non-existing cplex status for testing
KristianJensen Mar 13, 2017
89a5b5d
test: fix tests to reflect constraint refactoring
KristianJensen Mar 13, 2017
8e07c09
fix: update gurobi after changing bounds
KristianJensen Mar 13, 2017
4a3d0f4
fix: update gurobi after making changes
KristianJensen Mar 13, 2017
99a259d
fix: gurobi objective val is None without a model
KristianJensen Mar 13, 2017
b54bd66
chore: simplify set_linear_coefficients in gurobi
KristianJensen Mar 13, 2017
08098b6
chore: remove unused _internal_var attribute
KristianJensen Mar 13, 2017
8f430b1
fix: constraint construction when adding constraints
KristianJensen Mar 13, 2017
718616c
fix: reset solution before optimizing if non-optimal
KristianJensen Mar 13, 2017
53730c7
Miplib tests (#6)
the-code-magician Mar 14, 2017
1e08b41
Fix constraint bounds issue (#84)
KristianJensen Mar 20, 2017
c86d37f
fix: make sure that sloppy arg is being passed to super (#83)
KristianJensen Mar 20, 2017
40ab9d0
Netlib tests test also cloned models (#79)
phantomas1234 Mar 23, 2017
ebd5c1f
Add a Gitter chat badge to README.rst (#86) (#88)
KristianJensen Mar 23, 2017
d64cbff
Merge branch 'master' into devel
KristianJensen Mar 30, 2017
a3e5304
Merge branch 'master' into devel
KristianJensen Mar 30, 2017
d98708b
feat: cplex 12.7.1 compatibility
KristianJensen Mar 30, 2017
2ec31da
Change Module Loading Procedure (#91)
long-m-r Mar 31, 2017
7a15952
Fix MIP dual value behaviour (#93)
KristianJensen Apr 6, 2017
eae7c1d
Catch Cplex errors and raise `optlang.SolverError` (#96)
Midnighter Apr 6, 2017
a4030fa
Update README.rst
KristianJensen Apr 6, 2017
84b432e
Make glpk get_linear_coefficients respect variables arg. (#100)
cdiener Apr 8, 2017
e3ca986
Refactor batch getters of problem values (#101)
matthiaskoenig Apr 8, 2017
faf2c3b
test: get_linear_coefficients returns correct length
KristianJensen Apr 8, 2017
7334d9b
fix: disable results and logging with cplex verbosity=0
KristianJensen Apr 8, 2017
2bf107c
test: adapt netlib test to cplex 12.7.1
KristianJensen Apr 8, 2017
5470182
Merge master to devel
KristianJensen Apr 24, 2017
b27cbff
Merge branch 'master' into devel
KristianJensen Apr 24, 2017
aab6f90
chore: use swiglpk batch value functions
KristianJensen Apr 25, 2017
9ee8832
Disable _round_primal_to_bounds (#107)
KristianJensen Apr 27, 2017
60cd005
fix: don't round integer primals
KristianJensen May 2, 2017
6a97118
refactor: make gurobi use var._get_primal
KristianJensen May 2, 2017
3822ece
chore: remove gurobi under construction warning
KristianJensen May 16, 2017
55f4405
Interface to tolerance parameters (#108)
KristianJensen May 17, 2017
f8b8194
chore: update swiglpk requirement
KristianJensen May 17, 2017
8cb07f4
Objective constant terms (#109)
KristianJensen May 17, 2017
80f6e23
Merge branch 'master' into devel
KristianJensen May 19, 2017
98631d0
chore: update readme
KristianJensen May 19, 2017
4033a17
fix: convert obj offsets to floats
KristianJensen Jun 1, 2017
60dc085
fix: one more sympy offset
KristianJensen Jun 2, 2017
0bb0d30
Merge branch 'master' into devel
KristianJensen Jun 2, 2017
760b2a3
Add support for symengine (experimental) (#87)
KristianJensen Jun 13, 2017
9357508
fix: ensure that variable names are not empty str (#127)
hredestig Aug 11, 2017
c33f8ff
Various bug fixes (#126)
KristianJensen Aug 21, 2017
31b8034
chore: clean up interface.py
KristianJensen Aug 21, 2017
5ab47ea
test: add tests and pragmas (for symengine)
KristianJensen Aug 21, 2017
ee2b244
test: more pragmas
KristianJensen Aug 21, 2017
f35d4d7
fix: allow setting bounds on binary variables
KristianJensen Aug 24, 2017
53abedb
Merge branch 'master' into devel
KristianJensen Aug 24, 2017
8787878
chore: add beta warning when using symengine
KristianJensen Aug 24, 2017
a01a7f7
fix: convert cplex problem to LP when last integer var is removed
KristianJensen Sep 17, 2017
f022df9
test: add coverage
KristianJensen Sep 17, 2017
742b7f3
test: more coverage
KristianJensen Sep 17, 2017
768534f
test: pragma for symengine
KristianJensen Sep 18, 2017
9fba825
Merge branch 'master' into devel
KristianJensen Sep 19, 2017
2517287
Add basic types to optlang.symbolics (#134)
cdiener Oct 13, 2017
8a8200a
feat: add and mul return identities if called without arguments
KristianJensen Oct 13, 2017
50188ba
fix: flake8
KristianJensen Oct 13, 2017
1ef6023
test: add tests for symbolics coverage
KristianJensen Oct 15, 2017
206587f
Add missing unpacking in symengine mul (#136)
cdiener Oct 16, 2017
7e83521
Merge branch 'master' into devel
KristianJensen Oct 19, 2017
194caef
Merge branch 'master' into devel
KristianJensen Oct 20, 2017
f1c8bb3
Add an interface to GLPK's exact solver (#145)
phantomas1234 Nov 7, 2017
9ece974
adding simple example using numpy linear algebra (#143)
pstjohn Nov 7, 2017
58399b7
Update simple_numpy.py
KristianJensen Nov 7, 2017
c3feef4
Fix #140 – indicator constraints not being removed (#144)
phantomas1234 Nov 9, 2017
3a69c00
chore: add glpk_exact_interface to init.py
KristianJensen Nov 9, 2017
652639a
chore: pep8 style
KristianJensen Nov 9, 2017
15cad1c
Test symengine on travis (#146)
KristianJensen Nov 9, 2017
4b818c1
chore: remove symengine beta warning
KristianJensen Nov 9, 2017
8335383
chore: Temporarily disable changing of indicator variable
KristianJensen Nov 9, 2017
65602a4
test: add cplex indicator constraint expression test
KristianJensen Nov 9, 2017
5cfddb8
test: comment out unused features of scipy_interface
KristianJensen Nov 9, 2017
6da5d5f
test: improve cplex test coverage
KristianJensen Nov 16, 2017
d8aaa31
fix: flake8
KristianJensen Nov 16, 2017
5723b57
chore: disable integer variables in glpk_exact_interface
KristianJensen Nov 17, 2017
a075978
chore: remove unnecessary logic in glpk_exact_interface
KristianJensen Nov 17, 2017
7a7d738
chore: add optlang._USING_SYMENGINE flag (read-only)
KristianJensen Nov 17, 2017
e093916
fix: typos in glpk_exact_interface
KristianJensen Nov 22, 2017
dcf3efc
chore: adapt glpk_exact tests to not support integer vars
KristianJensen Nov 22, 2017
ac295da
fix: call update in set_linear_coefficients and get_linear_coefficients
KristianJensen Nov 22, 2017
807d7bb
chore: raise an error if glpk ids are longer than 256 chars
KristianJensen Nov 22, 2017
7586640
Merge branch 'master' into devel
KristianJensen Nov 22, 2017
4faedc1
Add QP capability for Gurobi (#149)
cdiener Mar 19, 2018
86f1626
fix: make releases from only one Python version (#152)
Midnighter Mar 21, 2018
d5b0493
Merge branch 'master' into devel
KristianJensen Mar 21, 2018
aef73b0
fix: git clone depth
KristianJensen Mar 21, 2018
c4d0cf0
Fix name issues (#155)
KristianJensen Apr 13, 2018
50b3052
Merge branch 'master' into devel
KristianJensen Apr 13, 2018
e3173fa
fix: Change error message for constraint and objective id errors
KristianJensen May 3, 2018
d14f12f
fix: get None if variable.problem is not defined
KristianJensen May 3, 2018
fac12ea
fix: flake8
KristianJensen May 3, 2018
d93b65e
Merge branch 'master' into devel
KristianJensen May 16, 2018
0f2314b
refactor: set cplex logger name (#162)
kvikshaug May 30, 2018
39f4530
chore: change logger name
KristianJensen May 30, 2018
4fb2c0c
fix: change verbosity first, so subsequent changes are not always logged
KristianJensen Jun 12, 2018
fbee0a4
refactor: make base constants real numbers (#160)
Midnighter Jul 4, 2018
6e7726c
Update README.rst
KristianJensen Aug 6, 2018
0913ac1
Update README.rst
KristianJensen Aug 6, 2018
eef2c9f
fix: automatically expand expressions when using symengine
KristianJensen Aug 6, 2018
d7ad79c
fix: flake8
KristianJensen Aug 7, 2018
2823849
Merge branch 'master' into devel
KristianJensen Aug 8, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ The following dependencies are needed.
The following are optional dependencies that allow other solvers to be used.

- `cplex <https://www-01.ibm.com/software/commerce/optimization/cplex-optimizer/>`__ (LP, MILP, QP, MIQP)
- `gurobipy <http://www.gurobi.com>`__ (LP, MILP (QP and MIQP support will be added in the future))
- `gurobipy <http://www.gurobi.com>`__ (LP, MILP, QP, MIQP)
- `scipy <http://www.scipy.org>`__ (LP)


Expand Down Expand Up @@ -134,9 +134,6 @@ Future outlook
`CPLEX <http://www-01.ibm.com/software/commerce/optimization/cplex-optimizer/>`__
etc.)

The optlang `trello board <https://trello.com/b/aiwfbVKO/optlang>`__
also provides a good overview of the project's roadmap.

.. |PyPI| image:: https://img.shields.io/pypi/v/optlang.svg?maxAge=2592000
:target: https://pypi.python.org/pypi/optlang
.. |License| image:: http://img.shields.io/badge/license-APACHE2-blue.svg
Expand Down
2 changes: 1 addition & 1 deletion optlang/cplex_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ class ResultsStreamHandler(StreamHandler):
def flush(self):
self.logger.debug(self.getvalue())

logger = logging.getLogger()
logger = logging.getLogger(__name__ + ".Model") # TODO: Make the logger name specific to each solver instance
logger.setLevel(logging.CRITICAL)
error_stream_handler = ErrorStreamHandler(logger)
warning_stream_handler = WarningStreamHandler(logger)
Expand Down
6 changes: 4 additions & 2 deletions optlang/expression_parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from optlang.symbolics import One
from optlang.symbolics import Integer

one = Integer(1)


def parse_optimization_expression(obj, linear=True, quadratic=False, expression=None, **kwargs):
Expand Down Expand Up @@ -84,7 +86,7 @@ def _parse_linear_expression(expression, expanded=False, **kwargs):

for var in coefficients:
if not (var.is_Symbol):
if var == One:
if var == one:
constant = var
offset = float(coefficients[var])
elif expanded:
Expand Down
2 changes: 1 addition & 1 deletion optlang/gurobi_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -402,10 +402,10 @@ class Configuration(interface.MathematicalProgrammingConfiguration):
def __init__(self, lp_method='primal', qp_method='primal', presolve=False,
verbosity=0, timeout=None, *args, **kwargs):
super(Configuration, self).__init__(*args, **kwargs)
self.verbosity = verbosity
self.lp_method = lp_method
self.qp_method = qp_method
self.presolve = presolve
self.verbosity = verbosity
self.timeout = timeout

@property
Expand Down
6 changes: 3 additions & 3 deletions optlang/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

import six

import optlang
from optlang.exceptions import IndicatorConstraintsNotSupported

from optlang.util import parse_expr, expr_to_json, is_numeric, SolverTolerances
Expand Down Expand Up @@ -463,7 +464,8 @@ def _canonicalize(self, expression):
elif isinstance(expression, int):
return symbolics.Integer(expression)
else:
# expression = expression.expand() This would be a good way to canonicalize, but is quite slow
if optlang._USING_SYMENGINE:
expression = expression.expand() # This is a good way to canonicalize, but is quite slow for sympy
return expression

@property
Expand Down Expand Up @@ -1630,6 +1632,4 @@ def __setstate__(self, state):

# model.remove(x1)

import optlang

model.interface = optlang.glpk_interface
5 changes: 3 additions & 2 deletions optlang/scipy_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,7 @@ def coefficient_dict(self, names=True):
if self.expression.is_Add:
coefficient_dict = {variable: coef for variable, coef in
self.expression.as_coefficients_dict().items() if variable.is_Symbol}
coefficient_dict = {var: float(coef) for var, coef in coefficient_dict.items()}
elif self.expression.is_Atom and self.expression.is_Symbol:
coefficient_dict = {self.expression: 1}
elif self.expression.is_Mul and len(self.expression.args) <= 2:
Expand Down Expand Up @@ -496,7 +497,7 @@ def coefficient_dict(self):
coefficient_dict = {}
else:
raise ValueError("Invalid expression: " + str(self.expression))
coefficient_dict = {var.name: coef for var, coef in coefficient_dict.items()}
coefficient_dict = {var.name: float(coef) for var, coef in coefficient_dict.items()}
return coefficient_dict

def set_linear_coefficients(self, coefficients):
Expand All @@ -509,7 +510,7 @@ def set_linear_coefficients(self, coefficients):
def get_linear_coefficients(self, variables):
if self.problem is not None:
self.problem.update()
return {v: self.problem.problem.objective.get(v.name, 0) for v in variables}
return {v: float(self.problem.problem.objective.get(v.name, 0)) for v in variables}
else:
raise Exception("Can't get coefficients from solver if objective is not in a model")

Expand Down
12 changes: 6 additions & 6 deletions optlang/symbolics.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@
Real = symengine.RealDouble
Basic = symengine.Basic
Number = symengine.Number
Zero = Integer(0)
One = Integer(1)
NegativeOne = Integer(-1)
Zero = Real(0)
One = Real(1)
NegativeOne = Real(-1)
sympify = symengine.sympy_compat.sympify

Add = symengine.Add
Expand Down Expand Up @@ -113,9 +113,9 @@ def mul(*args):
Real = sympy.RealNumber
Basic = sympy.Basic
Number = sympy.Number
Zero = Integer(0)
One = Integer(1)
NegativeOne = Integer(-1)
Zero = Real(0)
One = Real(1)
NegativeOne = Real(-1)
sympify = sympy.sympify

Add = sympy.Add
Expand Down
24 changes: 24 additions & 0 deletions optlang/tests/abstract_test_cases.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import six
from optlang import interface
from optlang import symbolics
import optlang
import pickle
import json
Expand Down Expand Up @@ -350,6 +351,18 @@ def test_new_invalid_name_raises(self):
with self.assertRaises(Exception):
const.name = "This\ttab"

def test_construct_with_sloppy(self):
x, y, z, w = self.model.variables[:4]
const = self.interface.Constraint(
symbolics.add([symbolics.mul(symbolics.One, var) for var in [x, y, z]]),
lb=0,
sloppy=True
)
self.model.add(const)
self.model.update()

self.assertTrue(const.get_linear_coefficients([x, y, z, w]) == {x: 1, y: 1, z: 1, w: 0})


@six.add_metaclass(abc.ABCMeta)
class AbstractObjectiveTestCase(unittest.TestCase):
Expand Down Expand Up @@ -390,6 +403,17 @@ def test_new_invalid_name_raises(self):
with self.assertRaises(Exception):
obj.name = "This\ttab"

def test_construct_with_sloppy(self):
x, y, z, w = self.model.variables[:4]
obj = self.interface.Objective(
symbolics.add([symbolics.mul((symbolics.One, var)) for var in [x, y, z]]),
direction="min",
sloppy=True
)
self.model.objective = obj

self.assertTrue(obj.get_linear_coefficients([x, y, z, w]) == {x: 1, y: 1, z: 1, w: 0})


@six.add_metaclass(abc.ABCMeta)
class AbstractModelTestCase(unittest.TestCase):
Expand Down
16 changes: 12 additions & 4 deletions optlang/tests/test_expression_parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,18 @@ def test_parse_non_expanded_quadratic_expression(self):
target = {frozenset([x]): 1, frozenset([y]): 1, frozenset([x, y]): 2, frozenset([z]): -1}
linear_target = {z: 4}

offset_const, linear_terms_const, quad_terms_const = parse_optimization_expression(Constraint(expr, lb=0), quadratic=True)
offset_obj, linear_terms_obj, quad_terms_obj = parse_optimization_expression(Objective(expr), linear=False)

self.assertEqual(offset_const, -4)
constraint = Constraint(expr, lb=0)
offset_const, linear_terms_const, quad_terms_const = parse_optimization_expression(
constraint,
quadratic=True
)
offset_obj, linear_terms_obj, quad_terms_obj = parse_optimization_expression(
Objective(expr),
expression=expr,
linear=False
)

self.assertEqual(offset_const - constraint.lb, -4 + offset)
self.assertEqual(offset_obj, -4 + offset)
_compare_term_dicts(self, linear_terms_const, linear_target)
_compare_term_dicts(self, linear_terms_obj, linear_target)
Expand Down
4 changes: 2 additions & 2 deletions optlang/tests/test_symbolics.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
class SymbolicsTestCase(unittest.TestCase):

def test_add_identity(self):
self.assertEqual(optlang.symbolics.add(), 0)
self.assertEqual(optlang.symbolics.add(), 0.0)

def test_mul_identity(self):
self.assertEqual(optlang.symbolics.mul(), 1)
self.assertEqual(optlang.symbolics.mul(), 1.0)