Skip to content

Dot product of two vectors / 1-d arrays not commutative (example shown in objective function) #230

@emunsing

Description

@emunsing

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}")

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions