Qiskit implementation
In the previous lesson, we took a first look at the Statevector
and Operator
classes in Qiskit, and used them to simulate operations and measurements on single qubits.
In this section, we'll use these classes to explore the behavior of multiple qubits.
from qiskit import __version__
print(__version__)
Output:
2.1.1
We'll start by importing the Statevector
and Operator
classes, as well as the square root function from NumPy
.
Hereafter, generally speaking, we'll take care of all of our required imports first within each lesson.
from qiskit.quantum_info import Statevector, Operator
from numpy import sqrt
Tensor products
The Statevector
class has a tensor
method, which returns the tensor product of that Statevector
with another, given as an argument.
The argument is interpreted as the tensor factor on the right.
For example, below we create two state vectors representing and and use the tensor
method to create a new vector,
Notice here that we're using the from_label
method to define the states and rather than defining them ourselves.
zero = Statevector.from_label("0")
one = Statevector.from_label("1")
psi = zero.tensor(one)
display(psi.draw("latex"))
Output:
Other allowed labels include "+" and "-" for the plus and minus states, as well as "r" and "l" (short for "right" and "left") for the states
Here's an example of the tensor product of and
plus = Statevector.from_label("+")
minus_i = Statevector.from_label("l")
phi = plus.tensor(minus_i)
display(phi.draw("latex"))
Output:
An alternative is to use the ^
operation for tensor products, which naturally gives the same results.
display((plus ^ minus_i).draw("latex"))
Output:
The Operator
class also has a tensor
method (as well as a from_label
method), as we see in the following examples.
H = Operator.from_label("H")
Id = Operator.from_label("I")
X = Operator.from_label("X")
display(H.tensor(Id).draw("latex"))
display(H.tensor(Id).tensor(X).draw("latex"))
Output:
Again, like in the vector case, the ^
operation is equivalent.
display((H ^ Id ^ X).draw("latex"))
Output:
Compound states can be evolved using compound operations as we would expect — just like we saw for single systems in the previous lesson. For example, the following code computes the state for (which was already defined above).
display(phi.evolve(H ^ Id).draw("latex"))
Output:
Here is some code that defines a operation and calculates for To be clear, this is a operation for which the left-hand qubit is the control and the right-hand qubit is the target. The result is the Bell state
CX = Operator([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]])
psi = plus.tensor(zero)
display(psi.evolve(CX).draw("latex"))
Output:
Partial measurements
In the previous lesson, we used the measure
method to simulate a measurement of a quantum state vector.
This method returns two items: the simulated measurement result, and the new Statevector
given this measurement.
By default, measure
measures all qubits in the state vector.
We can, alternatively, provide a list of integers as an argument, which causes only those qubit indices to be measured.
To demonstrate this, the code below creates the state
and measures qubit number 0, which is the rightmost qubit. (Qiskit numbers qubits starting from 0, from right to left. We'll return to this numbering convention in the next lesson.)
w = Statevector([0, 1, 1, 0, 1, 0, 0, 0] / sqrt(3))
display(w.draw("latex"))
result, state = w.measure([0])
print(f"Measured: {result}\nState after measurement:")
display(state.draw("latex"))
result, state = w.measure([0, 1])
print(f"Measured: {result}\nState after measurement:")
display(state.draw("latex"))
Output:
Measured: 0
State after measurement:
Measured: 00
State after measurement: