shor-team / shor

The Python Quantum Computing Library
MIT License
8 stars 3 forks source link

Improve and Implement Functional API #3

Open shordev opened 4 years ago

shordev commented 4 years ago

Functional APIs more directly represent quantum computing circuit diagrams / graphs.

Really, we can support a directed asynchronous graph (similar to neural network programming) so we should change the API from class based to functional.

circuit = Circuit() circuit.add(Qbits(5)) circuit.add(Hadamard()) circuit.add(Measure())

sess = Session(QuantumSimulator()) sess.run(circuit, times=1000)

Would be better represented by the following functional API X = Qbits(count=5, initial_state=[0, 1, 0, 0, 0]) X = Hadamard()(X) Y = Measure()(X)

circuit = Circuit(inputs=X, outputs=Y) result = circuit.run(backend=QuantumSimulator(), times=100)

It then allows you to apply different circuits to different inputs and combine the results:

X1 = Qbits(count=2) X1 = Hadamard()(X1) X2 = Qbits(count=2) X = CNOT()(X1, X2) Y = Measure()(X)

circuit = Circuit(inputs=X, outputs=Y) result = circuit.run(backend=QuantumSimulator(), times=100)

shordev commented 3 years ago

Thought about this some more, not sure a functional API makes sense. Quantum algorithms have quantum "state" vectors (2^n), which aren't visible, and also aren't copy-able (no-clone thm).

Functional APIs are good for DAGs, which can have arrows that point to earlier points in the graph.

The Quantum Circuit is more like a tree in that no edges will point back to earlier points in time / levels on the tree.

We want to avoid applying a function to a q = Qbits(3) Q = H(q) R = Z(Q[1]) S = H(Q[1])

Here we have attempted to apply a gate to the same Qbit (1) at the same point in time, which is illegal. The only way to enforce this is with a proper reference to the state of the circuit. q = Qbits(4) bits = Bits(4) qc = QuantumCircuit() # Optional

All of the following are equivalant

qc += H(q[0]) + X(q[1]) qc.add(H(q[0]).add(X(q[1])) qc = qc.add(H(q[0]).add(X(q[1])

I think where this will be useful is when overriding the operator for adding layers together. We should have that return a sub circuit / QuantumCircuit. We just need some way to may to provide a mapping of the qbits from the parent circuit to the child circuit