Skip to content

Shiro-Raven/shiroq-quantum-simulator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

💥 ShiroQ Quantum Computer 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. 😄

Pre-requisites

  • NumPy
  • Matplotlib
  • CuPy (Optional, needed for GPU acceleration)
  • SciPy (Suggested for variational quantum algorithms, using its optimize)

Features

  • Support for most common single-qubit quantum gates, as well as the Toffoli and Swap gates, along with their controlled versions.
  • Support for the parametric Rx, Ry, Rz, U1, and U3 gates.
  • Ability to run variational quantum algorithms.
  • OpenQASM translator to run your circuits on other frameworks and real hardware (or even apply some ZX-calculus magic).

Examples can be found in the notebooks folder.

Components

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.

Usage

  • Manual Circuit Building

    1. The circuit logic is contained in the QuantumRegister class. To start, initialise a register with a set size, with all qubits initialised to the ground state:
    example_reg = QuantumRegister(5)
    1. One can then initialise any of the qubits to any sound quantum state. The common base states {0, 1, +, -} are available from the class for convenience. Note that big endian indexing is used by default. If one prefers little endian indexing, the function set_endianness can be used:
    example_reg.initialise_qubit(0, QuantumRegister.plus)
    1. Once you are happy with the initial qubit states, you can start adding gates to your circuit, by passing the gate and the target qubits. For this, the 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])
    1. Adding gates to the circuit does not automatically apply them to the current state of the system. For this, you need to call the apply function simply as follows:
    example_reg.apply()
    1. To carry out a measurement, pass the number of shots and the qubits you want to measure as parameters to the measurement function. The function returns a dictionary of the measured states:
    results_dict = example_reg.measure(1000) # Implicit measurement of all qubits
    first_qubit_dict = example_reg.measure(1000, [0]) # Explicit choice of qubits
    1. If you wish to transform the added gates to a QASM file, simply call the translator's function. Note that measurement operators need to be explicitly passed to the translator as indices of the qubits to be measured.
    example_reg.store_as_qasm('sample_filename', [0 ,1, 2])
  • Automated Circuit Building

    1. 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)
    1. Afterwards, the 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)
    1. 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)

About

A simple quantum computer statevector simulator.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published