# 14.1 Fusion API conventions¶

## 14.1.1 General conventions¶

All the classes of the Fusion interface are contained in the package mosek.fusion. The user should not directly instantiate objects of any class other than creating a `Model`.

```M = Model()
M = Model('modelName')

with Model() as M:
```

The model is the main access point to an optimization problem and its solution. All other objects should be created through the model (`Model.variable`, `Model.constraint`, etc.) or using static factory methods (`Matrix.sparse` etc.).

## 14.1.2 Numerical types¶

Whenever a method expects a numeric or integer array, this can be either a Python list or a NumPy array of appropriate shape.

For NumPy arrays the element type must agree exactly with the type expected by the method, for instance for an argument of type `float[]` one can pass an array of type `numpy.array(dtype=float)` but not of type `numpy.array(dtype=int)`.

For sparse arrays use a `Matrix` created with `Matrix.sparse`.

## 14.1.3 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.1.3.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.1.3.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.1.3.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.1.3.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.1.3.5 Miscellaneous¶

Other syntactic additions.

 With `mosek.fusion.pythonic` Standard Fusion ```print(f"{x.shape}") ``` ```print(f"{x.getShape()}") ```