Skip to content
/ qxn Public

qxn is an open-source library for noiseless quantum circuit and algorithm simulation.

License

Notifications You must be signed in to change notification settings

DJayalath/qxn

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

qxn

qxn

Release Build License Documentation

Releases | License | Documentation

qxn is an open-source library for noiseless quantum circuit and algorithm simulation.

qxn is designed for mocking and verifying the behaviour of quantum algorithms quickly and efficiently through programmatically defined quantum oracles.

An unmaintained GUI for this library is also available.

...
quantumMachine.addGate(new Oracle(0, 2, 2, (x) -> {
    if (x == 0b00 || x == 0b01)
        return true;
    return false;
}));
...

Installation

Download the latest "fat" jar file from the releases and import into your java project.

Getting Started

STEP 1: Construct a quantum machine with your desired number of qubits

// Initialise a quantum virtual machine with 2 'wires' (2-qubit register)
QuantumMachine myQuantumMachine = new QuantumMachine(2);

STEP 2: Define your quantum circuit

...
myQuantumMachine.addGate(new H(0)); // Add Hadamard gate to wire 0
myQuantumMachine.addGate(new X(1)); // Add Pauli-X gate to wire 1
...

STEP 3: Run your quantum algorithm

...
myQuantumMachine.execute(); // Executes the quantum algorithm on the virtual quantum machine
myQuantumMachine.printState(); // Shows the final resulting bit strings and their respective probabilities

Some Notes:

  • Wires/Qubits are indexed starting from zero
  • The quantum virtual machine executes gates in the order they are added
  • The quantum machine will clear the internal set of gates after calling execute()

Using oracles

The defining feature of qxn is the ability to define oracles not only via a matrix but also through lambda functions.

An oracle is defined by a linear map U : (x, y) -> (x, y XOR f(x))

With qxn, you can define the function f(x) through a boolean lambda function:

// Example oracle where x is an 8-qubit register (wires 0-7) and y is on wire 8
// The lambda defines f(x) = 1 whenever x is even and f(x) = 0 otherwise
Oracle myOracle = new Oracle(0, 8, 8, (x) -> x % 2 == 0);
myQuantumMachine.addGate(myOracle);

When the lambda evaluates to true, f(x) = 1, and f(x) = 0 otherwise. The lambda allows you to provide a mapping for each possible input x.

qxn will generate a matrix for your oracle using the function definition which you can access:

myOracle.getMatrix().print();

qxn will even check if the provided function evaluates to a unitary matrix and warn you if it does not!

For an example of oracles in action, see the Deutsch-Josza algorithm example.

Useful features

View underlying quantum state

qxn is a Schrödinger full state-vector simulator so you can access the underlying quantum state at any time.

After calling execute() on your quantum virtual machine, you can view the quantum state matrix with myQuantumMachine.getQubits().print()

Measure qubits

You can measure qubits to retrieve a classical bit. This, like a real quantum machine, will collapse the underlying quantum state to the measured result.

int classicalBit = myQuantumMachine.measure(0); // Measure state of wire 0 (0th qubit)

Custom gates

qxn gives you the ability to define gates and oracles using matrices:

// Define the identity matrix to create a gate that preserves state (I gate)
ComplexMatrix myGateMatrix = new ComplexMatrix(2, 2);
myGateMatrix.data[0][0] = new Complex(1, 0);
myGateMatrix.data[0][1] = new Complex(0, 0);
myGateMatrix.data[1][0] = new Complex(0, 0);
myGateMatrix.data[1][1] = new Complex(1, 0);

Gate myCustomGate = new CustomGate(0, 1, myGateMatrix);

Controlled gates

You can make your own controlled gates using qxn's controlled gate composition:

// Create a controlled X gate with control wire 1
Gate CX = new C(new X(2), 1);

// Create a gate with two control wires by composition of controlled gates
Gate CCX = new C(CX, 0)

Examples

Quantum Teleportation

QuantumMachine teleportationMachine = new QuantumMachine(3);

// Set qubit to teleport in 0th wire (Remove X gate here to teleport 0 instead)
teleportationMachine.addGate(new X(0));
System.out.println("TELEPORTING: 1");

// Construct bell state between Alice and Bob (entangled pair) in wires 1 and 2

// Add Hadamard gate to wire 1
teleportationMachine.addGate(new H(1));
// Add CNOT gate to wire 1 (control) and wire 2 (target)
teleportationMachine.addGate(new CNOT(1, 2));

// Teleportation circuit

// Add CNOT gate to wire 0 (control) and wire 1 (target)
teleportationMachine.addGate(new CNOT(0, 1));
// Add Hadamard gate to wire 0
teleportationMachine.addGate(new H(0));

// Execute quantum machine        
teleportationMachine.execute();

// Measure state of wire 0 (collapses state and gives classical bit)
int m1 = teleportationMachine.measure(0);
// Measure state of wire 1 (collapses state and gives classical bit)
int m2 = teleportationMachine.measure(1);

// Apply correction
if (m2 == 1) {
    teleportationMachine.addGate(new X(2));
}
if (m1 == 1) {
    teleportationMachine.addGate(new Z(2));
}

teleportationMachine.execute();

System.out.println("RESULT: " + teleportationMachine.measure(2));

Deutsch-Josza Algorithm

// Construct a 9-qubit machine where x is the first 8 wires and y is the last wire
QuantumMachine deutschJoszaMachine = new QuantumMachine(9);

// Add Hadamard gate to entangle all x inputs (initially all |0>)
for (int i = 0; i < 8; i++)
    deutschJoszaMachine.addGate(new H(i));

// Initialise y to |1>
deutschJoszaMachine.addGate(new X(8));
// Apply Hadamard to entangle y
deutschJoszaMachine.addGate(new H(8));

// Use a functionally-defined oracle for ease
// This function definition should result in a balanced boolean function f(x) as it returns 1
// whenever x is even. Our algorithm should therefore determine this to be a balanced function
deutschJoszaMachine.addGate(new Oracle(0, 8, 8, (x) -> x % 2 == 0));

// Interfere bits of x
for (int i = 0; i < 8; i++)
    deutschJoszaMachine.addGate(new H(i));

deutschJoszaMachine.execute();

// We know that P(x = 0) = 1 if f(x) constant and P(x = 0) = 0 if f(x) balanced
// Therefore if the sum of the bits of x measured is 0, f(x) is constant,
// otherwise it is balanced
int bitSum = 0;
for (int i = 0; i < 8; i++)
    bitSum += deutschJoszaMachine.measure(i);

System.out.println((bitSum == 0) ? "CONSTANT" : "BALANCED");

About

qxn is an open-source library for noiseless quantum circuit and algorithm simulation.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages