diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7e68766 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python-envs.pythonProjects": [] +} \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 0924a34..ce47499 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,7 +13,7 @@ certifi==2025.8.3 cffi==2.0.0 charset-normalizer==3.4.3 comm==0.2.3 -contourpy==1.3.3 +contourpy==1.3.0 cycler==0.12.1 debugpy==1.8.17 decorator==5.2.1 @@ -28,7 +28,7 @@ httpcore==1.0.9 httpx==0.28.1 idna==3.10 ipykernel==6.30.1 -ipython==9.5.0 +ipython==8.18.1 ipython_pygments_lexers==1.1.1 ipywidgets==8.1.7 isoduration==20.11.0 @@ -50,10 +50,10 @@ jupyterlab==4.4.7 jupyterlab_pygments==0.3.0 jupyterlab_server==2.27.3 jupyterlab_widgets==3.0.15 -kiwisolver==1.4.9 +kiwisolver==1.4.7 lark==1.2.2 MarkupSafe==3.0.2 -matplotlib==3.10.6 +matplotlib==3.9.4 matplotlib-inline==0.1.7 mistune==3.1.4 mpmath==1.3.0 @@ -63,7 +63,7 @@ nbformat==5.10.4 nest-asyncio==1.6.0 notebook==7.4.5 notebook_shim==0.2.4 -numpy==2.3.3 +numpy==2.0.2 packaging==25.0 pandas==2.3.2 pandocfilters==1.5.1 @@ -95,7 +95,7 @@ rfc3986-validator==0.1.1 rfc3987-syntax==1.1.0 rpds-py==0.27.1 rustworkx==0.17.1 -scipy==1.16.2 +scipy==1.13.1 seaborn==0.13.2 Send2Trash==1.8.3 setuptools==80.9.0 @@ -104,7 +104,7 @@ sniffio==1.3.1 soupsieve==2.8 stack-data==0.6.3 stevedore==5.5.0 -sympy==1.14.0 +sympy==1.13.1 terminado==0.18.1 tinycss2==1.4.0 tornado==6.5.2 diff --git a/task.ipynb b/task.ipynb index 81e5b05..f3e1e9a 100644 --- a/task.ipynb +++ b/task.ipynb @@ -38,7 +38,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -67,9 +67,25 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " ┌───┐ ░ ┌─┐ \n", + "q_0: ┤ X ├─░─┤M├───\n", + " ├───┤ ░ └╥┘┌─┐\n", + "q_1: ┤ H ├─░──╫─┤M├\n", + " └───┘ ░ ║ └╥┘\n", + "c: 2/═════════╩══╩═\n", + " 0 1 \n", + "\n", + "Measurement results: {'11': 499, '01': 525}\n" + ] + } + ], "source": [ "def create_basic_circuit():\n", " \"\"\"\n", @@ -85,12 +101,16 @@ " qc = QuantumCircuit(2, 2)\n", " \n", " # Put qubit 0 in the |1⟩ state.\n", + " qc.x(0) # Apply X gate to qubit 0\n", " \n", " # Put qubit 1 in a superposition state.\n", + " qc.h(1) # Apply Hadamard gate to qubit 1\n", " \n", " # Add a barrier.\n", + " qc.barrier()\n", " \n", " # Measure both qubits.\n", + " qc.measure([0, 1], [0, 1])\n", " \n", " return qc\n", "\n", @@ -120,7 +140,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -136,6 +156,8 @@ " qc = QuantumCircuit(1, 1)\n", " # Apply the appropriate operation to prepare the |+⟩ state.\n", " # Measure the qubit.\n", + " qc.h(0) # Apply Hadamard gate to qubit 0\n", + " qc.measure(0, 0) # Measure the qubit\n", " \n", " return qc\n", "\n", @@ -151,6 +173,9 @@ " qc = QuantumCircuit(1, 1)\n", " # Apply the required operations to prepare the |−⟩ state.\n", " # Measure the qubit.\n", + " qc.h(0) # Apply Hadamard gate to qubit 0\n", + " qc.z(0) # Apply Z gate to qubit 0\n", + " qc.measure(0, 0) # Measure the qubit\n", " \n", " return qc\n", "\n", @@ -166,15 +191,51 @@ " qc = QuantumCircuit(2, 2)\n", " # Apply the operations to create the entangled state.\n", " # Measure both qubits.\n", + " qc.h(0) # Apply Hadamard gate to qubit 0\n", + " qc.cx(0, 1) # Apply CNOT gate with qubit 0 as control and qubit 1 as target\n", + " qc.measure([0, 1], [0, 1]) # Measure both qubits\n", " \n", " return qc\n" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Plus State:\n", + " ┌───┐┌─┐\n", + " q: ┤ H ├┤M├\n", + " └───┘└╥┘\n", + "c: 1/══════╩═\n", + " 0 \n", + "Results: {'0': 529, '1': 495}\n", + "\n", + "Minus State:\n", + " ┌───┐┌───┐┌─┐\n", + " q: ┤ H ├┤ Z ├┤M├\n", + " └───┘└───┘└╥┘\n", + "c: 1/═══════════╩═\n", + " 0 \n", + "Results: {'0': 508, '1': 516}\n", + "\n", + "Bell State:\n", + " ┌───┐ ┌─┐ \n", + "q_0: ┤ H ├──■──┤M├───\n", + " └───┘┌─┴─┐└╥┘┌─┐\n", + "q_1: ─────┤ X ├─╫─┤M├\n", + " └───┘ ║ └╥┘\n", + "c: 2/═══════════╩══╩═\n", + " 0 1 \n", + "Results: {'11': 514, '00': 510}\n" + ] + } + ], "source": [ "# Test each state\n", "states = {\n", @@ -207,9 +268,39 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Constant-0 Oracle:\n", + " \n", + "q_0: \n", + " \n", + "q_1: \n", + " \n", + "\n", + "Constant-1 Oracle:\n", + " \n", + "q_0: ─────\n", + " ┌───┐\n", + "q_1: ┤ X ├\n", + " └───┘\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "<>:5: SyntaxWarning: invalid escape sequence '\\o'\n", + "<>:5: SyntaxWarning: invalid escape sequence '\\o'\n", + "/var/folders/r0/5w_36nps06gd1l18plstmxk00000gn/T/ipykernel_56341/621186683.py:5: SyntaxWarning: invalid escape sequence '\\o'\n", + " The oracle is a unitary operation that maps $|x⟩|y⟩$ to $|x⟩|y \\oplus f(x)⟩$.\n" + ] + } + ], "source": [ "def create_constant_oracle(output):\n", " \"\"\"\n", @@ -228,6 +319,8 @@ " \n", " if output == 1:\n", " # Apply the required operation to the ancilla (qubit 1).\n", + " oracle.x(1) # Apply X gate to qubit 1\n", + " else:\n", " pass\n", " \n", " return oracle\n", @@ -258,7 +351,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -281,6 +374,7 @@ " \"\"\" \n", " oracle = QuantumCircuit(2, name='Constant-1')\n", " # Apply the operation to the ancilla qubit.\n", + " oracle.x(1) # Apply X gate to qubit 1\n", " return oracle\n", "\n", "def create_balanced_identity_oracle():\n", @@ -292,6 +386,7 @@ " \"\"\"\n", " oracle = QuantumCircuit(2, name='Balanced-Identity')\n", " # Apply the appropriate controlled operation.\n", + " oracle.cx(0, 1) # Apply CNOT gate with qubit 0 as control and qubit 1 as target\n", " return oracle\n", "\n", "def create_balanced_not_oracle():\n", @@ -303,14 +398,51 @@ " \"\"\"\n", " oracle = QuantumCircuit(2, name='Balanced-NOT')\n", " # Apply the required operations to the qubits.\n", + " oracle.cx(0, 1) # Apply CNOT gate with qubit 0 as control and qubit 1 as target\n", + " oracle.x(1) # Apply X gate to qubit 1\n", " return oracle\n" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Constant 0:\n", + " \n", + "q_0: \n", + " \n", + "q_1: \n", + " \n", + "\n", + "Constant 1:\n", + " \n", + "q_0: ─────\n", + " ┌───┐\n", + "q_1: ┤ X ├\n", + " └───┘\n", + "\n", + "Balanced Identity:\n", + " \n", + "q_0: ──■──\n", + " ┌─┴─┐\n", + "q_1: ┤ X ├\n", + " └───┘\n", + "\n", + "Balanced NOT:\n", + " \n", + "q_0: ──■───────\n", + " ┌─┴─┐┌───┐\n", + "q_1: ┤ X ├┤ X ├\n", + " └───┘└───┘\n", + "\n" + ] + } + ], "source": [ "# Test your oracles by visualizing them\n", "oracles = {\n", @@ -335,9 +467,24 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 38, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Complete Deutsch Algorithm:\n", + " ┌───┐ ░ ┌───┐┌─┐\n", + "q_0: ┤ H ├──────░───■──┤ H ├┤M├\n", + " ├───┤┌───┐ ░ ┌─┴─┐└───┘└╥┘\n", + "q_1: ┤ X ├┤ H ├─░─┤ X ├──────╫─\n", + " └───┘└───┘ ░ └───┘ ║ \n", + "c: 1/════════════════════════╩═\n", + " 0 \n" + ] + } + ], "source": [ "def deutsch_algorithm(oracle):\n", " \"\"\"\n", @@ -359,15 +506,21 @@ " qc = QuantumCircuit(2, 1)\n", " \n", " # Step 1: Initialize the ancilla.\n", + " qc.x(1) # Put ancilla in the |1⟩ state\n", " \n", " # Step 2: Apply the superposition-creating gate to both qubits.\n", - " \n", + " qc.h([0, 1]) # Put input & ancilla in superposition state\n", + " qc.barrier()\n", + "\n", " # Step 3: Apply the oracle.\n", - " \n", + " qc.compose(oracle, inplace=True)\n", + "\n", " # Step 4: Apply a final superposition-creating gate to the input qubit only.\n", - " \n", + " qc.h(0) # Apply Hadamard gate to input qubit 0\n", + "\n", " # Step 5: Measure the input qubit.\n", - " \n", + " qc.measure(0, 0) # Measure input qubit 0 into classical bit 0\n", + "\n", " return qc\n", "\n", "# Visualize the complete algorithm with one oracle\n", @@ -379,9 +532,34 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 39, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Deutsch Algorithm Test Results:\n", + "==================================================\n", + "Constant 0:\n", + " Results: {'0': 1024}\n", + " Type: CONSTANT\n", + "\n", + "Constant 1:\n", + " Results: {'0': 1024}\n", + " Type: CONSTANT\n", + "\n", + "Balanced (x):\n", + " Results: {'1': 1024}\n", + " Type: BALANCED\n", + "\n", + "Balanced (1⊕x):\n", + " Results: {'1': 1024}\n", + " Type: BALANCED\n", + "\n" + ] + } + ], "source": [ "def test_deutsch_algorithm():\n", " \"\"\"Test Deutsch algorithm with all four oracles\"\"\"\n", @@ -446,9 +624,36 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 46, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3-qubit balanced oracle (mask='101'):\n", + " \n", + "q_0: ──■───────\n", + " │ \n", + "q_1: ──┼───────\n", + " │ \n", + "q_2: ──┼────■──\n", + " ┌─┴─┐┌─┴─┐\n", + "q_3: ┤ X ├┤ X ├\n", + " └───┘└───┘\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "<>:11: SyntaxWarning: invalid escape sequence '\\s'\n", + "<>:11: SyntaxWarning: invalid escape sequence '\\s'\n", + "/var/folders/r0/5w_36nps06gd1l18plstmxk00000gn/T/ipykernel_56341/2105454869.py:11: SyntaxWarning: invalid escape sequence '\\s'\n", + " This implements the inner product $f(x) = \\sum_{i} x_i \\cdot mask_i \\pmod{2}$.\n" + ] + } + ], "source": [ "def create_dj_oracle(n, function_type, mask=None):\n", " \"\"\"\n", @@ -476,13 +681,17 @@ " if function_type == 'constant':\n", " if mask == '1': \n", " # Apply the appropriate operation to the ancilla (qubit n).\n", + " QuantumCircuit.x(n) # Apply X gate to the ancilla qubit\n", + " else:\n", " pass\n", " \n", " elif function_type == 'balanced':\n", " if mask:\n", " # Iterate through the mask and apply a controlled operation for each '1' bit.\n", - " for i, bit in enumerate(mask):\n", + " for i, bit in enumerate(reversed(mask)):\n", " if bit == '1':\n", + " oracle.cx(i, n) # Apply CNOT gate with qubit i as control and ancilla n as target\n", + " else:\n", " pass\n", " \n", " return oracle\n", @@ -502,9 +711,28 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 47, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Complete 3-qubit Deutsch-Jozsa circuit:\n", + " ┌───┐ ┌───┐ ┌─┐ \n", + "q_0: ┤ H ├───────■──┤ H ├──────────┤M├───\n", + " ├───┤┌───┐ │ └┬─┬┘ └╥┘ \n", + "q_1: ┤ H ├┤ H ├──┼───┤M├────────────╫────\n", + " ├───┤└───┘ │ └╥┘ ┌───┐ ║ ┌─┐\n", + "q_2: ┤ H ├───────┼────╫────■──┤ H ├─╫─┤M├\n", + " ├───┤┌───┐┌─┴─┐ ║ ┌─┴─┐└───┘ ║ └╥┘\n", + "q_3: ┤ X ├┤ H ├┤ X ├──╫──┤ X ├──────╫──╫─\n", + " └───┘└───┘└───┘ ║ └───┘ ║ ║ \n", + "c: 3/═════════════════╩═════════════╩══╩═\n", + " 1 0 2 \n" + ] + } + ], "source": [ "def deutsch_jozsa_algorithm(n, oracle):\n", " \"\"\"\n", @@ -527,14 +755,22 @@ " qc = QuantumCircuit(n + 1, n)\n", " \n", " # Step 1: Initialize the ancilla.\n", + " qc.x(n) # Put ancilla in |1⟩ state\n", + " qc.h(n) # Put ancilla in superposition state\n", " \n", " # Step 2: Apply the superposition-creating gate to all qubits.\n", + " for i in range(n):\n", + " qc.h(i) # Apply Hadamard gate to each input qubit\n", " \n", " # Step 3: Apply the oracle.\n", + " qc.compose(oracle, inplace=True)\n", " \n", " # Step 4: Apply the final superposition-creating gate to the input qubits.\n", + " for i in range(n):\n", + " qc.h(i) # Apply Hadamard gate to each input qubit\n", " \n", " # Step 5: Measure the input qubits.\n", + " qc.measure(range(n), range(n))\n", " \n", " return qc\n", "\n", @@ -553,9 +789,48 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 43, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Deutsch-Jozsa Test Results:\n", + "============================================================\n", + "\n", + "Test: n=2, constant, mask=None\n", + "Expected: Should measure 00\n", + "Results: {'00': 1024}\n", + "Most frequent: 00\n", + "Correct: True\n", + "\n", + "Test: n=2, constant, mask=1\n", + "Expected: Should measure 00\n", + "Results: {'00': 1024}\n", + "Most frequent: 00\n", + "Correct: True\n", + "\n", + "Test: n=3, balanced, mask=101\n", + "Expected: Should measure 101\n", + "Results: {'000': 1024}\n", + "Most frequent: 000\n", + "Correct: False\n", + "\n", + "Test: n=3, balanced, mask=111\n", + "Expected: Should measure 111\n", + "Results: {'000': 1024}\n", + "Most frequent: 000\n", + "Correct: False\n", + "\n", + "Test: n=2, balanced, mask=01\n", + "Expected: Should measure 01\n", + "Results: {'00': 1024}\n", + "Most frequent: 00\n", + "Correct: False\n" + ] + } + ], "source": [ "def test_deutsch_jozsa():\n", " \"\"\"Test with multiple cases\"\"\"\n", @@ -600,6 +875,11 @@ } ], "metadata": { + "kernelspec": { + "display_name": ".venv (3.13.7)", + "language": "python", + "name": "python3" + }, "language_info": { "codemirror_mode": { "name": "ipython", @@ -610,7 +890,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": 3 + "version": "3.13.7" } }, "nbformat": 4,