Skip to content

Latest commit

History

47 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

This is a simple implementation of quantum circuitry emulation framework. Some comment's on how it's implemented are on my blog.

Have you ever wondered whether the black-box boolean function $f: \lbrace 0,1\rbrace \to \lbrace 0, 1\rbrace$ is constant and needed to compute the answer really quickly using a quantum computer, but actually very slowly because of emulation!? The infamously pointless Deutsch-Jozsa algorithm is implemented using this framework for you to solve this problem while evaluating $f$ only once (on a certain superposition of 0 and 1)!

This framework is kind of similar to QisKit but less powerful, so if you want to do something serious with quantum computation use QisKit instead. I wanted to try to implement this myself as a hobby project and I didn't inspect QisKit sources and only learned about it when I was finishing this.

The code is designed as a re-usable and extensible OOP/lazy-evaluation library.

I guess it could be used for educational purposes, or something?

The Deutsch-Jozsa quantum circuit: Circuit diagram

That can be implemented (here for simplicity $n=1$ but can be easily generalized) using the following code:

fromgatesimportBooleanReversibleGate, HadamardGate, TensorProductGate, IdentityGate, CircuitfromqubitsimportQubitArrayfromtypingimportCallable, CollectionclassDeutschOracle(BooleanReversibleGate):
def__init__(self, f: Callable[[bool], bool]):
super().__init__(lambdax, y: (x, y^f(x)))
defdeutsh_algorithm(f: Callable[[bool], bool]) ->Collection[float]:
circuit=Circuit( # lazy declarationHadamardGate(2),
DeutschOracle(f),
TensorProductGate(HadamardGate(1), IdentityGate(1))
)
input_qubits=QubitArray.from_bits([0, 1])
final_pure_state=circuit(input_qubits) # Actual emulation happens herereturnfinal_pure_state.measure() # Get probabilities of observations using Born ruleif__name__=="__main__":
print(deutsh_algorithm(lambdax: False)) # constantprint(deutsh_algorithm(lambdax: True)) # constantprint(deutsh_algorithm(lambdax: x)) # balancedprint(deutsh_algorithm(lambdax: notx)) # balanced

The quantum algorithm will differentiate the balanced and the constant boolean functions using a single pass, something that is impossible on a classical computer. The output from the block above is:

[0.5, 0.5, 0, 0]
[0.5, 0.5, 0, 0]
[ 0, 0, 0.5, 0.5]
[ 0, 0, 0.5, 0.5]

These probabilities correspond to the observations of $|00\rangle, |01\rangle, |10\rangle$ and $|11\rangle$ respectively. Only the first bit is relevant.

Cool video explaing the homemade hardware implementation for this: https://www.youtube.com/watch?v=tHfGucHtLqo

The gates API should be flexible enough to build various gates from the primitives. For example:

fromgatesimportCircuit, HadamardGate, ControlledGate, PauliX, BooleanReversibleGate, \
PhaseShiftGate, Oraclefrommathimportpiasπcnot=ControlledGate(2, PauliX(), at_qubit=1, controlled_by=0)
toffoli=ControlledGate(3, cnot, at_qubit=1, controlled_by=0)
swap=BooleanReversibleGate(lambdax, y: (y, x))
sqrt_not=Circuit(HadamardGate(1), PhaseShiftGate(-π/2), HadamardGate(1))
sqrt_swap=Oracle([
[1, 0, 0, 0],
[0, 0.5+0.5j, 0.5-0.5j, 0],
[0, 0.5-0.5j, 0.5+0.5j, 0],
[0, 0, 0, 1]
])

About

Simple quantum computing emulation framework

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages