Monodimensional Angular Model

[1]:
import numpy as np
import matplotlib.pyplot as plt
from qiskit.visualization import plot_histogram
from qrobot.models import AngularModel

In this notebook we present a 1-dimensional (\(n=1\)) demo for the AngularModel class.

[2]:
n = 1

Here, we considered a time window of \(\tau > 1\).

[3]:
tau = 30

Input definition

We start by defining an arbirary input sequence:

[4]:
sequence = list()

# Balanced events (between 0 and 1)
for i in range(0, int(tau / 2)):
    sequence.append(np.random.randint(0, 1000) / 1000)

# Unbalanced events (balanced between .5 and 1)
for i in range(int(tau / 2), tau):
    sequence.append(np.random.randint(500, 1000) / 1000)

plt.figure()
plt.stem(sequence, use_line_collection=True, linefmt="w", basefmt="w")
plt.xlabel("Time index t")
plt.ylabel("Input value x")
plt.title("Input sequence")
plt.show()
../_images/notebooks_02_monodimensional_angular_model_7_0.png

Encode the input in the model

We initialize the model by instantiating an object with \(n\) and \(\tau\)

[5]:
model = AngularModel(n, tau)

Using the encode method, we can encode each event’s data in the model (for multidimensional inputs, a second loop is needed in order to loop through the \(n\) dimensions of the input).

[6]:
model.clear()  # to re-initialize the model (allows re-runing this cell without double the encoding)

for t in range(0, model.tau):  # loop throug the event sequence
    model.encode(sequence[t], dim=0)

The model is implemented by a Qiskit quantum circuit:

[7]:
model.print_circuit()
     ┌──────────────┐┌────────────┐┌──────────┐┌──────────────┐┌──────────────┐»
q_0: ┤ Ry(0.033406) ├┤ Ry(π/1200) ├┤ Ry(π/75) ├┤ Ry(0.046286) ├┤ Ry(0.043878) ├»
     └──────────────┘└────────────┘└──────────┘└──────────────┘└──────────────┘»
c: 1/══════════════════════════════════════════════════════════════════════════»
                                                                               »
«     ┌──────────────┐┌──────────────┐┌──────────────┐┌──────────────┐»
«q_0: ┤ Ry(0.071209) ├┤ Ry(0.083043) ├┤ Ry(0.013404) ├┤ Ry(0.061575) ├»
«     └──────────────┘└──────────────┘└──────────────┘└──────────────┘»
«c: 1/════════════════════════════════════════════════════════════════»
«                                                                     »
«     ┌──────────────┐┌──────────────┐┌──────────────┐┌──────────────┐»
«q_0: ┤ Ry(0.043145) ├┤ Ry(0.045658) ├┤ Ry(0.027646) ├┤ Ry(0.021782) ├»
«     └──────────────┘└──────────────┘└──────────────┘└──────────────┘»
«c: 1/════════════════════════════════════════════════════════════════»
«                                                                     »
«     ┌───────────────┐┌─────────────┐┌──────────────┐┌──────────────┐»
«q_0: ┤ Ry(0.0073304) ├┤ Ry(0.05435) ├┤ Ry(0.064298) ├┤ Ry(0.061575) ├»
«     └───────────────┘└─────────────┘└──────────────┘└──────────────┘»
«c: 1/════════════════════════════════════════════════════════════════»
«                                                                     »
«     ┌──────────────┐┌──────────────┐┌──────────────┐┌─────────────┐»
«q_0: ┤ Ry(0.086603) ├┤ Ry(0.053512) ├┤ Ry(0.088279) ├┤ Ry(0.10064) ├»
«     └──────────────┘└──────────────┘└──────────────┘└─────────────┘»
«c: 1/═══════════════════════════════════════════════════════════════»
«                                                                    »
«     ┌──────────────┐┌──────────────┐┌─────────────┐┌──────────────┐»
«q_0: ┤ Ry(0.076969) ├┤ Ry(0.065136) ├┤ Ry(0.10388) ├┤ Ry(0.088593) ├»
«     └──────────────┘└──────────────┘└─────────────┘└──────────────┘»
«c: 1/═══════════════════════════════════════════════════════════════»
«                                                                    »
«     ┌──────────────┐┌─────────────┐┌──────────────┐┌──────────────┐»
«q_0: ┤ Ry(0.053931) ├┤ Ry(0.08608) ├┤ Ry(0.066183) ├┤ Ry(0.088802) ├»
«     └──────────────┘└─────────────┘└──────────────┘└──────────────┘»
«c: 1/═══════════════════════════════════════════════════════════════»
«                                                                    »
«     ┌──────────────┐
«q_0: ┤ Ry(0.073827) ├
«     └──────────────┘
«c: 1/════════════════
«

Given the input we defined above, the model is in the following state:

[8]:
model.plot_state_mat()
../_images/notebooks_02_monodimensional_angular_model_15_0.png

Density matrix (from Wikipedia): or a finite-dimensional function space, the most general density operator is of the form

\[\rho =\sum _{j}p_{j}|\psi _{j}\rangle \langle \psi _{j}|\]

where the coefficients \(p_{j}\) are non-negative and add up to one, and \(|\psi _{j}\rangle \langle \psi _{j}|\) is an outer product written in bra-ket notation. This represents a mixed state, with probability $ p_{j}$ that the system is in the pure state $|:nbsphinx-math:psi `_{j}:nbsphinx-math:rangle `$.

Measurement simulation

We simulate shots measurements, and then we extract the relative frequencies for the two possible basis state outcomes $:nbsphinx-math:lvert `0 :nbsphinx-math:rangle ,:nbsphinx-math:lvert 1 :nbsphinx-math:rangle `$.

[9]:
shots = 1000000
counts = model.measure(shots)

Raw counts for each possible outcome:

[10]:
import json

print("Aggregated binary outcomes of the circuit:")
print(json.dumps(counts, sort_keys=True, indent=4))
Aggregated binary outcomes of the circuit:
{
    "0": 407070,
    "1": 592930
}

From the raw counts we can obtain the relative frequencies (aka the probabilities) and compare them with the input sequence shape:

[11]:
plt.figure(figsize=(15, 4), dpi=150)

ax1 = plt.subplot(1, 2, 1)
ax1.stem(sequence, use_line_collection=True, linefmt="w", basefmt="w")
ax1.set_xlabel("Time index t")
ax1.set_ylabel("Input value x")
ax1.set_title("Input sequence")

ax2 = plt.subplot(1, 2, 2)
plot_histogram(counts, ax=ax2)
ax2.set_ylabel("")
ax2.set_title("Probabilities")

plt.show()
../_images/notebooks_02_monodimensional_angular_model_22_0.png

(…)