math#

class gamspy.math.Dim(dims: 'list[int]')[source]#

Bases: object

dims: list[int]#
class gamspy.math.MathOp(op_name: str, elements: tuple, *, safe_cancel: bool = False)[source]#

Bases: Operable

Represents a symbolic and numerical mathematical operation.

Parameters:
op_namestr

Name of the operation.

elementstuple

Arguments for the operation.

safe_cancelbool

Whether to allow square and square root to cancel each other.

Attributes:
records

Evaluates the expression and returns the resulting records.

Methods

gamsRepr()

Representation of this MathOp in GAMS.

latexRepr()

Representation of this MathOp in Latex.

toList()

Convenience method to return the records of the expression as a list.

toValue()

Convenience method to return expression records as a Python float.

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import Round, div
>>> m = Container()
>>> a = Parameter(m, "a", records=200)
>>> b = Parameter(m, "b")
>>> Round(div(a, 3), 2).toValue()
np.float64(66.67)
gamsRepr() str[source]#

Representation of this MathOp in GAMS.

Returns:
str

Examples

>>> import gamspy as gp
>>> m = gp.Container()
>>> a = gp.Parameter(m, "a", records=5)
>>> print(gp.math.div(a,5).gamsRepr())
div(a,5)
latexRepr() str[source]#

Representation of this MathOp in Latex.

Returns:
str

Examples

>>> import gamspy as gp
>>> m = gp.Container()
>>> a = gp.Parameter(m, "a", records=5)
>>> print(gp.math.div(a,5).latexRepr())
div(a,5)
toList() list | None[source]#

Convenience method to return the records of the expression as a list.

Returns:
list | None

Examples

>>> import numpy as np
>>> from gamspy import Container, Parameter, Set
>>> from gamspy.math import Round, div
>>> m = Container()
>>> i = Set(m, "i", records=["i1", "i2"])
>>> a = Parameter(m, "a", domain=i, records=np.array([200, 300]))
>>> Round(div(a, 3), 2).toList()
[['i1', 66.67], ['i2', 100.0]]
toValue() float | None[source]#

Convenience method to return expression records as a Python float. Only possible if there is a single record as a result of the expression evaluation.

Returns:
float | None
Raises:
TypeError

In case the dimension of the expression is not zero.

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import Round, div
>>> m = Container()
>>> a = Parameter(m, "a", records=200)
>>> b = Parameter(m, "b")
>>> Round(div(a, 3), 2).toValue()
np.float64(66.67)
property records: pd.DataFrame | None#

Evaluates the expression and returns the resulting records.

Returns:
pd.DataFrame | None

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import Round, div
>>> m = Container()
>>> a = Parameter(m, "a", records=200)
>>> b = Parameter(m, "b")
>>> Round(div(a, 3), 2).records
   value
0  66.67
gamspy.math.Max(*values) MathOp[source]#

Maximum value of the values, where the number of values may vary.

Returns:
MathOp

Examples

>>> from gamspy import Container, Set, Parameter
>>> from gamspy.math import Max
>>> m = Container()
>>> i = Set(m, name="i", records=["i1", "i2", "i3"])
>>> a = Parameter(m, "a", domain=i, records=[("i1", 2), ("i2", 0.3), ("i3", 2.5)])
>>> b = Parameter(m, "b", domain=i)
>>> b[i] = Max(a[i], 1)
>>> b.toList()
[('i1', 2.0), ('i2', 1.0), ('i3', 2.5)]
gamspy.math.Min(*values) MathOp[source]#

Minimum value of the values, where the number of values may vary.

Returns:
MathOp

Examples

>>> from gamspy import Container, Set, Parameter
>>> from gamspy.math import Min
>>> m = Container()
>>> i = Set(m, name="i", records=["i1", "i2", "i3"])
>>> a = Parameter(m, "a", domain=i, records=[("i1", -2), ("i2", 0.3), ("i3", 2)])
>>> b = Parameter(m, "b", domain=i)
>>> b[i] = Min(a[i], 1)
>>> b.toList()
[('i1', -2.0), ('i2', 0.3), ('i3', 1.0)]
gamspy.math.Round(x: OperableType, num_decimals: int = 0) MathOp[source]#

Round x to num_decimals decimal places (i.e. Round(3.14159, 2) returns 3.14)

Parameters:
xOperableType
num_decimalsint, optional
Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import Round, div
>>> m = Container()
>>> a = Parameter(m, "a", records=200)
>>> b = Parameter(m, "b")
>>> b[...] = Round(div(a, 3), 2)
>>> b.toValue()
np.float64(66.67)
gamspy.math.abs(x: OperableType) MathOp[source]#

Absolute value of x (i.e. |x|)

Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import abs
>>> m = Container()
>>> a = Parameter(m, "a", records=-3.8)
>>> b = Parameter(m, "b")
>>> b[...] = abs(a)
>>> b.toValue()
np.float64(3.8)
gamspy.math.acos(x: OperableType) MathOp[source]#

Inverse cosine of x.

Returns:
Expresion | float

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import acos
>>> m = Container()
>>> r = Parameter(m, "r")
>>> r[...] = acos(1)
>>> r.toValue()
np.float64(0.0)
gamspy.math.aggregate(source: Set | Alias | ImplicitSet | Parameter | ImplicitParameter, target: Parameter | ImplicitParameter, direction: Literal['right', 'left'] = 'right') None[source]#

Aggregates the elements of a source set into a target parameter.

Parameters:
sourceSet | Alias | ImplicitSet

The multi-dimensional source set.

targetParameter | ImplicitParameter

The target set to project into.

directionLiteral[“right”, “left”], optional

The direction of the permutation/projection if domains are ambiguous. Default is “right”.

Examples

>>> import gamspy as gp
>>> import gamspy.math as gmath
>>> m = gp.Container()
>>> i = gp.Set(m, "i", records=["i1", "i2"])
>>> j = gp.Set(m, "j", records=["j1", "j2"])
>>> k = gp.Set(m, "k", records=["k1", "k2", "k3"])
>>> ijk = gp.Set(m, "ijk", domain=[i, j, k])
>>> ijk[i, j, k] = True
>>> count_ij = gp.Parameter(m, "count_ij", domain=[i, j])
>>> gmath.aggregate(source=ijk[i, j, k], target=count_ij[i, j])
>>> count_ij.toList()
[('i1', 'j1', 3.0), ('i1', 'j2', 3.0), ('i2', 'j1', 3.0), ('i2', 'j2', 3.0)]
gamspy.math.asin(x: OperableType) MathOp[source]#

Inver sinus of x.

Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import asin
>>> m = Container()
>>> r = Parameter(m, "r")
>>> r[...] = asin(0)
>>> r.toValue()
np.float64(0.0)
gamspy.math.atan(x: OperableType) MathOp[source]#

Inverse tangent of x.

Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import atan
>>> m = Container()
>>> r = Parameter(m, "r")
>>> r[...] = atan(0)
>>> r.toValue()
np.float64(0.0)
gamspy.math.atan2(y: OperableType, x: OperableType) MathOp[source]#

Four-quadrant arctan function yielding arctan(y/x), which is the angle the vector (x,y) makes with (1,0) in radians.

Returns:
MathOp

Examples

>>> import math
>>> from gamspy import Container, Parameter
>>> from gamspy.math import atan2
>>> m = Container()
>>> r = Parameter(m, "r")
>>> r[...] = atan2(1,1)
>>> math.isclose(r.toValue(), 0.7853981633974483)
True
gamspy.math.beta(x: OperableType, y: OperableType) MathOp[source]#

Beta function: B(x, y) = gamma(x) * gamma(y) / gamma(x + y) = (x-1)! * (y-1)! / (x + y - 1)!

Parameters:
xOperableType
yOperableType
Returns:
MathOp

Examples

>>> import math
>>> from gamspy import Container, Parameter
>>> from gamspy.math import beta
>>> m = Container()
>>> a = Parameter(m, "a", records=3)
>>> b = Parameter(m, "b")
>>> b[...] = beta(a, 1)
>>> math.isclose(b.toValue(), 0.3333333333333333)
True
gamspy.math.binomial(n: OperableType, k: OperableType) MathOp[source]#

(Generalized) Binomial coefficient for n > -1 and -1 < k < n + 1

Parameters:
nOperableType
kOperableType
Returns:
MathOp

Examples

>>> from gamspy import Container, Set, Parameter
>>> from gamspy.math import binomial
>>> m = Container()
>>> i = Set(m, name="i", records=["i1", "i2", "i3"])
>>> p = Parameter(m, "p", domain=i, records=[("i1", 0.3), ("i2", 0.8), ("i3", 0.45)])
>>> b = Parameter(m, "b", domain=i)
>>> b[i] = binomial(75, p[i])
gamspy.math.bool_and(x: OperableType, y: OperableType) MathOp[source]#

Returns true iff both x and y are true

Parameters:
xOperableType
yOperableType
Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import bool_and
>>> m = Container()
>>> a = Parameter(m, "a", records=12)
>>> b = Parameter(m, "b", records=7)
>>> c = Parameter(m, "c")
>>> c[...] = bool_and(a > 10, b < 5)
>>> c.toValue()
np.float64(0.0)
gamspy.math.bool_eqv(x: OperableType, y: OperableType) MathOp[source]#

Returns false iff exactly one argument is false

Parameters:
xOperableType
yOperableType
Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import bool_eqv
>>> m = Container()
>>> a = Parameter(m, "a", records=12)
>>> b = Parameter(m, "b", records=7)
>>> c = Parameter(m, "c")
>>> c[...] = bool_eqv(a > 10, b < 5)
>>> c.toValue()
np.float64(0.0)
gamspy.math.bool_imp(x: OperableType, y: OperableType) MathOp[source]#

Returns true iff x is false or y is true

Parameters:
xOperableType
yOperableType
Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import bool_imp
>>> m = Container()
>>> a = Parameter(m, "a", records=12)
>>> b = Parameter(m, "b", records=7)
>>> c = Parameter(m, "c")
>>> c[...] = bool_imp(a < 10, b > 5)
>>> c.toValue()
np.float64(1.0)
gamspy.math.bool_not(x: OperableType) MathOp[source]#

Returns true iff x is false

Parameters:
xOperableType
Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import bool_not
>>> m = Container()
>>> a = Parameter(m, "a", records=12)
>>> b = Parameter(m, "b", records=7)
>>> c = Parameter(m, "c")
>>> c[...] = bool_not(a > 10)
>>> c.toValue()
np.float64(0.0)
gamspy.math.bool_or(x: OperableType, y: OperableType) MathOp[source]#

Returns true iff x is true or y is true

Parameters:
xOperableType
yOperableType
Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import bool_or
>>> m = Container()
>>> a = Parameter(m, "a", records=12)
>>> b = Parameter(m, "b", records=7)
>>> c = Parameter(m, "c")
>>> c[...] = bool_or(a > 15, b < 5)
>>> c.toValue()
np.float64(0.0)
gamspy.math.bool_xor(x: OperableType, y: OperableType) MathOp[source]#

Returns true iff exactly one argument is false

Parameters:
xOperableType
yOperableType
Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import bool_xor
>>> m = Container()
>>> a = Parameter(m, "a", records=12)
>>> b = Parameter(m, "b", records=7)
>>> c = Parameter(m, "c")
>>> c[...] = bool_xor(a < 15, b > 5)
>>> c.toValue()
np.float64(0.0)
gamspy.math.ceil(x: OperableType) MathOp[source]#

The smallest integer greater than or equal to x (i.e. ceil(4.1) returns 5)

Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import ceil
>>> m = Container()
>>> a = Parameter(m, "a", records=3.2)
>>> b = Parameter(m, "b")
>>> b[...] = ceil(a)
>>> b.toValue()
np.float64(4.0)
gamspy.math.centropy(x: OperableType, y: OperableType, z: float = 1e-20) MathOp[source]#

Cross-entropy: x.ln((x + z) / (y + z)) for x, y > 0 and z >= 0

Parameters:
xOperableType
yOperableType
zfloat, optional
Returns:
MathOp
Raises:
ValueError

if z is smaller than 0

Examples

>>> from gamspy import Container, Set, Parameter
>>> from gamspy.math import centropy
>>> m = Container()
>>> i = Set(m, name="i", records=["i1", "i2", "i3"])
>>> x = Parameter(m, "x", domain=i, records=[("i1", 0.3), ("i2", 8), ("i3", 45)])
>>> b = Parameter(m, "b", domain=i)
>>> b[i] = centropy(2.8, x[i])
>>> b.toList()
[('i1', 6.254058220219863), ('i2', -2.939501948596297), ('i3', -7.775720603249651)]
gamspy.math.cos(x: OperableType) MathOp[source]#

Cosine of x.

Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import cos
>>> import numpy as np
>>> m = Container()
>>> r = Parameter(m, "r")
>>> r[...] = cos(np.pi)
>>> r.toValue()
np.float64(-1.0)
gamspy.math.cosh(x: OperableType) MathOp[source]#

Hyperbolic cosine of x.

Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import cosh
>>> m = Container()
>>> r = Parameter(m, "r")
>>> r[...] = cosh(0)
>>> r.toValue()
np.float64(1.0)
gamspy.math.cv_power(base: float, exponent: OperableType) MathOp[source]#

Real power (i.e. base ^ exponent where base >= 0; error for base < 0)

Parameters:
basefloat
exponentOperableType
Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import cv_power
>>> m = Container()
>>> a = Parameter(m, "a", records=4)
>>> b = Parameter(m, "b")
>>> b[...] = cv_power(3, a)
gamspy.math.dim(dims: list[int] | tuple[int, ...]) Dim[source]#

Returns an array where each element corresponds to a set where the dimension of the set is equal to the element in dims. If same dimension size used, then next free alias will be returned. Symbols are generated once the Dim object is passed to a constructor that supports it.

Parameters:
dims: list[int] | tuple[int, …]
Returns:
Dim

Examples

>>> import gamspy as gp
>>> import math
>>> m = gp.Container()
>>> a = gp.math.dim([10, 20]) # nothing generated yet
>>> a
Dim(dims=[10, 20])
>>> par = gp.Parameter(m, name="par", domain=a) # now two sets are generated
>>> par.domain
[Set(name='DenseDim10_1', domain=['*']), Set(name='DenseDim20_1', domain=['*'])]
>>> par2 = gp.Parameter(m, name="par2", domain=a) # same 2 sets are used
>>> par2.domain
[Set(name='DenseDim10_1', domain=['*']), Set(name='DenseDim20_1', domain=['*'])]
gamspy.math.dist(x1: OperableType, x2: OperableType) MathOp[source]#

Euclidean or L-2 Norm: sqrt(x1^2 + x2^2 + ... + xn^2)

Returns:
MathOp
Raises:
Exception

In case both x1 and x2 are not a tuple or none.

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import dist
>>> m = Container()
>>> a = Parameter(m, "a", records=210)
>>> b = Parameter(m, "b")
>>> b[...] = dist(a, 100)
gamspy.math.div(dividend: OperableType, divisor: OperableType) MathOp[source]#

Dividing operation, Error if the divisor is 0. To avoid the error, div0 can be used instead.

Parameters:
dividendOperableType
divisorOperableType
Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import div
>>> m = Container()
>>> a = Parameter(m, "a", records=210)
>>> b = Parameter(m, "b")
>>> b[...] = div(a, 3)
>>> b.toValue()
np.float64(70.0)
gamspy.math.div0(dividend: OperableType, divisor: OperableType) MathOp[source]#

Dividing operation, returns 1e+299 if the divisor is 0

Parameters:
dividendOperableType
divisorOperableType
Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import div0
>>> m = Container()
>>> a = Parameter(m, "a", records=210)
>>> b = Parameter(m, "b")
>>> b[...] = div0(a, 0)
>>> b.toValue()
np.float64(1e+299)
gamspy.math.entropy(x: OperableType) MathOp[source]#

Entropy function: -x*ln(x) where x >= 0

Parameters:
xOperableType
Returns:
MathOp

Examples

>>> from gamspy import Container, Set, Parameter
>>> from gamspy.math import entropy
>>> m = Container()
>>> i = Set(m, name="i", records=["i1", "i2", "i3"])
>>> a = Parameter(m, "a", domain=i, records=[("i1", 1), ("i2", 0.8), ("i3", 15)])
>>> b = Parameter(m, "b", domain=i)
>>> b[i] = entropy(a[i])
gamspy.math.errorf(x: OperableType) MathOp[source]#

Integral of the standard normal distribution from negative infinity to x

Parameters:
xint, float, Symbol
Returns:
MathOp

Examples

>>> from gamspy import Container, Set, Parameter
>>> from gamspy.math import errorf
>>> m = Container()
>>> i = Set(m, name="i", records=["i1", "i2", "i3"])
>>> a = Parameter(m, "a", domain=i, records=[("i1", -2.5), ("i2", 0.8), ("i3", 1.7)])
>>> b = Parameter(m, "b", domain=i)
>>> b[i] = errorf(a[i])
gamspy.math.exp(x: OperableType) MathOp[source]#

Exponential of x (i.e. e^x)

Parameters:
xOperableType
Returns:
MathOp

Examples

>>> import math
>>> from gamspy import Container, Parameter
>>> from gamspy.math import exp
>>> m = Container()
>>> a = Parameter(m, "a", records=3.8)
>>> b = Parameter(m, "b")
>>> b[...] = exp(a)
>>> math.isclose(b.toValue(), 44.701184493300815)
True
gamspy.math.factorial(x: int) MathOp[source]#

Factorial of x: x!

Parameters:
xint
Returns:
MathOp

Examples

>>> from gamspy import Container, Set, Parameter
>>> from gamspy.math import factorial
>>> m = Container()
>>> b = Parameter(m, "b")
>>> b[...] = factorial(2)
gamspy.math.floor(x: OperableType) MathOp[source]#

The greatest integer less than or equal to x (i.e. floor(4.9) returns 4)

Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import floor
>>> m = Container()
>>> a = Parameter(m, "a", records=3.9)
>>> b = Parameter(m, "b")
>>> b[...] = floor(a)
>>> b.toValue()
np.float64(3.0)
gamspy.math.fractional(x: OperableType) MathOp[source]#

Returns the fractional part of x (i.e. fractional(3.9) returns 0.9)

Returns:
MathOp

Examples

>>> import math
>>> from gamspy import Container, Parameter
>>> from gamspy.math import fractional
>>> m = Container()
>>> a = Parameter(m, "a", records=3.9)
>>> b = Parameter(m, "b")
>>> b[...] = fractional(a)
>>> math.isclose(b.toValue(), 0.8999999999999999)
True
gamspy.math.gamma(x: OperableType) MathOp[source]#

Gamma function: gamma(x) = (x-1)!

Parameters:
xint | float
Returns:
MathOp

Examples

>>> from gamspy import Container, Set, Parameter
>>> from gamspy.math import gamma
>>> m = Container()
>>> i = Set(m, name="i", records=["i1", "i2", "i3"])
>>> a = Parameter(m, "a", domain=i, records=[("i1", 4), ("i2", 7), ("i3", 0.5)])
>>> b = Parameter(m, "b", domain=i)
>>> b[i] = gamma(a[i])
gamspy.math.gelu(x: Parameter | Variable | implicits.ImplicitParameter | implicits.ImplicitVariable | Expression | Operation) tuple[Variable, list[Equation]][source]#

Implements the Gaussian Error Linear Unit (GELU) activation function. The GELU function is defined as GELU(x) = x * CDF(x), where CDF is the cumulative distribution function of the Gaussian distribution. It uses the intrinsic errorf function to compute the CDF. This implementation generates one variable, which serves as the activation variable and an equation. The activation variable shares the same domain as the input.

Returns the activation variable and the equation list.

Parameters:
xParameter | Variable | implicits.ImplicitParameter | implicits.ImplicitVariable | Expression | Operation
Returns:
tuple[Variable, list[Equation]]

Examples

>>> from gamspy import Container, Variable
>>> from gamspy.math import dim
>>> from gamspy.math.activation import gelu
>>> m = Container()
>>> x = Variable(m, "x", domain=dim([2,3,4]))
>>> y, eqs = gelu(x)
>>> y.domain
[Set(name='DenseDim2_1', domain=['*']), Set(name='DenseDim3_1', domain=['*']), Set(name='DenseDim4_1', domain=['*'])]
gamspy.math.ifthen(condition: Expression, yes_return: float | Expression, no_return: float | Expression) MathOp[source]#

If the logical condition is true, the function returns yes_return, else it returns no_return

Parameters:
conditionExpression
yes_returnfloat | Expression
no_returnfloat | Expression
Returns:
MathOp

Examples

>>> from gamspy.math import ifthen
>>> import gamspy as gp
>>> m = gp.Container()
>>> tt = gp.Parameter(m, "tt", records=2)
>>> y = gp.Parameter(m, "y", records=2)
>>> x = ifthen(tt == 2, 3, 4 + y)
gamspy.math.leaky_relu_with_binary_var(x: Parameter | Variable | implicits.ImplicitParameter | implicits.ImplicitVariable | Expression | Operation, negative_slope: float, default_lb: float = -1000000, default_ub: float = 1000000, *, return_binary_var: bool = False)[source]#

Implements the LeakyReLU activation function using binary variables. The LeakyReLU function is defined as LeakyReLU(x, negative_slope) = max(x, 0) + negative_slope * min(0, x). This implementation generates one binary variable, one output variable and four equations. The binary variable is necessary to represent the mathematical relationship, while the output variable serves as the activation variable. Both the binary and ouput variables share the same domain as the input.

The formulation of this function requires having lower and upper bounds for the input x. This function utilizes the bounds from the variables if provided. If not, it defaults to the bounds defined by default_lb and default_ub. Providing tighter and correct bounds can enhance the quality of linear relaxations.

Returns the activation variable and the equation list if return_binary_var is False, otherwise returns activation, binary variable and equation list in order.

Parameters:
xParameter | Variable | implicits.ImplicitParameter | implicits.ImplicitVariable | Expression | Operation
negative_slope: float
default_ubfloat
default_lbfloat
return_binary_var: bool
Returns:
tuple[Variable, list[Equation]] | tuple[Variable, Variable, list[Equation]]

Examples

>>> from gamspy import Container, Variable, Set
>>> from gamspy.math.activation import leaky_relu_with_binary_var
>>> m = Container()
>>> i = Set(m, "i", records=range(3))
>>> x = Variable(m, "x", domain=[i])
>>> y, eqs = leaky_relu_with_binary_var(x, 0.01)
>>> len(eqs)
4
>>> y, b, eqs = leaky_relu_with_binary_var(x, 0.01, return_binary_var=True)
>>> b.type
'binary'
>>> y.domain # i many activation variables
[Set(name='i', domain=['*'])]
>>> b.domain # i many binary variables
[Set(name='i', domain=['*'])]
gamspy.math.log(x: OperableType) MathOp[source]#

Natural logarithm of x (i.e. logarithm base e of x)

Parameters:
xOperableType
Returns:
MathOp

Examples

>>> import math
>>> from gamspy import Container, Parameter
>>> from gamspy.math import log
>>> m = Container()
>>> a = Parameter(m, "a", records=3.8)
>>> b = Parameter(m, "b")
>>> b[...] = log(a)
>>> math.isclose(b.toValue(), 1.33500106673234)
True
gamspy.math.log10(x: OperableType) MathOp[source]#

Common logarithm (i.e. logarithm base 10 of x)

Parameters:
xOperableType
Returns:
MathOp

Examples

>>> import math
>>> from gamspy import Container, Parameter
>>> from gamspy.math import log10
>>> m = Container()
>>> a = Parameter(m, "a", records=3.8)
>>> b = Parameter(m, "b")
>>> b[...] = log10(a)
>>> math.isclose(b.toValue(), 0.5797835966168101)
True
gamspy.math.log2(x: OperableType) MathOp[source]#

Binary logarithm (i.e. logarithm base 2 of x)

Parameters:
xOperableType
Returns:
MathOp

Examples

>>> import math
>>> from gamspy import Container, Parameter
>>> from gamspy.math import log2
>>> m = Container()
>>> a = Parameter(m, "a", records=3.8)
>>> b = Parameter(m, "b")
>>> b[...] = log2(a)
>>> math.isclose(b.toValue(), 1.9259994185562224)
True
gamspy.math.log_beta(x: OperableType, y: OperableType) MathOp[source]#

Log beta function (i.e. log(B(x, y))

Parameters:
xOperableType
yOperableType
Returns:
MathOp

Examples

>>> import math
>>> from gamspy import Container, Parameter
>>> from gamspy.math import log_beta
>>> m = Container()
>>> a = Parameter(m, "a", records=3.8)
>>> b = Parameter(m, "b")
>>> b[...] = log_beta(a,5)
>>> math.isclose(b.toValue(), -5.45446741772822)
True
gamspy.math.log_gamma(x: OperableType) MathOp[source]#

Log gamma function of x

Parameters:
xOperableType
Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import log_gamma
>>> m = Container()
>>> a = Parameter(m, "a", records=3.8)
>>> b = Parameter(m, "b")
>>> b[...] = log_gamma(a)
gamspy.math.log_softmax(x: Variable, dim: int = -1, *, skip_intrinsic: bool = False)[source]#

Implements the log_softmax activation function. This function strictly requires a GAMSPy Variable, y = log_softmax(x). The dim parameter specifies the index of the softmax dimension. If not provided, it calculates log_softmax for the last dimension. This function is preferred over the softmax function because, when the softmax dimension has 20 or fewer elements, it uses the lse_max (log-sum-exp) intrinsic function for improved numerical stability which usually leads to faster solve times. Some solvers do not support lse_max, in that case you can set skip_intrinsic parameter to True to not use intrinsic functions even when possible.

To learn more about Log-Sum-Exp trick .

This function is usually combined with Negative Log Likelihood loss for classification problems.

Returns the activation variable and the equation list.

Parameters:
xVariable
dimint
skip_intrinsic: bool
Returns:
Variable, list[Equation]

Examples

>>> from gamspy import Container, Variable
>>> from gamspy.math import dim
>>> from gamspy.math.activation import log_softmax
>>> m = Container()
>>> x = Variable(m, "x", domain=dim([500, 10]))
>>> y, eqs1 = log_softmax(x) # uses LSE because 10 <= 20
>>> y.domain
[Set(name='DenseDim500_1', domain=['*']), Set(name='DenseDim10_1', domain=['*'])]
>>> y2, eqs2 = log_softmax(x, dim=0) # cannot use LSE because 500 > 20
>>> y3, eqs3 = log_softmax(x, skip_intrinsic=True) # don't use LSE because of skip_intrinsic
gamspy.math.logit(x: OperableType) MathOp[source]#

Logit Transformation (i.e. log(x / (1 - x))) for x in (0, 1)

Parameters:
xOperableType
Returns:
MathOp

Examples

>>> import math
>>> from gamspy import Container, Parameter
>>> from gamspy.math import logit
>>> m = Container()
>>> a = Parameter(m, "a", records=0.8)
>>> b = Parameter(m, "b")
>>> b[...] = logit(a)
>>> math.isclose(b.toValue(), 1.3862943611198908)
True
gamspy.math.lse_max(*xs) MathOp[source]#

Smoothed Max via the Logarithm of the Sum of Exponentials: ln(exp(x1) + exp(x2) + ... + exp(xn))

Returns:
MathOp

Examples

>>> from gamspy import Container, Set, Parameter
>>> from gamspy.math import lse_max
>>> m = Container()
>>> i = Set(m, name="i", records=["i1", "i2", "i3"])
>>> a = Parameter(m, "a", domain=i, records=[("i1", 4), ("i2", 10), ("i3", 0.5)])
>>> b = Parameter(m, "b", domain=i)
>>> b[i] = lse_max(a[i], 5)
gamspy.math.lse_max_sc(t, *xs) MathOp[source]#

Scaled smoothed Max via the Logarithm of the Sum of Exponentials: lse_max_sc(T,x) = lse_max(Tx)/T

Returns:
MathOp

Examples

>>> from gamspy import Container, Set, Parameter
>>> from gamspy.math import lse_max_sc
>>> m = Container()
>>> i = Set(m, name="i", records=["i1", "i2", "i3"])
>>> a = Parameter(m, "a", domain=i, records=[("i1", 4), ("i2", 100), ("i3", 0.5)])
>>> b = Parameter(m, "b", domain=i)
>>> b[i] = lse_max_sc(7.5, a[i], 10.5)
gamspy.math.lse_min(*xs) MathOp[source]#

Smoothed Min via the Logarithm of the Sum of Exponentials: -ln(exp(-x1) + exp(-x2) + ... + exp(-xn))

Returns:
MathOp

Examples

>>> from gamspy import Container, Set, Parameter
>>> from gamspy.math import lse_min
>>> m = Container()
>>> i = Set(m, name="i", records=["i1", "i2", "i3"])
>>> a = Parameter(m, "a", domain=i, records=[("i1", 4), ("i2", 10), ("i3", 0.5)])
>>> b = Parameter(m, "b", domain=i)
>>> b[i] = lse_min(a[i], 5)
gamspy.math.lse_min_sc(t, *xs) MathOp[source]#

Scaled smoothed Min via the Logarithm of the Sum of Exponentials: lse_min_sc(T,x) = lse_min(Tx)/T

Returns:
MathOp

Examples

>>> from gamspy import Container, Set, Parameter
>>> from gamspy.math import lse_min_sc
>>> m = Container()
>>> i = Set(m, name="i", records=["i1", "i2", "i3"])
>>> a = Parameter(m, "a", domain=i, records=[("i1", 4), ("i2", 100), ("i3", 0.5)])
>>> b = Parameter(m, "b", domain=i)
>>> b[i] = lse_min_sc(7.5, a[i], 10.5)
>>> b.toList()
[('i1', 4.0), ('i2', 10.5), ('i3', 0.5)]
gamspy.math.map_value(x: OperableType) MathOp[source]#

Returns an integer value that indicates what special value (if any) is stored in the input. Possible results: 0: is not a special value 4: is UNDF (undefined) 5: is NA (not available) 6: is INF 7: is -INF 8: is EPS

Parameters:
xOperableType
Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import map_value
>>> m = Container()
>>> a = Parameter(m, "a", records=12)
>>> b = Parameter(m, "b")
>>> b[...] = map_value(a)
>>> b.toValue()
np.float64(0.0)
>>> a[...] = float('inf')
>>> b[...] = map_value(a)
>>> b.toValue()
np.float64(6.0)
gamspy.math.mod(x: OperableType, y: OperableType) MathOp[source]#

Remainder of x divided by y (i.e. mod(10, 3) returns 1)

Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import mod
>>> m = Container()
>>> a = Parameter(m, "a", records=200)
>>> b = Parameter(m, "b")
>>> b[...] = mod(a, 3)
>>> b.toValue()
np.float64(2.0)
gamspy.math.ncpVUpow(r: SymbolType, s: SymbolType, mu: int | float = 0) MathOp[source]#

NCP Veelken-Ulbrich (smoothed min(r,s))

Parameters:
rSymbolType
sSymbolType
muint | float, optional
Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import ncpVUpow
>>> m = Container()
>>> y = Parameter(m, "y", records=2)
>>> b = Parameter(m, "b")
>>> b[...] = ncpVUpow(1, y, 0.5)
>>> b.toValue()
np.float64(1.0)
gamspy.math.ncpVUsin(r: SymbolType, s: SymbolType, mu: int | float = 0) MathOp[source]#

NCP Veelken-Ulbrich (smoothed min(r,s))

Parameters:
rSymbolType
sSymbolType
muint | float, optional
Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import ncpVUsin
>>> m = Container()
>>> y = Parameter(m, "y", records=2)
>>> b = Parameter(m, "b")
>>> b[...] = ncpVUsin(1, y, 0.5)
>>> b.toValue()
np.float64(1.0)
gamspy.math.ncp_cm(x: SymbolType, y: SymbolType, z: float | int) MathOp[source]#

Chen-Mangasarian smoothing: x - z*ln(1 + exp((x-y)/z))

Parameters:
xSymbolType
ySymbolType
zint | float
Returns:
MathOp

Examples

>>> import math
>>> from gamspy import Container, Parameter
>>> from gamspy.math import ncp_cm
>>> m = Container()
>>> y = Parameter(m, "y", records=2)
>>> b = Parameter(m, "b")
>>> b[...] = ncp_cm(1, y, 0.5)
>>> math.isclose(b.toValue(), 0.9365359944785137)
True
gamspy.math.ncp_f(x: SymbolType, y: SymbolType, z: int | float = 0) MathOp[source]#

Fisher-Burmeister smoothing: sqrt(x^2 + y^2 + 2z) - x - y where z >= 0 (default z = 0)

Parameters:
xSymbolType
ySymbolType
zint | float, optional
Returns:
MathOp

Examples

>>> import math
>>> from gamspy import Container, Parameter
>>> from gamspy.math import ncp_f
>>> m = Container()
>>> y = Parameter(m, "y", records=2)
>>> b = Parameter(m, "b")
>>> b[...] = ncp_f(1, y, 0.5)
>>> math.isclose(b.toValue(), -0.5505102572168221)
True
gamspy.math.next_alias(symbol: Alias | Set) Alias[source]#

Provided the set or alias, it returns the next alias. If it is not found, it creates the alias. This function is mainly for matrix multiplication conflict resolution but it might be helpful in the cases where you need to generate many aliases from a set.

Parameters:
symbolSet | Alias
Returns:
Alias

Examples

>>> import gamspy as gp
>>> m = gp.Container()
>>> i = gp.Set(m, name="i", records=["i1", "i2", "i3"])
>>> j = gp.math.next_alias(i)
>>> j.name
'AliasOfi_2'
>>> k = gp.math._generate_dims(m, [10])[0]
>>> k.name
'DenseDim10_1'
>>> k2 = gp.math.next_alias(k)
>>> k2.name
'DenseDim10_2'
gamspy.math.normal(mean: int | float, dev: int | float) MathOp[source]#

Generate a random number from the normal distribution with mean mean and standard deviation dev

Parameters:
meanint | float
devint | float
Returns:
MathOp

Examples

>>> from gamspy import Container, Set, Parameter
>>> from gamspy.math import normal
>>> m = Container()
>>> i = Set(m, name="i", records=["i1", "i2", "i3"])
>>> x = Parameter(m, "x", domain=i, records=[("i1", 30), ("i2", 8), ("i3", 45)])
>>> b = Parameter(m, "b", domain=i)
>>> b[i] = normal(x[i], 5)
gamspy.math.permute(x: Parameter | ImplicitParameter | Variable | ImplicitVariable, dims: list[int]) ImplicitVariable | ImplicitParameter[source]#

Permutes the dimensions provided input x using dim. Similar to PyTorch permute.

Parameters:
x: (

Parameter | implicits.ImplicitParameter | Variable | implicits.ImplicitVariable

)
dims: list[int]
Returns:
implicits.ImplicitVariable | implicits.ImplicitParameter

Examples

>>> import gamspy as gp
>>> m = gp.Container()
>>> i = gp.Set(m, name="i")
>>> j = gp.Set(m, name="j")
>>> k = gp.Set(m, name="k")
>>> p = gp.Parameter(m, name="p", domain=[i, j, k])
>>> p2 = gp.math.permute(p, [2, 0, 1])
>>> p2.domain
[Set(name='k', domain=['*']), Set(name='i', domain=['*']), Set(name='j', domain=['*'])]
gamspy.math.poly(x, *args) MathOp[source]#

Polynomial function: p(x) = A[0] + A[1]*x + A[2]*x^2 + ... + A[n-1]*x^(n-1)

Returns:
MathOp
Raises:
ValidationError

If the number of arguments (args) is less than 3 or if any of args is not an integer or a float.

Examples

>>> from gamspy import Container, Set, Parameter
>>> from gamspy.math import poly
>>> m = Container()
>>> i = Set(m, name="i", records=["i1", "i2", "i3"])
>>> a = Parameter(m, "a", domain=i, records=[("i1", 4), ("i2", 10), ("i3", 0.5)])
>>> b = Parameter(m, "b", domain=i)
>>> b[i] = poly(a[i], 15, 3, 4)
>>> b.toList()
[('i1', 91.0), ('i2', 445.0), ('i3', 17.5)]
gamspy.math.power(base: float | Operable, exponent: OperableType) MathOp[source]#

Base to the exponent power (i.e. base ^ exponent)

Parameters:
baseOperableType
exponentOperableType
Returns:
MathOp

Examples

>>> import math
>>> from gamspy import Container, Parameter
>>> from gamspy.math import power
>>> m = Container()
>>> a = Parameter(m, "a", records=3.8)
>>> b = Parameter(m, "b")
>>> b[...] = power(a, 3)
>>> math.isclose(b.toValue(), 54.87199999999999)
True
gamspy.math.project(source: Set | Alias | ImplicitSet | Parameter | ImplicitParameter, target: Set | Alias | ImplicitSet, direction: Literal['right', 'left'] = 'right') None[source]#

Projects the dimensions of a source set onto a target set.

Parameters:
sourceSet | Alias | ImplicitSet | Parameter | ImplicitParameter

The multi-dimensional source set.

targetSet | Alias | ImplicitSet

The target set to project into.

directionLiteral[“right”, “left”], optional

The direction of the permutation/projection if domains are ambiguous. Default is “right”.

Examples

>>> import gamspy as gp
>>> import gamspy.math as gmath
>>> m = gp.Container()
>>> i = gp.Set(m, "i", records=["i1", "i2"])
>>> j = gp.Set(m, "j", records=["j1", "j2"])
>>> k = gp.Set(m, "k", records=["k1", "k2"])
>>> ijk = gp.Set(m, "ijk", domain=[i, j, k])
>>> ijk[i, j, k] = True
>>> ij = gp.Set(m, "ij", domain=[i, j])
>>> gmath.project(source=ijk[i, j, k], target=ij[i, j])
>>> ij.toList()
[('i1', 'j1'), ('i1', 'j2'), ('i2', 'j1'), ('i2', 'j2')]
gamspy.math.rand_binomial(n: int | float, p: int | float) MathOp[source]#

Generate a random number from the binomial distribution, where n is the number of trials and p the probability of success for each trial

Parameters:
nint | float
pint | float
Returns:
MathOp

Examples

>>> from gamspy import Container, Set, Parameter
>>> from gamspy.math import rand_binomial
>>> m = Container()
>>> i = Set(m, name="i", records=["i1", "i2", "i3"])
>>> p = Parameter(m, "p", domain=i, records=[("i1", 0.3), ("i2", 0.8), ("i3", 0.45)])
>>> b = Parameter(m, "b", domain=i)
>>> b[i] = rand_binomial(75, p[i])
>>> b.toList()
[('i1', 21.0), ('i2', 63.0), ('i3', 25.0)]
gamspy.math.rand_linear(low: int | float, slope: int | float, high: int | float) MathOp[source]#

Generate a random number between low and high with linear distribution. slope must be less than 2 / (high - low) and greater than 0

Parameters:
lowint | float
slopeint | float
highint | float
Returns:
MathOp

Examples

>>> from gamspy import Container, Set, Parameter
>>> from gamspy.math import rand_linear
>>> m = Container()
>>> i = Set(m, name="i", records=["i1", "i2", "i3"])
>>> s = Parameter(m, "s", domain=i, records=[("i1", 0.03), ("i2", 0.008), ("i3", 0.04)])
>>> b = Parameter(m, "b", domain=i)
>>> b[i] = rand_linear(75, s[i], 125)
gamspy.math.rand_triangle(low: int | float, mid: int | float, high: int | float) MathOp[source]#

Generate a random number between low and high with triangular distribution. mid is the most probable number.

Parameters:
lowint | float
midint | float
highint | float
Returns:
MathOp

Examples

>>> from gamspy import Container, Set, Parameter
>>> from gamspy.math import rand_triangle
>>> m = Container()
>>> i = Set(m, name="i", records=["i1", "i2", "i3"])
>>> s = Parameter(m, "s", domain=i, records=[("i1", 103), ("i2", 80), ("i3", 115)])
>>> b = Parameter(m, "b", domain=i)
>>> b[i] = rand_triangle(75, s[i], 125)
gamspy.math.regularized_beta(x: int | float, y: int | float, z: int | float) MathOp[source]#

Regularized Beta Function, See MathWorld

Parameters:
xint | float
yint | float
zint | float
Returns:
MathOp

Examples

>>> import math
>>> from gamspy import Container, Parameter
>>> from gamspy.math import regularized_beta
>>> m = Container()
>>> a = Parameter(m, "a", records=3)
>>> b = Parameter(m, "b")
>>> b[...] = regularized_beta(0.5, a, 1)
>>> math.isclose(b.toValue(), 0.12500000000000003)
True
gamspy.math.regularized_gamma(x: int | float, a: int | float) MathOp[source]#

Lower Incomplete Regularized Gamma function, See MathWorld

Parameters:
xint | float
aint | float
Returns:
MathOp

Examples

>>> from gamspy import Container, Set, Parameter
>>> from gamspy.math import regularized_gamma
>>> m = Container()
>>> i = Set(m, name="i", records=["i1", "i2", "i3"])
>>> a = Parameter(m, "a", domain=i, records=[("i1", 4), ("i2", 1), ("i3", 0.5)])
>>> b = Parameter(m, "b", domain=i)
>>> b[i] = regularized_gamma(0.5, a[i])
gamspy.math.rel_eq(x: OperableType, y: OperableType) MathOp[source]#

Returns true iff x == y

Parameters:
xOperableType
yOperableType
Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import rel_eq
>>> m = Container()
>>> a = Parameter(m, "a", records=12)
>>> b = Parameter(m, "b", records=7)
>>> c = Parameter(m, "c")
>>> c[...] = rel_eq(a, b)
>>> c.toValue()
np.float64(0.0)
gamspy.math.rel_ge(x: OperableType, y: OperableType) MathOp[source]#

Returns true iff x >= y

Parameters:
xOperableType
yOperableType
Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import rel_ge
>>> m = Container()
>>> a = Parameter(m, "a", records=12)
>>> b = Parameter(m, "b", records=7)
>>> c = Parameter(m, "c")
>>> c[...] = rel_ge(a, b)
>>> c.toValue()
np.float64(1.0)
gamspy.math.rel_gt(x: OperableType, y: OperableType) MathOp[source]#

Returns true iff x > y

Parameters:
xOperableType
yOperableType
Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import rel_gt
>>> m = Container()
>>> a = Parameter(m, "a", records=7)
>>> b = Parameter(m, "b", records=7)
>>> c = Parameter(m, "c")
>>> c[...] = rel_gt(a, b)
>>> c.toValue()
np.float64(0.0)
gamspy.math.rel_le(x: OperableType, y: OperableType) MathOp[source]#

Returns true iff x <= y

Parameters:
xOperableType
yOperableType
Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import rel_le
>>> m = Container()
>>> a = Parameter(m, "a", records=12)
>>> b = Parameter(m, "b", records=11)
>>> c = Parameter(m, "c")
>>> c[...] = rel_le(a, b)
>>> c.toValue()
np.float64(0.0)
gamspy.math.rel_lt(x: OperableType, y: OperableType) MathOp[source]#

Returns true iff x < y

Parameters:
xOperableType
yOperableType
Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import rel_lt
>>> m = Container()
>>> a = Parameter(m, "a", records=12)
>>> b = Parameter(m, "b", records=17)
>>> c = Parameter(m, "c")
>>> c[...] = rel_lt(a, b)
>>> c.toValue()
np.float64(1.0)
gamspy.math.rel_ne(x: OperableType, y: OperableType) MathOp[source]#

Returns true iff x != y

Parameters:
xOperableType
yOperableType
Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import rel_ne
>>> m = Container()
>>> a = Parameter(m, "a", records=12)
>>> b = Parameter(m, "b", records=12)
>>> c = Parameter(m, "c")
>>> c[...] = rel_ne(a, b)
>>> c.toValue()
np.float64(0.0)
gamspy.math.relu_with_binary_var(x: Parameter | Variable | implicits.ImplicitParameter | implicits.ImplicitVariable | Expression | Operation, default_lb: float = -1000000, default_ub: float = 1000000, *, return_binary_var: bool = False) FormulationResult[source]#

Implements the ReLU activation function using binary variables. The ReLU function is defined as ReLU(x) = max(x, 0). This implementation generates one binary variable, one positive variable and three equations. The binary variable is necessary to represent the mathematical relationship, while the positive variable serves as the activation variable. Both the binary and positive variables share the same domain as the input.

The formulation of this function requires having lower and upper bounds for the input x. This function utilizes the bounds from the variables if provided. If not, it defaults to the bounds defined by default_lb and default_ub. Providing tighter and correct bounds can enhance the quality of linear relaxations.

Returns the activation variable and the equation list if return_binary_var is False, otherwise returns activation, binary variable and equation list in order.

Adapted from OMLT

FormulationResult:
  • variables_created: [“output”, “binary”]

  • equations_created: [“y_gte_x”, “y_lte_x_1”, “y_lte_x_2”]

Parameters:
xParameter | Variable | implicits.ImplicitParameter | implicits.ImplicitVariable | Expression | Operation
default_ubfloat
default_lbfloat
return_binary_var: bool
Returns:
FormulationResult

Examples

>>> from gamspy import Container, Variable, Set
>>> from gamspy.math.activation import relu_with_binary_var
>>> m = Container()
>>> i = Set(m, "i", records=range(3))
>>> x = Variable(m, "x", domain=[i])
>>> y, eqs = relu_with_binary_var(x) # FormulationResult can be unpacked for backwards compat
>>> y.type
'positive'
>>> len(eqs)
3
>>> y, b, eqs = relu_with_binary_var(x, return_binary_var=True)
>>> b.type
'binary'
>>> y.domain # i many activation variables
[Set(name='i', domain=['*'])]
>>> b.domain # i many binary variables
[Set(name='i', domain=['*'])]
>>> output = relu_with_binary_var(x) # You can use FormulationResult too
>>> binary_var = output.variables_created["binary"]
>>> y = output.result
gamspy.math.relu_with_complementarity_var(x: Parameter | Variable | implicits.ImplicitParameter | implicits.ImplicitVariable | Expression | Operation)[source]#

Implements the ReLU activation function using complementarity conditions. The ReLU function is defined as ReLU(x) = max(x, 0). This implementation generates one positive variable, which serves as the activation variable and two equations. The activation variable shares the same domain as the input. Unlike relu_with_binary_var, this function does not require lower and upper bounds for the formulation.

Returns the activation variable and the equation list.

Adapted from OMLT

Parameters:
xParameter | Variable | implicits.ImplicitParameter | implicits.ImplicitVariable | Expression | Operation
Returns:
tuple[Variable, list[Equation]]

Examples

>>> from gamspy import Container, Variable, Set
>>> from gamspy.math.activation import relu_with_complementarity_var
>>> m = Container()
>>> i = Set(m, "i", records=range(3))
>>> x = Variable(m, "x", domain=[i])
>>> y, eqs = relu_with_complementarity_var(x)
>>> y.type
'positive'
>>> len(eqs)
2
gamspy.math.relu_with_equilibrium(x: Parameter | Variable | implicits.ImplicitParameter | implicits.ImplicitVariable | Expression | Operation) FormulationResult[source]#

Implements the ReLU activation function using Equilibrium Constraints. This implementation is suitable for models of type Mathematical Program with Equilibrium Constraints (MPEC) or Mixed Complementarity Problem (MCP). One positive variable is generated, which serves as the activation variable and no equations. The activation variable shares the same domain as the input. Lower and upper bounds are not required for this formulation.

Returns FormulationResult which can be unpacked as activation variable, matches dictionary and the equation list (empty).

FormulationResult:

variables_created: [“output”] equations_created: [] matches: {(output - x) : output} extra_return: yes (matches)

or if the provided input was not a Variable, this formulation assigns it to a new variable and uses the new variable instead

FormulationResult:

variables_created: [“output”, “new_input”] equations_created: [“set_new_input”] matches: {(output - new_input) : output} extra_return: yes (matches)

Parameters:
xVariable
Returns:
FormulationResult

Examples

>>> from gamspy import Container, Variable, Set
>>> from gamspy.math.activation import relu_with_equilibrium
>>> m = Container()
>>> i = Set(m, "i", records=range(3))
>>> x = Variable(m, "x", domain=[i])
>>> y, matches, eqs = relu_with_equilibrium(x)
>>> y.type
'positive'
>>> len(eqs)
0
>>> len(matches)
1
>>> result = relu_with_equilibrium(x)
>>> type(result)
<class 'gamspy.formulations.result.FormulationResult'>
>>> result = relu_with_equilibrium(x - 5)
>>> new_input = result.variables_created["new_input"]
gamspy.math.relu_with_sos1_var(x: Parameter | Variable | implicits.ImplicitParameter | implicits.ImplicitVariable | Expression | Operation, *, return_slack_var: bool = False)[source]#

Implements the ReLU activation function using SOS1 variables. The ReLU function is defined as ReLU(x) = max(x, 0). This implementation generates one SOS1 type variable which is necessary to represent the mathematical relationship and one equation. The SOS1 variable contains the activation variable and the slack variable.

Unlike relu_with_binary_var, this function does not require lower and upper bounds for the formulation. It is claimed that when providing tight bounds is not straightforward, using relu_with_sos1_var might perform better than relu_with_binary_var, as the relaxation of relu_with_binary_var can be weak.

Usage of SOS1 variables require MIP or MINLP and a solver that supports SOS1 variables. Main intended use case of this function is embedding the trained neural network into MIP models, we do not suggest using it in training since you would need a MINLP solver that support SOS1 variables.

Returns the activation variable and the equation list if return_slack_var is False, otherwise returns activation, slack variable and the equation list in order. Since activation variable and slack variable are the same variable only separated by the last domain this function returns ImplicitVariable instead of Variable.

Based on paper: PySCIPOpt-ML: Embedding trained machine learning models into mixed-integer programs.

Parameters:
xParameter | Variable | implicits.ImplicitParameter | implicits.ImplicitVariable | Expression | Operation
return_slack_var: bool
Returns:
tuple[implicits.ImplicitVariable, list[Equation]] | tuple[implicits.ImplicitVariable, implicits.ImplicitVariable, list[Equation]]

Examples

>>> from gamspy import Container, Variable, Set
>>> from gamspy.math.activation import relu_with_sos1_var
>>> m = Container()
>>> i = Set(m, "i", records=range(3))
>>> x = Variable(m, "x", domain=[i])
>>> y, eqs = relu_with_sos1_var(x)
>>> y, s, eqs = relu_with_sos1_var(x, return_slack_var=True)
>>> y.domain # implicit activation variable has the same domain
[Set(name='i', domain=['*'])]
>>> s.domain # implicit slack variable has the same domain as well
[Set(name='i', domain=['*'])]
>>> y.name == s.name # In the background that y and s are parts of the same variable
True
>>> id(y.parent) == id(s.parent)
True
gamspy.math.rpower(base: OperableType | Operable, exponent: OperableType)[source]#

Returns x^y for x > 0 and also for x = 0 and restricted values of y (Error if x < 0)

Parameters:
baseOperableType
exponentOperableType
Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter, Set
>>> from gamspy.math import rpower
>>> m = Container()
>>> i = Set(m, name="i", records=["i1", "i2"])
>>> a = Parameter(m, "a", domain=i, records=[("i1", 3.8)])
>>> b = Parameter(m, "b", domain=i)
>>> b[i] = rpower(a[i], 3)
gamspy.math.same_as(arg1: Set | Alias | str, arg2: Set | Alias | str) MathOp[source]#

Evaluates to true if this set is identical to the given set or alias, false otherwise.

Parameters:
arg1Set | Alias | str
otherSet | Alias | str
Returns:
MathOp

Examples

>>> import gamspy as gp
>>> from gamspy.math import same_as
>>> m = gp.Container()
>>> i = gp.Set(m, name="i", records=["seattle", "san-diego"])
>>> j = gp.Set(m, name="j", records=["new-york", "seattle"])
>>> attr = gp.Parameter(m, "attr", domain = [i, j])
>>> attr[i,j]  =  same_as(i, j)
>>> attr.records.values.tolist()
[['seattle', 'seattle', 1.0]]
gamspy.math.sigmoid(x: OperableType) MathOp[source]#

Sigmoid of x (i.e. 1 / (1 + exp(-x)))

Parameters:
xOperableType
Returns:
MathOp

Examples

>>> from gamspy import Container, Set, Parameter
>>> from gamspy.math import sigmoid
>>> m = Container()
>>> i = Set(m, name="i", records=["i1", "i2", "i3"])
>>> a = Parameter(m, "a", domain=i, records=[("i1", 4), ("i2", -1), ("i3", 0.5)])
>>> b = Parameter(m, "b", domain=i)
>>> b[i] = sigmoid(a[i])
gamspy.math.sign(x: SymbolType) MathOp[source]#

Sign of x returns 1 if x > 0, -1 if x < 0, and 0 if x = 0

Parameters:
xSymbolType
Returns:
MathOp

Examples

>>> from gamspy import Container, Set, Parameter
>>> from gamspy.math import sign
>>> m = Container()
>>> i = Set(m, name="i", records=["i1", "i2", "i3"])
>>> a = Parameter(m, "a", domain=i, records=[("i1", 2), ("i2", -5.4), ("i3", 0)])
>>> b = Parameter(m, "b", domain=i)
>>> b[i] = sign(a[i])
>>> b.toList()
[('i1', 1.0), ('i2', -1.0)]
gamspy.math.sign_power(base: OperableType, exponent: float)[source]#

Signed power: sign(base) * |base|^exponent, for exponent > 0

Parameters:
baseOperableType
exponentfloat
Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter, Set
>>> from gamspy.math import sign_power
>>> m = Container()
>>> i = Set(m, name="i", records=["i1", "i2"])
>>> a = Parameter(m, "a", domain=i, records=[("i1", 3.8)])
>>> b = Parameter(m, "b", domain=i)
>>> b[i] = sign_power(a[i], 5)
gamspy.math.sin(x: OperableType) MathOp[source]#

Sine of x.

Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import sin
>>> import numpy as np
>>> m = Container()
>>> r = Parameter(m, "r")
>>> r[...] = sin(np.pi/2)
>>> r.toValue()
np.float64(1.0)
gamspy.math.sinh(x: OperableType) MathOp[source]#

Hyperbolic sine of x.

Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import sinh
>>> m = Container()
>>> r = Parameter(m, "r")
>>> r[...] = sinh(0)
>>> r.toValue()
np.float64(0.0)
gamspy.math.slexp(x: OperableType, S: int | float = 150) MathOp[source]#

Smooth (linear) exponential where S <= 150. (Default S = 150)

Parameters:
xOperableType
Sint | float, by default 150
Returns:
MathOp

Examples

>>> import math
>>> from gamspy import Container, Parameter
>>> from gamspy.math import slexp
>>> m = Container()
>>> a = Parameter(m, "a", records=3)
>>> b = Parameter(m, "b")
>>> b[...] = slexp(a)
>>> math.isclose(b.toValue(), 20.085536923187668)
True
gamspy.math.sllog10(x: OperableType, S: int | float = 1e-150) MathOp[source]#

Smooth (linear) logarithm base 10

Parameters:
xOperableType
Sint | float, by default 1.0e-150
Returns:
MathOp

Examples

>>> import math
>>> from gamspy import Container, Parameter
>>> from gamspy.math import sllog10
>>> m = Container()
>>> a = Parameter(m, "a", records=3.8)
>>> b = Parameter(m, "b")
>>> b[...] = sllog10(a)
>>> math.isclose(b.toValue(), 0.5797835966168101)
True
gamspy.math.slrec(x: OperableType, S: int | float = 1e-10) MathOp[source]#

Smooth (linear) reciprocal, where S >= 1e-10. (Default S = 1e-10)

Parameters:
xOperableType
Sint | float, by default 1e-10
Returns:
MathOp

Examples

>>> from gamspy import Container, Set, Parameter
>>> from gamspy.math import slrec
>>> m = Container()
>>> i = Set(m, name="i", records=["i1", "i2", "i3"])
>>> a = Parameter(m, "a", domain=i, records=[("i1", 1), ("i2", 0.8), ("i3", 15)])
>>> b = Parameter(m, "b", domain=i)
>>> b[i] = slrec(a[i])
gamspy.math.softmax(x: Variable, dim: int = -1)[source]#

Implements the softmax activation function. This function strictly requires a GAMSPy Variable, y = softmax(x). The dim parameter specifies the index of the softmax dimension. If not provided, the softmax is calculated for the last dimension. This function is implemented for completeness; however, in many cases, you can use log_softmax for better numerical stability.

Use log_softmax if you need to take the logarithm of the softmax function.

Returns the activation variable and the equation list.

Parameters:
xVariable
dimint
Returns:
tuple[Variable, list[Equation]]

Examples

>>> from gamspy import Container, Variable
>>> from gamspy.math import dim
>>> from gamspy.math.activation import softmax
>>> m = Container()
>>> x = Variable(m, "x", domain=dim([500, 10]))
>>> y, eqs = softmax(x)
>>> y.domain
[Set(name='DenseDim500_1', domain=['*']), Set(name='DenseDim10_1', domain=['*'])]
gamspy.math.softplus(x: Variable, beta=1.0, *, skip_intrinsic: bool = False) tuple[Variable, list[Equation]][source]#

Implements the softplus activation function. This function uses the lse_max_sc (log-sum-exp) intrinsic function for improved numerical stability which usually leads to faster solve times. Some solvers do not support lse_max_sc, in that case you can set skip_intrinsic parameter to True to not use intrinsic functions.

beta value controls the smoothness and slope of the function, by default equals to 1.

skip_intrinsic (Default False)

Parameters:
xVariable
betafloat
skip_intrinsic: bool
Returns:
tuple[Variable, list[Equation]]

Examples

>>> from gamspy import Container, Variable
>>> from gamspy.math import dim
>>> from gamspy.math.activation import softplus
>>> m = Container()
>>> x = Variable(m, "x", domain=dim([500, 10]))
>>> y, eqs1 = softplus(x)
>>> y.domain
[Set(name='DenseDim500_1', domain=['*']), Set(name='DenseDim10_1', domain=['*'])]
>>> y2, eqs2 = softplus(x, skip_intrinsic=True) # don't use LSE because of skip_intrinsic
gamspy.math.sqexp(x: OperableType, S: int | float = 150) MathOp[source]#

Smooth (quadratic) exponential where S <= 150. (Default S = 150)

Parameters:
xOperableType
Sint | float, by default 150
Returns:
MathOp

Examples

>>> import math
>>> from gamspy import Container, Parameter
>>> from gamspy.math import sqexp
>>> m = Container()
>>> a = Parameter(m, "a", records=3)
>>> b = Parameter(m, "b")
>>> b[...] = sqexp(a)
>>> math.isclose(b.toValue(), 20.085536923187668)
True
gamspy.math.sqlog10(x: OperableType, S: int | float = 1e-150) MathOp[source]#

Smooth (quadratic) logarithm base 10

Parameters:
xOperableType
Sint | float, by default 1.0e-150
Returns:
MathOp

Examples

>>> import math
>>> from gamspy import Container, Parameter
>>> from gamspy.math import sqlog10
>>> m = Container()
>>> a = Parameter(m, "a", records=3.8)
>>> b = Parameter(m, "b")
>>> b[...] = sqlog10(a)
>>> math.isclose(b.toValue(), 0.5797835966168101)
True
gamspy.math.sqr(x: OperableType) MathOp[source]#

Square of x (i.e. x^2)

Parameters:
xOperableType
Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import sqr
>>> m = Container()
>>> a = Parameter(m, "a", records=4)
>>> b = Parameter(m, "b")
>>> b[...] = sqr(a)
>>> b.toValue()
np.float64(16.0)
gamspy.math.sqrec(x: OperableType, S: int | float = 1e-10) MathOp[source]#

Smooth (quadratic) reciprocal, where S >= 1e-10. (Default S = 1e-10)

Parameters:
xOperableType
Sint | float, by default 1e-10
Returns:
MathOp

Examples

>>> from gamspy import Container, Set, Parameter
>>> from gamspy.math import sqrec
>>> m = Container()
>>> i = Set(m, name="i", records=["i1", "i2", "i3"])
>>> a = Parameter(m, "a", domain=i, records=[("i1", 1), ("i2", 0.8), ("i3", 15)])
>>> b = Parameter(m, "b", domain=i)
>>> b[i] = sqrec(a[i])
gamspy.math.sqrt(x: OperableType, *, safe_cancel: bool = False) MathOp[source]#

Square root of x

Returns:
MathOp

Examples

>>> from gamspy import Container, Set, Parameter
>>> from gamspy.math import sqrt
>>> m = Container()
>>> i = Set(m, name="i", records=["i1", "i2", "i3"])
>>> a = Parameter(m, "a", domain=i, records=[("i1", 4), ("i2", 54), ("i3", 0)])
>>> b = Parameter(m, "b", domain=i)
>>> b[i] = sqrt(a[i])
gamspy.math.tan(x: OperableType) MathOp[source]#

Tangent of x.

Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import tan
>>> import numpy as np
>>> m = Container()
>>> r = Parameter(m, "r")
>>> r[...] = tan(np.pi/4)
>>> round(r.toValue(), 2)
np.float64(1.0)
gamspy.math.tanh(x: OperableType) MathOp[source]#

Hyperbolic tangent of x.

Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import tanh
>>> m = Container()
>>> r = Parameter(m, "r")
>>> r[...] = tanh(0)
>>> r.toValue()
np.float64(0.0)
gamspy.math.trace(x: Parameter | implicits.ImplicitParameter | Variable | implicits.ImplicitVariable, axis1: int = 0, axis2: int = 1) Operation[source]#

Returns trace of the given input x. By default trace of zeroth and first axis used. axis1 and axis2 parameters control on which axes to get trace. Domains at the axis1 and axis2 must be same or aliases.

Parameters:
x: (

Parameter | implicits.ImplicitParameter | Variable | implicits.ImplicitVariable

)
axis1=0
axis2=1
Returns:
Operation

Examples

>>> import gamspy as gp
>>> import numpy as np
>>> m = gp.Container()
>>> identity = np.eye(3, 3)
>>> mat = gp.Parameter(m, name="mat", domain=gp.math.dim([3, 3]), records=identity, uels_on_axes=True)
>>> sc = gp.Parameter(m, name="sc", domain=[])
>>> sc[...] = gp.math.trace(mat)
>>> int(sc.toDense())
3
gamspy.math.truncate(x: OperableType) MathOp[source]#

Returns the integer part of x (i.e. truncate(3.9) returns 3)

Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import truncate
>>> m = Container()
>>> a = Parameter(m, "a", records=3.9)
>>> b = Parameter(m, "b")
>>> b[...] = truncate(a)
>>> b.toValue()
np.float64(3.0)
gamspy.math.uniform(lower_bound: float | Expression, upper_bound: float | Expression) MathOp[source]#

Generates a random number from the uniform distribution between lower_bound and higher_bound

Parameters:
lower_boundfloat
upper_boundfloat
Returns:
MathOp

Examples

>>> from gamspy import Container, Set, Parameter
>>> from gamspy.math import uniform
>>> m = Container()
>>> i = Set(m, name="i", records=["i1", "i2", "i3"])
>>> x = Parameter(m, "x", domain=i, records=[("i1", 30), ("i2", 8), ("i3", 45)])
>>> b = Parameter(m, "b", domain=i)
>>> b[i] = uniform(x[i], 50)
gamspy.math.uniformInt(lower_bound: int | float, upper_bound: int | float) MathOp[source]#

Generates an integer random number from the discrete uniform distribution whose outcomes are the integers between lower_bound and higher_bound

Parameters:
lower_boundint | float
upper_boundint | float
Returns:
MathOp

Examples

>>> from gamspy import Container, Set, Parameter
>>> from gamspy.math import uniformInt
>>> m = Container()
>>> i = Set(m, name="i", records=["i1", "i2", "i3"])
>>> x = Parameter(m, "x", domain=i, records=[("i1", 30), ("i2", 8), ("i3", 45)])
>>> b = Parameter(m, "b", domain=i)
>>> b[i] = uniformInt(x[i], 50)
>>> b.toList()
[('i1', 33.0), ('i2', 44.0), ('i3', 48.0)]
gamspy.math.vc_power(base: OperableType, exponent: OperableType)[source]#

Returns x^y for x >= 0 (error for x < 0)

Parameters:
baseOperableType
exponentOperableType
Returns:
MathOp

Examples

>>> from gamspy import Container, Parameter
>>> from gamspy.math import vc_power
>>> m = Container()
>>> a = Parameter(m, "a", records=4)
>>> b = Parameter(m, "b")
>>> b[...] = vc_power(a, 3)
gamspy.math.vector_norm(x: Parameter | Variable | implicits.ImplicitParameter | implicits.ImplicitVariable | Expression | Operation, ord: float | int = 2, dim: list[int] | list[Set | Alias] | None = None) Operation | Expression | MathOp[source]#

Returns the vector norm of the provided vector x. If ord is not an even integer, absolute value is used which requires DNLP.

Parameters:
xParameter | Variable | implicits.ImplicitParameter | implicits.ImplicitVariable | Expression | Operation
ord: int | float
dim: list[int] | list[Set | Alias], optional
Returns:
Expression | Operation | MathOp

Examples

>>> import gamspy as gp
>>> import math
>>> m = gp.Container()
>>> i = gp.Set(m, name="i", records=["i1", "i2"])
>>> vec = gp.Parameter(m, "vec", domain=[i], records=[("i1", 3), ("i2", 4)])
>>> vlen = gp.Parameter(m, "vlen", domain=[])
>>> vlen[...] = gp.math.vector_norm(vec)
>>> math.isclose(vlen.toValue(), 5, rel_tol=1e-4)
True