Skip to content

Commit b748328

Browse files
authored
Merge pull request #2971 from mathgeekcoder/highspy-scalar-division
Added support for scalar division to highspy
2 parents e8c0584 + e898989 commit b748328

2 files changed

Lines changed: 65 additions & 0 deletions

File tree

highs/highspy/highs.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1701,6 +1701,15 @@ def __ge__(self, other: Union[float, int, highs_var, highs_linear_expression]):
17011701
else:
17021702
return highs_linear_expression(self).__ge__(other)
17031703

1704+
# self / scalar
1705+
def __truediv__(self, other: Union[float, int, highs_linear_expression]):
1706+
expr = highs_linear_expression(self)
1707+
expr /= other
1708+
return expr
1709+
1710+
# scalar / self
1711+
def __rtruediv__(self, other: Union[float, int, highs_linear_expression]):
1712+
raise Exception("Only division of a linear expression by a scalar is allowed.")
17041713

17051714
# highs constraint
17061715
class highs_cons(object):
@@ -2243,6 +2252,32 @@ def __isub__(self, other: Union[float, int, highs_var, highs_linear_expression])
22432252

22442253
self.constant = (self.constant or 0.0) - float(other)
22452254
return self
2255+
2256+
# expr / scalar
2257+
def __truediv__(self, other: Union[float, int, highs_linear_expression]):
2258+
copy = highs_linear_expression(self)
2259+
copy /= other
2260+
return copy
2261+
2262+
# expr /= scalar
2263+
def __itruediv__(self, other: Union[float, int, highs_linear_expression]):
2264+
if isinstance(other, (float, int)):
2265+
divisor = float(other)
2266+
2267+
elif isinstance(other, highs_linear_expression) and other.idxs == [] and other.constant is not None:
2268+
divisor = float(other.constant)
2269+
2270+
else:
2271+
raise Exception("Only division by a scalar is allowed.")
2272+
2273+
if divisor == 0:
2274+
raise ZeroDivisionError("division by zero")
2275+
2276+
return self.__imul__(1.0 / divisor)
2277+
2278+
# scalar / expr
2279+
def __rtruediv__(self, other: Union[float, int, highs_var, highs_linear_expression]):
2280+
raise Exception("Only division of a linear expression by a scalar is allowed.")
22462281

22472282
def __imul__(self, other: Union[float, int, highs_var, highs_linear_expression]):
22482283
if isinstance(other, (float, int)):

tests/test_highspy.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2043,6 +2043,36 @@ def test_multiply(self):
20432043
e1 *= x - 4 <= 3
20442044
self.assertEqualExpr(e1, [x], [1], None, [-self.h.inf, 7])
20452045

2046+
def test_divide(self):
2047+
x, y = self.x[0:2]
2048+
2049+
expr = x / 4
2050+
self.assertEqualExpr(expr, [x], [0.25])
2051+
2052+
expr = (x + 2 * y + 8) / 4
2053+
self.assertEqualExpr(expr, [x, y], [0.25, 0.5], 2)
2054+
2055+
expr = (4 <= x + 2 * y <= 8) / 2
2056+
self.assertEqualExpr(expr, [x, y], [0.5, 1], None, [2, 4])
2057+
2058+
expr = (x + 2 * y) / highs_linear_expression(4)
2059+
self.assertEqualExpr(expr, [x, y], [0.25, 0.5])
2060+
2061+
expr = x + 2 * y + 8
2062+
expr /= 4
2063+
self.assertEqualExpr(expr, [x, y], [0.25, 0.5], 2)
2064+
2065+
expr = 4 <= x + 2 * y <= 8
2066+
expr /= -2
2067+
self.assertEqualExpr(expr, [x, y], [-0.5, -1], None, [-4, -2])
2068+
2069+
self.assertRaises(Exception, lambda: x / y)
2070+
self.assertRaises(Exception, lambda: (x + y) / (x + 1))
2071+
self.assertRaises(Exception, lambda: 2 / x)
2072+
self.assertRaises(Exception, lambda: 2 / (x + y))
2073+
self.assertRaises(ZeroDivisionError, lambda: x / 0)
2074+
self.assertRaises(ZeroDivisionError, lambda: (x + y) / highs_linear_expression(0))
2075+
20462076
def test_simplify(self):
20472077
x, y, z = self.x[0:3]
20482078

0 commit comments

Comments
 (0)