Skip to content
Open
Show file tree
Hide file tree
Changes from all 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 @@ -15,6 +15,7 @@
- Replaced `format()` with f-strings in examples
- Refactor general expression conversion into per-class `to_scip_expr` recursion
- Made expression fields read-only to prevent accidental runtime modification
- Expression fields now use concrete Cython types (`double`/`list`), so values are converted on construction
- Methods taking a list of variables (e.g. `addConsKnapsack()`) no longer convert it to a NumPy array to check its dimension
- Speed up `PowExpr._evaluate` via the C-level API
- `PowExpr._evaluate` now raises `ValueError("math domain error")` for a negative base with a non-integer exponent and `OverflowError` when the result overflows.
Expand Down
19 changes: 9 additions & 10 deletions src/pyscipopt/expr.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ Operator = Op()
cdef class GenExpr(ExprLike):

cdef public _op
cdef readonly children
cdef readonly list children

def __init__(self): # do we need it
''' '''
Expand Down Expand Up @@ -756,7 +756,7 @@ cdef class GenExpr(ExprLike):
# Sum Expressions
cdef class SumExpr(GenExpr):

cdef readonly constant
cdef readonly double constant

def __init__(self):
self.constant = 0.0
Expand Down Expand Up @@ -810,7 +810,7 @@ cdef class SumExpr(GenExpr):
# Prod Expressions
cdef class ProdExpr(GenExpr):

cdef readonly constant
cdef readonly double constant

def __init__(self):
self.constant = 1.0
Expand Down Expand Up @@ -887,7 +887,7 @@ cdef class VarExpr(GenExpr):
# Pow Expressions
cdef class PowExpr(GenExpr):

cdef readonly expo
cdef readonly double expo

def __init__(self):
self.expo = 1.0
Expand All @@ -906,14 +906,13 @@ cdef class PowExpr(GenExpr):

cpdef double _evaluate(self, Solution sol) except *:
cdef double base = (<GenExpr>self.children[0])._evaluate(sol)
cdef double expo = <double>self.expo
if base == 0.0 and expo < 0:
if base == 0.0 and self.expo < 0:
raise ZeroDivisionError("0.0 cannot be raised to a negative power")
elif base < 0.0 and expo != c_floor(expo):
elif base < 0.0 and self.expo != c_floor(self.expo):
raise ValueError("math domain error")

cdef double res = c_pow(base, expo)
if c_fabs(res) == INFINITY and c_fabs(base) != INFINITY and c_fabs(expo) != INFINITY:
cdef double res = c_pow(base, self.expo)
if c_fabs(res) == INFINITY and c_fabs(base) != INFINITY and c_fabs(self.expo) != INFINITY:
raise OverflowError("math range error")
return res

Expand Down Expand Up @@ -1045,7 +1044,7 @@ cdef class CosExpr(UnaryExpr):

cdef class Constant(GenExpr):

cdef readonly number
cdef readonly double number

def __init__(self, number: Union[int, float]):
self.number = number
Expand Down
8 changes: 4 additions & 4 deletions src/pyscipopt/scip.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ class Conshdlr:
@disjoint_base
class Constant(GenExpr):
@property
def number(self) -> SupportsFloat: ...
def number(self) -> float: ...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

numebr is float now, not like float. SupportsFloat uses the __float__ protocol.

def __init__(self, number: SupportsFloat) -> None: ...
def __neg__(self, /) -> Constant: ...
def __pow__( # type: ignore[override]
Expand Down Expand Up @@ -2165,7 +2165,7 @@ class PY_SCIP_STATUS:
@disjoint_base
class PowExpr(GenExpr):
@property
def expo(self) -> SupportsFloat: ...
def expo(self) -> float: ...
def __init__(self) -> None: ...
def __neg__(self, /) -> ProdExpr: ...

Expand Down Expand Up @@ -2197,7 +2197,7 @@ class Pricer:
@disjoint_base
class ProdExpr(GenExpr):
@property
def constant(self) -> SupportsFloat: ...
def constant(self) -> float: ...
def __init__(self) -> None: ...
def __neg__(self, /) -> ProdExpr: ...

Expand Down Expand Up @@ -2397,7 +2397,7 @@ class Statistics:
@disjoint_base
class SumExpr(GenExpr):
@property
def constant(self) -> SupportsFloat: ...
def constant(self) -> float: ...
def __init__(self) -> None: ...
def __neg__(self, /) -> ProdExpr: ...

Expand Down
Loading
Loading