diff --git a/notebooks/textbook/Shors_Algorithm.ipynb b/notebooks/textbook/Shors_Algorithm.ipynb index f59535d4..462e5970 100644 --- a/notebooks/textbook/Shors_Algorithm.ipynb +++ b/notebooks/textbook/Shors_Algorithm.ipynb @@ -48,7 +48,7 @@ "metadata": {}, "outputs": [], "source": [ - "N = 15 # Integer to factor (currently 15, 21, 35 work)\n", + "N = 15 # Integer to factor (currently 15, 21, 33, 35 work)\n", "a = 7 # Any integer that satisfies 1 < a < N and gcd(a, N) = 1.\n", "\n", "\n", diff --git a/src/braket/experimental/algorithms/shors/shors.py b/src/braket/experimental/algorithms/shors/shors.py index 4a0ced2e..0c9027cf 100644 --- a/src/braket/experimental/algorithms/shors/shors.py +++ b/src/braket/experimental/algorithms/shors/shors.py @@ -60,7 +60,10 @@ def shors_algorithm(integer_N: int, integer_a: int) -> Circuit: shors_circuit.x(aux_qubits[0]) # Apply modular exponentiation - shors_circuit.modular_exponentiation_amod15(counting_qubits, aux_qubits, integer_a) + if integer_N == 33: + shors_circuit.modular_exponentiation_amod33(counting_qubits, aux_qubits, integer_a) + else: + shors_circuit.modular_exponentiation_amod15(counting_qubits, aux_qubits, integer_a) # Apply inverse QFT shors_circuit.inverse_qft_noswaps(counting_qubits) @@ -179,6 +182,41 @@ def modular_exponentiation_amod15( return mod_exp_amod15 +@circuit.subroutine(register=True) +def modular_exponentiation_amod33( + counting_qubits: QubitSetInput, aux_qubits: QubitSetInput, integer_a: int +) -> Circuit: + """ + Construct a circuit object corresponding the modular exponentiation of a^x Mod 33 + + Args: + counting_qubits (QubitSetInput): Qubits defining the counting register + aux_qubits (QubitSetInput) : Qubits defining the auxilary register + integer_a (int) : Any integer that satisfies 1 < a < N and gcd(a, N) = 1. + Returns: + Circuit: Circuit object that implements the modular exponentiation of a^x Mod 33 + """ + + # Instantiate circuit object + mod_exp_amod33 = Circuit() + + for x in counting_qubits: + r = 2**x + if integer_a not in [10, 23]: + raise ValueError("integer 'a' must be 10 or 23 for N = 33") + for iteration in range(r): + if integer_a == 10: + mod_exp_amod33.cnot(x, aux_qubits[0]) + mod_exp_amod33.cnot(x, aux_qubits[1]) + mod_exp_amod33.cnot(x, aux_qubits[3]) + if integer_a == 23: + mod_exp_amod33.cnot(x, aux_qubits[1]) + mod_exp_amod33.cnot(x, aux_qubits[2]) + mod_exp_amod33.cnot(x, aux_qubits[4]) + + return mod_exp_amod33 + + def get_factors_from_results( results: Dict[str, Any], integer_N: int, diff --git a/test/unit_tests/braket/experimental/algorithms/shors/test_shors.py b/test/unit_tests/braket/experimental/algorithms/shors/test_shors.py index 43bf5dc9..6bce040c 100644 --- a/test/unit_tests/braket/experimental/algorithms/shors/test_shors.py +++ b/test/unit_tests/braket/experimental/algorithms/shors/test_shors.py @@ -50,6 +50,16 @@ def test_shors_algorithm(): assert aggregate_results["guessed_factors"] == {3, 5} +def test_shors_algorithm_for_33(): + integer_N = 33 + integer_a = 10 + shor = shors_algorithm(integer_N, integer_a) + local_simulator = LocalSimulator() + output = run_shors_algorithm(shor, local_simulator) + aggregate_results = get_factors_from_results(output, integer_N, integer_a, False) + assert aggregate_results["guessed_factors"] == {3, 11} + + def test_all_valid_a(): local_simulator = LocalSimulator() integer_N = 15 @@ -60,6 +70,16 @@ def test_all_valid_a(): assert aggregate_results["guessed_factors"] == {3, 5} +def test_all_valid_a_for_33(): + local_simulator = LocalSimulator() + integer_N = 33 + for integer_a in [10, 23]: + shor = shors_algorithm(integer_N, integer_a) + output = run_shors_algorithm(shor, local_simulator) + aggregate_results = get_factors_from_results(output, integer_N, integer_a, True) + assert aggregate_results["guessed_factors"] == {3, 11} + + def test_no_counts(): with pytest.raises(TypeError): output = {"measurement_counts": False}