{ "cells": [ { "cell_type": "markdown", "id": "8b7726d0", "metadata": {}, "source": [ "# Ripple Carry Adder\n", "\n", "**Download Notebook** - {nb-download}`ripple_carry_addition_example.ipynb`\n", "\n", "Example of ripple carry adder circuit using Guppy." ] }, { "cell_type": "code", "execution_count": 1, "id": "4e5bd97d", "metadata": {}, "outputs": [], "source": [ "from guppylang import guppy\n", "from guppylang.std.builtins import array, comptime, output\n", "from selene_sim import Quest, build\n", "from hugr.qsystem.result import QsysResult\n", "from guppylang.std.quantum import qubit, discard_array, measure_array, measure, collect_measurements\n", "from guppyalgos.primitives.arithmetic import adder_ripple_cuccaro_carry_out, subtractor_ripple_cuccaro_carry_out\n", "from guppyalgos.utils import int_to_bits, apply_bitstring, qarray" ] }, { "cell_type": "markdown", "id": "d5504c92", "metadata": {}, "source": [ "I.e. the length of bitstring is set as n=5, the first integer is 5(00101), the second integer is 31(11111),\n", "then, the binary of a+b is 36(001001)" ] }, { "cell_type": "code", "execution_count": 2, "id": "19af3591", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The first integer a is: 5, the binary of a is: [True, False, True, False, False]\n", "The second integer b is: 31, the binary of b is: [True, True, True, True, True]\n", "The correct a+b is: 36, the binary of a+b is: [False, False, True, False, False, True]\n" ] } ], "source": [ "n = 5 \n", "n_qubits = 2 * (n + 1)\n", "a = 5\n", "b = 31\n", "\n", "a_bits = int_to_bits(a, n)\n", "a_bit_array = array(*a_bits) \n", "b_bits = int_to_bits(b, n)\n", "b_bit_array = array(*b_bits) \n", "a_plus_b = int_to_bits(a + b, n + 1)\n", "\n", "print(\"The first integer a is:\", str(a)+ \", the binary of a is:\", a_bits)\n", "print(\"The second integer b is:\", str(b)+ \", the binary of b is:\", b_bits)\n", "print(\"The correct a+b is:\", str(a + b)+ \", the binary of a+b is:\", a_plus_b)\n" ] }, { "cell_type": "markdown", "id": "7a7de966", "metadata": {}, "source": [ "Then, we convert the bool strings of a and b and apply the ripple carry adder " ] }, { "cell_type": "code", "execution_count": 3, "id": "81751a3a", "metadata": {}, "outputs": [], "source": [ "@guppy\n", "def main() -> None:\n", " \"\"\"Main function.\"\"\"\n", " a_reg = qarray(n)\n", " b_reg = qarray(n)\n", " carry_out = qubit()\n", " apply_bitstring(a_reg, a_bit_array)\n", " apply_bitstring(b_reg, b_bit_array)\n", " \n", " adder_ripple_cuccaro_carry_out(a_reg, b_reg, carry_out)\n", " discard_array(a_reg)\n", "\n", " output(\"b_reg\", collect_measurements(measure_array(b_reg)))\n", " output(\"carry_out\", measure(carry_out).read())\n", "\n" ] }, { "cell_type": "markdown", "id": "8f1ff96a", "metadata": {}, "source": [ "To see if the generated the string is correct, we append the b_reg and the second qubit of anci_reg" ] }, { "cell_type": "code", "execution_count": 4, "id": "efe05178", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The the a+b entry from the quantum circuit is: [False, False, True, False, False, True], if this is equal to the classical results, True\n" ] } ], "source": [ "HUGR = main.compile()\n", "runner = build(HUGR)\n", "\n", "run_shots = 1\n", "shots = QsysResult(\n", " runner.run_shots(\n", " simulator=Quest(),\n", " n_qubits=n_qubits,\n", " n_shots=run_shots,\n", " )\n", ")\n", "b_reg = dict(shots.register_counts()[\"b_reg\"])\n", "carry_out = dict(shots.register_counts()[\"carry_out\"])\n", "output_string = list(b_reg.keys())[0] + list(carry_out.keys())[0]\n", "output_string_bool = [bool(int(bit)) for bit in output_string]\n", "\n", "print(\"The the a+b entry from the quantum circuit is:\", str(output_string_bool) + \",\", \"if this is equal to the classical results,\", output_string_bool ==a_plus_b)" ] }, { "cell_type": "markdown", "id": "2ae2099b", "metadata": {}, "source": [ "The subtraction is similar, but with using two complements representation for instance" ] }, { "cell_type": "code", "execution_count": 5, "id": "2e7cec92", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The correct a-b is: 26, the binary of a-b is: [False, True, False, True, True]\n" ] } ], "source": [ "b_minus_a = b - a\n", "b_minus_a_bits = int_to_bits(b_minus_a % 2**n, n)\n", "print(\"The correct a-b is:\", str(b_minus_a) + \", the binary of a-b is:\", b_minus_a_bits)" ] }, { "cell_type": "markdown", "id": "1e5adda7", "metadata": {}, "source": [ "Thus, we can implement the subtractor_ripple_cuccaro guppy function" ] }, { "cell_type": "code", "execution_count": 6, "id": "83fc8809", "metadata": {}, "outputs": [], "source": [ "@guppy\n", "def main() -> None:\n", " \"\"\"Apply main.\"\"\"\n", " a_reg = qarray(n)\n", " b_reg = qarray(n)\n", " carry_out = qubit()\n", " apply_bitstring(a_reg, a_bit_array)\n", " apply_bitstring(b_reg, b_bit_array)\n", " subtractor_ripple_cuccaro_carry_out(a_reg, b_reg, carry_out)\n", " discard_array(a_reg)\n", " output(\"b_reg\", collect_measurements(measure_array(b_reg)))\n", " output(\"carry_out\", measure(carry_out).read())\n", "\n" ] }, { "cell_type": "markdown", "id": "007031a9", "metadata": {}, "source": [ "The b_reg stores the minus results, and the second qubit of anci_reg includes the sign" ] }, { "cell_type": "code", "execution_count": 7, "id": "9abee637", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The the b-a entry from the quantum circuit is: [False, True, False, True, True], if this is equal to the classical results, True\n", "The sign qubit is: 0, 0 means positive and neutral, 1 means negative.\n" ] } ], "source": [ "HUGR = main.compile()\n", "runner = build(HUGR)\n", "\n", "run_shots = 1\n", "shots = QsysResult(\n", " runner.run_shots(\n", " simulator=Quest(),\n", " n_qubits=n_qubits,\n", " n_shots=run_shots,\n", " )\n", ")\n", "b_reg = dict(shots.register_counts()[\"b_reg\"])\n", "carry_out = dict(shots.register_counts()[\"carry_out\"])\n", "b_reg_bool = [bool(int(bit)) for bit in list(b_reg.keys())[0]]\n", "carry_out_bool = int(list(carry_out.keys())[0])\n", "\n", "print(\"The the b-a entry from the quantum circuit is:\", str(b_reg_bool) + \",\", \"if this is equal to the classical results,\", b_reg_bool == b_minus_a_bits)\n", "print(\"The sign qubit is:\", str(carry_out_bool) + \",\", \"0 means positive and neutral, 1 means negative.\")" ] } ], "metadata": { "kernelspec": { "display_name": ".venv (3.13.12)", "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.13.12" } }, "nbformat": 4, "nbformat_minor": 5 }