14.2 Pythonic extensions¶
Standard Python arithmetic operators and extensions known for example from NumPy can be used in Fusion upon importing the following extension:
import mosek.fusion.pythonic
14.2.1 Arithmetic operators¶
Operators +
, -
, @
, *
, /
are available for affine expressions or constants of matching dimensions, as equivalents to Expr.add (+)
, Expr.sub (-)
, Expr.neg (-)
, Expr.mul (*,@)
. Operator precedence is handled by Python. Transposition of variables, expressions and matrices can be obtained with .T
.
With |
Standard Fusion |
x + b
x - b
A @ x
A @ x + c
x / 4.0
2 * y + A @ (x - b)
x.T @ mu - alpha * gamma
|
Expr.add(x, b)
Expr.sub(x, b)
Expr.mul(A, x)
Expr.add(Expr.mul(A, x), c)
Expr.mul(x, 0.25)
Expr.add(Expr.mul(2, y), Expr.mul(A, Expr.sub(x, b)))
Expr.sub(Expr.dot(x, mu), Expr.mul(alpha, gamma))
|
14.2.2 Constraints¶
Operators <=
, >=
, ==
can be used to define linear constraints. The operator ==
can also be used as a shorthand to indicate membership in other domains.
With |
Standard Fusion |
M.constraint(A @ x + c >= 0)
M.constraint("lt", A @ x <= y + c)
M.constraint("eq", A @ (x - b) == y + c)
M.constraint(5 * x == Domain.inRange(-1, 1))
M.constraint("cone", Expr.vstack(0.1, A @ x) == Domain.inQCone())
|
M.constraint(Expr.add(Expr.mul(A, x), c), Domain.greaterThan(0))
M.constraint("lt", Expr.sub(Expr.mul(A, x), y), Domain.lessThan(c))
M.constraint("eq", Expr.sub(Expr.mul(A, Expr.sub(x, b)), y), Domain.equalsTo(c))
M.constraint(Expr.mul(5, x), Domain.inRange(-1, 1))
M.constraint("cone", Expr.vstack(0.1, Expr.mul(A, x)), Domain.inQCone())
|
14.2.3 Indexing and slicing¶
The index operator []
plays the role of the indexing and slicing methods Expression.index ([])
, Expression.slice ([])
, Expression.pick ([])
and their analogues for variables and parameters. Standard conventions about empty slice bounds and negative indices and slice bounds apply (for example x[-1]
is the last entry of x
).
With |
Standard Fusion |
# index
x[1]
# pick
x[[1,2,4]]
# 2-dim index
z[3, 4]
# 2-dim slice
z[2:4, :9]
# 2-dim pick
z[[(1, 2), (2, 3), (4, 5)]]
|
# index
x.index(1)
# pick
x.pick([1,2,4])
# 2-dim index
z.index([3, 4])
# 2-dim slice
z.slice([2, 0], [4, 9])
# 2-dim pick
z.pick([[1, 2], [2, 3], [4, 5]])
|
14.2.4 Logical operators in disjunctions¶
Operators |
and &
can be used as OR
and AND
to form simple disjunctions. They only make sense within Model.disjunction (|)
. Note that the default precedence rules will usually require parenthesizing all clauses.
With |
Standard Fusion |
M.disjunction((x[i] == 0) | (x[i] == Domain.inRange(2, 3)))
M.disjunction( ((y <= -1) & (z == 0)) | ((y >= 1) & (z == 1)) )
M.disjunction( ((A @ x >= c) & (z == 1)) | (z == 0) )
|
M.disjunction(DJC.term(x.index(i), Domain.equalsTo(0)),
DJC.term(x.index(i), Domain.inRange(2, 3)) )
M.disjunction(DJC.AND(DJC.term(y, Domain.lessThan(-1)),
DJC.term(z, Domain.equalsTo(0)) ),
DJC.AND(DJC.term(y, Domain.greaterThan(1)),
DJC.term(z, Domain.equalsTo(1)) ) )
M.disjunction(DJC.AND(DJC.term(Expr.sub(Expr.mul(A, x), c), Domain.greaterThan(0)),
DJC.term(z, Domain.equalsTo(1)) ),
DJC.term(z, Domain.equalsTo(0)) )
|
14.2.5 Miscellaneous¶
Other syntactic additions.
With |
Standard Fusion |
# Shape
print(f"{x.shape}")
# Flattening
z.F
|
# Shape
print(f"{x.getShape()}")
# Flattening
Var.flatten(z)
|