Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- Removed `Py_INCREF`/`Py_DECREF` on `Model` in `catchEvent`/`dropEvent` that caused memory leak for imbalanced usage
- Used getIndex() instead of ptr() for sorting nonlinear expression terms to avoid nondeterministic behavior
### Changed
- Speed up `constant * Expr` via C-level API
### Removed
- Removed outdated warning about Make build system incompatibility

Expand Down
14 changes: 8 additions & 6 deletions src/pyscipopt/expr.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -289,22 +289,24 @@ cdef class Expr:
cdef PyObject *v2_ptr = NULL
cdef PyObject *old_v_ptr = NULL
cdef Term child
cdef double prod_v
cdef double coef

if _is_number(other):
f = float(other)
return Expr({v:f*c for v,c in self.terms.items()})
coef = float(other)
while PyDict_Next(self.terms, &pos1, &k1_ptr, &v1_ptr):
res[<Term>k1_ptr] = <double>(<object>v1_ptr) * coef
return Expr(res)

elif isinstance(other, Expr):
while PyDict_Next(self.terms, &pos1, &k1_ptr, &v1_ptr):
pos2 = <Py_ssize_t>0
while PyDict_Next(other.terms, &pos2, &k2_ptr, &v2_ptr):
child = (<Term>k1_ptr) * (<Term>k2_ptr)
prod_v = (<double>(<object>v1_ptr)) * (<double>(<object>v2_ptr))
coef = (<double>(<object>v1_ptr)) * (<double>(<object>v2_ptr))
if (old_v_ptr := PyDict_GetItem(res, child)) != NULL:
res[child] = <double>(<object>old_v_ptr) + prod_v
res[child] = <double>(<object>old_v_ptr) + coef
else:
res[child] = prod_v
res[child] = coef
return Expr(res)

elif isinstance(other, GenExpr):
Expand Down
5 changes: 5 additions & 0 deletions tests/test_expr.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,11 @@ def test_mul():
x = m.addVar(name="x")
y = m.addVar(name="y")

# test Expr * number
assert str((x + y) * 2.0) == "Expr({Term(x): 2.0, Term(y): 2.0})"
Comment thread
Zeroto521 marked this conversation as resolved.
assert str(2.0 * (x + y)) == "Expr({Term(x): 2.0, Term(y): 2.0})"

# test Expr * Expr
assert str(Expr({CONST: 1.0}) * x) == "Expr({Term(x): 1.0})"
assert str(y * Expr({CONST: -1.0})) == "Expr({Term(y): -1.0})"
assert str((x - x) * y) == "Expr({Term(x, y): 0.0})"
Expand Down
Loading