-
Notifications
You must be signed in to change notification settings - Fork 280
Speed up -SumExpr, -ProdExpr and -Constant
#1179
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
base: master
Are you sure you want to change the base?
Changes from 19 commits
28d3adc
1be74c8
e4351fa
fb9fcc8
f55c222
cb349ce
5896012
6387cfa
eac8db9
fecba06
02e32b5
bd280f6
2e97cc7
67ce45d
40945ad
ef034c4
86678e2
394c682
d348d48
b881b12
39c036c
3d2bff0
1c6598f
2b0cc32
70ef34e
05dd131
af2f83a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -45,9 +45,10 @@ | |
| import math | ||
| from typing import TYPE_CHECKING | ||
|
|
||
| from pyscipopt.scip cimport Variable, Solution | ||
| from cpython.dict cimport PyDict_Next | ||
| from cpython.dict cimport PyDict_Next, PyDict_SetItem | ||
| from cpython.object cimport Py_TYPE | ||
| from cpython.ref cimport PyObject | ||
| from pyscipopt.scip cimport Variable, Solution | ||
|
|
||
| import numpy as np | ||
|
|
||
|
|
@@ -308,8 +309,15 @@ cdef class Expr: | |
| else: | ||
| raise TypeError(f"Unsupported base type {type(other)} for exponentiation.") | ||
|
|
||
| def __neg__(self): | ||
| return Expr({v:-c for v,c in self.terms.items()}) | ||
| def __neg__(self) -> Expr: | ||
| cdef dict res = {} | ||
| cdef Py_ssize_t pos = <Py_ssize_t>0 | ||
| cdef PyObject* key_ptr | ||
| cdef PyObject* val_ptr | ||
|
|
||
| while PyDict_Next(self.terms, &pos, &key_ptr, &val_ptr): | ||
| PyDict_SetItem(res, <Term>key_ptr, -<double>(<object>val_ptr)) | ||
| return Expr(res) | ||
|
|
||
| def __sub__(self, other): | ||
| return self + (-other) | ||
|
|
@@ -659,14 +667,31 @@ cdef class SumExpr(GenExpr): | |
| self.coefs = [] | ||
| self.children = [] | ||
| self._op = Operator.add | ||
|
|
||
| def __neg__(self) -> SumExpr: | ||
| cdef int i = 0, n = len(self.coefs) | ||
| cdef list coefs = [0.0] * n | ||
| cdef double[:] dest_view = coefs | ||
| cdef double[:] src_view = self.coefs | ||
|
|
||
| for i in range(n): | ||
| dest_view[i] = -src_view[i] | ||
|
|
||
|
Comment on lines
+718
to
+724
|
||
| cdef SumExpr res = SumExpr.__new__(SumExpr) | ||
| res.coefs = coefs | ||
| res.children = self.children.copy() | ||
| res.constant = -self.constant | ||
| res._op = Operator.add | ||
| return res | ||
|
|
||
| def __repr__(self): | ||
| return self._op + "(" + str(self.constant) + "," + ",".join(map(lambda child : child.__repr__(), self.children)) + ")" | ||
|
|
||
| cpdef double _evaluate(self, Solution sol) except *: | ||
| cdef double res = self.constant | ||
| cdef int i = 0, n = len(self.children) | ||
| cdef list children = self.children | ||
| cdef list coefs = self.coefs | ||
| cdef double[:] coefs = self.coefs | ||
| for i in range(n): | ||
| res += <double>coefs[i] * (<GenExpr>children[i])._evaluate(sol) | ||
|
Comment on lines
737
to
741
|
||
| return res | ||
|
|
@@ -682,6 +707,13 @@ cdef class ProdExpr(GenExpr): | |
| self.children = [] | ||
| self._op = Operator.prod | ||
|
|
||
| def __neg__(self) -> ProdExpr: | ||
| cdef ProdExpr res = ProdExpr.__new__(ProdExpr) | ||
| res.constant = -res.constant | ||
|
Zeroto521 marked this conversation as resolved.
Outdated
|
||
| self.children = self.children.copy() | ||
|
Zeroto521 marked this conversation as resolved.
Outdated
|
||
| res._op = Operator.prod | ||
| return res | ||
|
|
||
| def __repr__(self): | ||
| return self._op + "(" + str(self.constant) + "," + ",".join(map(lambda child : child.__repr__(), self.children)) + ")" | ||
|
|
||
|
|
@@ -746,11 +778,16 @@ cdef class UnaryExpr(GenExpr): | |
|
|
||
| # class for constant expressions | ||
| cdef class Constant(GenExpr): | ||
|
|
||
| cdef public number | ||
|
|
||
| def __init__(self,number): | ||
| self.number = number | ||
| self._op = Operator.const | ||
|
|
||
| def __neg__(self): | ||
| return Constant(-self.number) | ||
|
|
||
| def __repr__(self): | ||
| return str(self.number) | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.