A simple quantum computer statevector simulator.
This is a simple quantum computer simulator implemented in Python as the screening task for QOSF‘s Quantum Computing Mentorship Program. This submission was officially chosen by one of the mentors and I am one of the Winter 2020 cohort mentees. 😄
optimize
)Examples can be found in the notebooks folder.
The simulator consists of the following components:
register.py
: This is where most of the magic happens. This file contains the QuantumRegister
class which contains most of the simulators logic.gate.py
: This file is responsible for creating reusable instances of all supported gates that can be added to your quantum register, using the QuantumGate
class. program_parser.py
: This file contains the logic for parsing a program as detailed in the explanation of the task, and compiling the parameters needed for runnning that program in our QuantumRegister
.utils.py
: This file contains some helper functions for calculating tensor products, reordering the wiring of a quantum gate, and creating an arbitrary state from Bloch sphere angles with a global phase, and plotting counts.openqasm.py
: This file contains the translation to OpenQASM logic.Manual Circuit Building
QuantumRegister
class. To start, initialise a register with a set size, with all qubits initialised to the ground state:
example_reg = QuantumRegister(5)
set_endianness
can be used:
example_reg.initialise_qubit(0, QuantumRegister.plus)
QuantumGate
class can be used as a gate builder. Just pass the gate name to the constructor:
x_gate = QuantumGate('X')
controlled_z = QuantumGate('cz')
controlled_u3 = QuantumGate('cu3', 3.1415, 0, -1.5707)
example_reg.add_gate(x_gate, [0,1,2])
example_reg.add_gate(controlled_z, [0, 4])
example_reg.add_gate(controlled_u3, [3, 0])
apply
function simply as follows:
example_reg.apply()
results_dict = example_reg.measure(1000) # Implicit measurement of all qubits
first_qubit_dict = example_reg.measure(1000, [0]) # Explicit choice of qubits
example_reg.store_as_qasm('sample_filename', [0 ,1, 2])
Automated Circuit Building
Instead of manually adding gates, one can parse a list of dictionaries containing the configurations of the different gates of the circuit. First, inintialise the circuit similar to steps 1 and 2 above. Then, the list has to be passed to parse_program
function in utils.py
. The path to a file containing the list can also be used.
circuit_conf = [
{ "gate": "h", "target": [0] },
{ "gate": "cx", "target": [0, 1] },
{ "gate": "u1", "params" : {"theta": 3.14159265}, "target": [0, 1] },
]
parsed_program = parser.parse_program(circuit_conf)
run_program
of QuantumRegister
must be invoked of the parsed list. This function automatically applies any outstanding gates to the state of the system, unlike before.
example_reg.run_program(parsed_program)
Several programs can be run consequently. One can also use both approaches to build circuits (remember to call apply
if final addition of gates was manual!):
example_reg.run_program(program_1)
example_reg.add_gate(QuantumGate('H'), [0,2,1])
example_reg.run_program(program_2)