When using the @ operator in the objective function, it appears that the operator is not commutative for vectors, and that the objective is mutated silently. Specifically, right-multiplying a 1-d CyLPVar with a numpy.array or CyLPArray results in a zero objective function, while left-multiplying the variable/expression with the same vector results in expected, nonzero values.
Mathematically, I would not expect vector dot products to be non-commutative. If there is a mathematical reason for this (e.g. due to implicit shape assumptions) I would expect this to raise a shape error or warning.
I have not tested this with non-vector CyLPVars, CyLPExpressions, or confirmed behavior outside of the objective. Below is a simple test which replicates my observed behavior for a simple 2-D test case.
import numpy as np
import pytest
from cylp.cy import CyClpSimplex
from cylp.py.modeling import CyLPModel, CyLPArray
obj_vals = [-1,-2]
@pytest.mark.parametrize(
"test_name, obj",
[
("nparray", np.array(obj_vals)),
("CyLPArray", CyLPArray(obj_vals))
]
)
def test_objective_order(test_name, obj):
model = CyLPModel()
x = model.addVariable('x', 2)
model += 0 <= x <= 2
model.objective = x @ obj
if np.abs(model.objective).sum() == 0:
print("Objective is zero")
s = CyClpSimplex(model)
s.primal()
x1 = s.primalVariableSolution['x']
print(f"Initial solve for x: {x1}")
model.objective = obj @ x
if np.abs(model.objective).sum() > 0:
print("Objective is nonzero")
s = CyClpSimplex(model)
s.primal()
x2 = s.primalVariableSolution['x']
assert all(np.isclose(x1, x2)), "Different solutions for objectives with dot product commutation"
print(f"Second solve for x: {x2}")
When using the
@operator in the objective function, it appears that the operator is not commutative for vectors, and that the objective is mutated silently. Specifically, right-multiplying a 1-d CyLPVar with a numpy.array or CyLPArray results in a zero objective function, while left-multiplying the variable/expression with the same vector results in expected, nonzero values.Mathematically, I would not expect vector dot products to be non-commutative. If there is a mathematical reason for this (e.g. due to implicit shape assumptions) I would expect this to raise a shape error or warning.
I have not tested this with non-vector CyLPVars, CyLPExpressions, or confirmed behavior outside of the objective. Below is a simple test which replicates my observed behavior for a simple 2-D test case.