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 mosek.fusion.pythonic

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 mosek.fusion.pythonic

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 mosek.fusion.pythonic

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 mosek.fusion.pythonic

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 mosek.fusion.pythonic

Standard Fusion

# Shape
print(f"{x.shape}")

# Flattening
z.F
# Shape
print(f"{x.getShape()}")

# Flattening
Var.flatten(z)