Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Womanium Final Assignment - Petra Brčić #382

Merged
merged 1 commit into from
Jul 30, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
265 changes: 265 additions & 0 deletions community/womanium/assignments/Petra_Brcic_hw4.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,265 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 46,
"metadata": {},
"outputs": [],
"source": [
"from classiq import *\n",
"from classiq.execution import ExecutionPreferences"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Quantum walk on a line\n",
"We want to perform a quantum walk on a line with 16 nodes:\n",
"#### 0--1--2--3--...--14--15\n",
"To perform the walk, we move from the current node to one of the adjecent nodes with equal probability. Notice that at the ends of the line we only have one adjecent node, therefore only one option to move.\n",
"We require two components: the Coin operator C which determines the next destination of the walker, and the Shift operator which \"shift\" the walker to the next destination."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Coin operator"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [],
"source": [
"@qfunc\n",
"def prepare_minus(x: QBit):\n",
" '''\n",
" Prepare the qubit x in the minus state.\n",
" '''\n",
" X(x)\n",
" H(x)"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [],
"source": [
"@qfunc\n",
"def diffuzer_oracle(aux: Output[QNum],x:QNum):\n",
" '''\n",
" Perform the diffuzer oracle: check whether the qnum x is zero, and save the result in the aux qnum.\n",
" '''\n",
" aux^=(x!=0)"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [],
"source": [
"@qfunc\n",
"def zero_diffuzer(x: QNum):\n",
" '''\n",
" Perform the zero diffuzer: reflect the qnum x around zero. If x==0, then it's not affected, otherwise picks up a minus sign.\n",
" '''\n",
" aux = QNum('aux')\n",
" allocate(1,aux)\n",
" within_apply(compute=lambda: prepare_minus(aux),\n",
" action=lambda: diffuzer_oracle)"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [],
"source": [
"def C_iteration(i:int, vertices: QNum, adjacent_vertices:QNum):\n",
" '''\n",
" Perform the Coin operation at the current node i.\n",
" '''\n",
" prob = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]\n",
" if i==0: # we can't loop around when we are at the edges of the line \n",
" prob[1]=1.\n",
" elif i==15:\n",
" prob[14]=1.\n",
" else:\n",
" prob[(i+1)]=0.5\n",
" prob[(i-1)]=0.5\n",
" print(f'State={i}, prob vec ={prob}')\n",
" \n",
" control(ctrl=vertices==i,\n",
" operand=lambda: within_apply(\n",
" compute= lambda: inplace_prepare_state(probabilities=prob, bound=0.01, target=adjacent_vertices),\n",
" action= lambda: zero_diffuzer(adjacent_vertices)))\n"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [],
"source": [
"@qfunc \n",
"def C_operator(vertices:QNum, adjacent_vertices: QNum):\n",
" '''\n",
" Perform the Coin operation at all vertices.\n",
" '''\n",
" for i in range(2**size):\n",
" C_iteration(i,vertices,adjacent_vertices)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Shift operator"
]
},
{
"cell_type": "code",
"execution_count": 52,
"metadata": {},
"outputs": [],
"source": [
"@qfunc\n",
"def edge_oracle(res:Output[QBit], vertices: QNum, adjacent_vertices: QNum):\n",
" '''\n",
" Check if the edge exists. i.e. whether two verties are adjecent.\n",
" '''\n",
" distance = vertices-adjacent_vertices\n",
" res |= ((distance == 1) | (distance == -1)) # abs() is not currently in supported functions"
]
},
{
"cell_type": "code",
"execution_count": 53,
"metadata": {},
"outputs": [],
"source": [
"@qfunc \n",
"def bitwise_swap(x: QArray[QBit], y:QArray[QBit]):\n",
" '''\n",
" Bitwise swap of the values x and y.\n",
" '''\n",
" repeat(count= x.len,\n",
" iteration= lambda i: SWAP(x[i],y[i]))"
]
},
{
"cell_type": "code",
"execution_count": 54,
"metadata": {},
"outputs": [],
"source": [
"@qfunc \n",
"def S_operator(vertices:QNum, adjacent_vertices: QNum):\n",
" '''\n",
" Perform the Shift operator: move from the current vertex onto the adjecent vertices.\n",
" '''\n",
" res = QNum('res')\n",
" edge_oracle(res,vertices,adjacent_vertices)\n",
" control(ctrl= res==1,\n",
" operand= lambda: bitwise_swap(vertices,adjacent_vertices))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Quantum walk"
]
},
{
"cell_type": "code",
"execution_count": 55,
"metadata": {},
"outputs": [],
"source": [
"@qfunc \n",
"def main(vertices:Output[QNum], adjacent_vertices:Output[QNum]):\n",
" '''\n",
" Perform the quantum walk over the vertices by applying the Coin operator (to find the next nodes), followed by \n",
" the Shift operator (to perform the movement onto the next nodes).\n",
" '''\n",
"\n",
" allocate(size,vertices)\n",
" hadamard_transform(vertices)\n",
" allocate(size, adjacent_vertices)\n",
"\n",
" C_operator(vertices,adjacent_vertices)\n",
" S_operator(vertices,adjacent_vertices)"
]
},
{
"cell_type": "code",
"execution_count": 58,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"State=0, prob vec =[0, 1.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n",
"State=1, prob vec =[0.5, 0, 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n",
"State=2, prob vec =[0, 0.5, 0, 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n",
"State=3, prob vec =[0, 0, 0.5, 0, 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n",
"State=4, prob vec =[0, 0, 0, 0.5, 0, 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n",
"State=5, prob vec =[0, 0, 0, 0, 0.5, 0, 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n",
"State=6, prob vec =[0, 0, 0, 0, 0, 0.5, 0, 0.5, 0, 0, 0, 0, 0, 0, 0, 0]\n",
"State=7, prob vec =[0, 0, 0, 0, 0, 0, 0.5, 0, 0.5, 0, 0, 0, 0, 0, 0, 0]\n",
"State=8, prob vec =[0, 0, 0, 0, 0, 0, 0, 0.5, 0, 0.5, 0, 0, 0, 0, 0, 0]\n",
"State=9, prob vec =[0, 0, 0, 0, 0, 0, 0, 0, 0.5, 0, 0.5, 0, 0, 0, 0, 0]\n",
"State=10, prob vec =[0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5, 0, 0.5, 0, 0, 0, 0]\n",
"State=11, prob vec =[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5, 0, 0.5, 0, 0, 0]\n",
"State=12, prob vec =[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5, 0, 0.5, 0, 0]\n",
"State=13, prob vec =[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5, 0, 0.5, 0]\n",
"State=14, prob vec =[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5, 0, 0.5]\n",
"State=15, prob vec =[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.0, 0]\n",
"Opening: https://platform.classiq.io/circuit/8ee86a61-9d31-4999-9bf4-740426069b92?version=0.43.3\n"
]
}
],
"source": [
"size = 4 # we need 4 qubits to encode 16 nodes\n",
"qmod = create_model(main)\n",
"qprog = synthesize(qmod)\n",
"show(qprog)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
}
},
"nbformat": 4,
"nbformat_minor": 2
}