Run on Jupyter Notebook

Sample codeIn this section, we introduce Amplify's features by programming an Ising machine using Amplify. For more information, see the official documentation.

A polynomial of $n$ number of binary variables, $f_n$, is expressed as follows:

$\displaystyle f_n(x_1, x_2, \cdots, x_n) = \sum_{\{k_1,k_2, \cdots, k_n\}}a_{k_1k_2\cdots k_n}x_1^{k_i}x_2^{k_2}\cdots x_n^{k_n}\,\quad k_i\in\{0, 1\}$

The $x_i$ is a binary variable, either a binary variable $q_i\in\{0,1\in\}$ or an Ising variable $s_i\in\{-1, +1\in\}$. Also, $a_{k_1k_2\cdots k_n}$ are the coefficients of the polynomial.

Amplify provides the following polynomial classes to represent binary multivariate polynomials.

`BinaryPoly`

(Polynomials with binary variables)`IsingPoly`

(Polynomials with Ising variables)

Amplify can generate binary variables in the form of multi-dimensional arrays using
`gen_symbols`

. You can also generate polynomials by using operations of product
`*`

and sum `+`

on the generated binary variables.

In [ ]:

```
from amplify import (
gen_symbols,
BinaryPoly,
)
# A one-dimensional array of four binary variables
q_1d = gen_symbols(BinaryPoly, 4)
# A 3x2 two-dimensional array of binary variables
q_2d = gen_symbols(BinaryPoly, 3, 2)
# A 3x2 two-dimensional array of binary variables with variable indices starting from 10
q_2d_2 = gen_symbols(BinaryPoly, 10, (3, 2))
print(f"q_1d = {q_1d}")
print(f"q_2d = {q_2d}")
print(f"q_2d_2 = {q_2d_2}")
```

In [ ]:

```
q = gen_symbols(BinaryPoly, 4)
# q_0 * q_1 + q_2
f0 = q[0] * q[1] + q[2]
# q_1 + q_3 + 1
f1 = q[1] + q[3] + 1
# (q_0 * q_1 + q_2) + (q_1 + q_3 + 1)
f2 = f0 + f1
# (q_1 + q_3 + 1) * (q_1 + q_3 + 1)
f3 = f1**2
print(f"f0 = {f0}")
print(f"f1 = {f1}")
print(f"f2 = {f2}")
print(f"f3 = {f3}")
```

`gen_symbols`

function generates binary variables whose variable index starts at $0$ by
default. You can change the leading variable index by giving an offset as the second argument.

In [ ]:

```
from amplify import (
gen_symbols,
BinaryPoly,
)
s1 = gen_symbols(BinaryPoly, 4)
s2 = gen_symbols(BinaryPoly, 4)
# If you don't shift the index, the same variables will be defined
print(s1, s2)
# Create variables by shifting the index by the length of s1
s3 = gen_symbols(BinaryPoly, len(s1), (4,))
# Different variables can be defined
print(s1, s3)
```

Amplify implements the following three functions as formulation aids for polynomial classes:

`sum_poly()`

: Equivalent to all sums $\sum_i$`pair_sum()`

: Equivalent to the sum of all combinations of functions $\sum_{i\neq j}$`product()`

: Equivalent to all products $\prod_i$

We show a few examples of how to use these formulation aids.

In [ ]:

```
from amplify import sum_poly
# Generate 8 binary variables in 1D array format
q = gen_symbols(BinaryPoly, 8)
# Given a list of binary variables or polynomials, the sum of them can be calculated
f0 = sum_poly(q)
print(f"f0 = {f0}")
```

In [ ]:

```
# Generate three binary variables
q = gen_symbols(BinaryPoly, 3)
# It is also possible to specify a function that takes an index and an upper limit for the index, and take the sum
f1 = sum_poly(3, lambda i: sum_poly(3, lambda j: q[i] * q[j]))
print(f"f1 = {f1}")
```

In [ ]:

```
# Generate a 2x2 binary variable array
q = gen_symbols(BinaryPoly, 2, 2)
# Double sum of formulas involving squaring and quadrature
f2 = sum_poly(2, lambda i: (sum_poly(2, lambda j: q[i][j]) - 1) ** 2)
print(f"f2 = {f2}")
```

In [ ]:

```
from amplify import pair_sum
# Generate three binary variables
q = gen_symbols(BinaryPoly, 3)
f3 = pair_sum(q)
print(f"f3 = {f3}")
```

In [ ]:

```
from amplify import product
# Generate three binary variables
q = gen_symbols(BinaryPoly, 3)
f4 = product(q)
print(f"f4 = {f4}")
```

It is also possible to construct polynomials directly from the `BinaryPoly`

and
`IsingPoly`

polynomial constructors.

To create any term of a binary multivariate polynomial, a dictionary of the following form is put into the argument of the constructor of the above class.

$kx_{i}x_{j}\cdots x_{m} \rightarrow $ `{(i, j, ..., m): k}`

Multiple terms can also be combined into a dictionary form.

$k_2 x_ix_j + k_1 x_l + c \rightarrow $ `{(i, j): k2, (l): k1, (): c)}`

The following is a basic example:

In [ ]:

```
from amplify import BinaryPoly
# q_0
f0 = BinaryPoly({(0): 1})
# 2 * q_0 * q_1 + 1
f1 = BinaryPoly({(0, 1): 2, (): 1})
print(f"f0 = {f0}")
print(f"f1 = {f1}")
```

When dealing with Ising polynomials, `IsingPoly`

.

In [ ]:

```
from amplify import IsingPoly
# s_0
f0 = IsingPoly({(0): 1})
# 2 * s_0 * s_1 + 1
f1 = IsingPoly({(0, 1): 2, (): 1})
print(f"f0 = {f0}")
print(f"f1 = {f1}")
```