1. qib Basics¶
In this basic example, we construct and “run” a quantum circuit which prepares a Bell state.
1.1. Circuit construction¶
[1]:
# import the qib package; see the README for installation instructions
import qib
As first step, we define a qubit “field” with two sites, which is essentially a quantum register containing two qubits. Fields can also host fermionic particles, for example, which will become relevant for defining chemistry Hamiltonians.
[2]:
field = qib.field.Field(qib.field.ParticleType.QUBIT, qib.lattice.IntegerLattice((2,)))
[3]:
# retrieve the two qubits of the field
qa = qib.field.Qubit(field, 0)
qb = qib.field.Qubit(field, 1)
Next, we define standard Hadamard and CNOT quantum gates and associate the qubits with them. In qib, gates contain a reference to the qubits which they act on.
[4]:
# Hadamard gate
hadamard = qib.HadamardGate(qa)
# CNOT gate
cnot = qib.ControlledGate(qib.PauliXGate(qb), 1).set_control(qa)
We now construct a circuit out of the gates. The gates “know” already which qubits they are applied to.
[5]:
circuit = qib.Circuit()
circuit.append_gate(hadamard)
circuit.append_gate(cnot)
The following code generates the matrix representation of the circuit. The list of fields passed as argument determines the logical ordering of the qubits.
[6]:
circuit.as_matrix([field]).toarray()
[6]:
array([[ 0.70710678, 0. , 0.70710678, 0. ],
[ 0. , 0.70710678, 0. , 0.70710678],
[ 0. , 0.70710678, 0. , -0.70710678],
[ 0.70710678, 0. , -0.70710678, 0. ]])
1.2. Running the circuit¶
We use qib’s built-in statevector simulator to “run” the quantum circuit:
[7]:
statesim = qib.simulator.StatevectorSimulator()
[8]:
ψ = statesim.run(circuit, [field], None)
As expected, ψ is a Bell state:
[9]:
ψ
[9]:
array([0.70710678, 0. , 0. , 0.70710678])
Alternatively, qib also implements a tensor network simulator:
[10]:
netsim = qib.simulator.TensorNetworkSimulator()
[11]:
ψn = netsim.run(circuit, [field], None)
The output quantum state is represented as tensor, using a tensor “leg” (or axis) for each qubit wire.
[12]:
ψn
[12]:
array([[0.70710678, 0. ],
[0. , 0.70710678]])
We obtain the usual statevector by flattening the tensor:
[13]:
ψn.reshape(-1)
[13]:
array([0.70710678, 0. , 0. , 0.70710678])