diff --git a/algorithms/algebraic/discrete_log/discrete_log.ipynb b/algorithms/algebraic/discrete_log/discrete_log.ipynb
index 025dced4..e8a87b94 100644
--- a/algorithms/algebraic/discrete_log/discrete_log.ipynb
+++ b/algorithms/algebraic/discrete_log/discrete_log.ipynb
@@ -15,19 +15,19 @@
"source": [
"The Discrete Logarithm Problem [[1](#DiscreteLog)] was shown by Shor [[2](#Shor)] to be solved in a polynomial time using quantum computers, while the fastest classical algorithms take a superpolynomial time. The problem is at least as hard as the factoring problem. In fact, the hardness of the problem is the basis for the Diffie-Hellman [[3](#DiffieHellman)] protocol for key exchange. \n",
"\n",
- "### Problem formulation\n",
+ "## Formulating the Problem\n",
"\n",
"* **Input:** A cyclic group $G = \\langle g \\rangle$ with $g$ as a generator, and an element $x\\in G$.\n",
"\n",
"* **Promise:** There is a number $s$ such that $g^s = x$.\n",
"\n",
- "* **Output:** $s$, the discrete logarithm: $s = \\log_gx$\n",
+ "* **Output:** $s$, the discrete logarithm: $s = \\log_gx$.\n",
"\n",
"*** \n",
"\n",
- "In Shor's implementation the order of $g$ is assumed to be known beforehand (for example using the order finding algorithm). We will also assume it in the demonstration. \n",
+ "In Shor's implementation, the order of $g$ is assumed to be known beforehand (for example, using the order finding algorithm). We also assume it in the demonstration. \n",
"\n",
- "The Discrete Log problem is a specific example for the Abelian Hidden Subgroup Problem [[4](#HSP)], for the case of an additive group, with the function:\n",
+ "The Discrete Log problem is a specific example of the Abelian Hidden Subgroup Problem [[4](#HSP)] for the case of an additive group, with this function:\n",
"$$\n",
"f: \\mathbb{Z}_N \\times \\mathbb{Z}_N \\rightarrow G\n",
"$$\n",
@@ -41,7 +41,7 @@
"id": "8ab4be3d-dbd8-41d4-be9d-d025deebf713",
"metadata": {},
"source": [
- "## How to build the Algorithm with Classiq"
+ "## Building the Algorithm with Classiq"
]
},
{
@@ -49,21 +49,21 @@
"id": "b14cfda4-29fa-45e5-a59c-f4c798f09172",
"metadata": {},
"source": [
- "The heart of the algorithm's logic is the implementation of the function:\n",
+ "The heart of the algorithm's logic is the implementation of the function\n",
"$$\n",
- "|x_1\\rangle|x_2\\rangle|1\\rangle \\rightarrow |x_1\\rangle|x_2\\rangle|x^{x_1} g^{x_2}\\rangle \n",
+ "|x_1\\rangle|x_2\\rangle|1\\rangle \\rightarrow |x_1\\rangle|x_2\\rangle|x^{x_1} g^{x_2}\\rangle. \n",
"$$\n",
"\n",
- "This is done using 2 applications of the modular exponentiation function, which was described in detail in the [Shor's Factoring Algorithm](https://github.com/Classiq/classiq-library/blob/main/algorithms/algebraic/shor/shor_modular_exponentiation.ipynb) notebook. So here we will just import it from the classiq's library.\n",
+ "This is done using two applications of the modular exponentiation function, described in detail in the [Shor's Factoring Algorithm](https://github.com/Classiq/classiq-library/blob/main/algorithms/algebraic/shor/shor_modular_exponentiation.ipynb) notebook. So here we import it from the Classiq library.\n",
"\n",
- "The function `modular_exp` accepts the following arguments:\n",
+ "The `modular_exp` function accepts these arguments:\n",
"- `n: CInt` - modulo number\n",
"- `a: CInt` - base of the exponentiation\n",
- "- `x: QArray[QBit]` - unsigned integer to multiply be the exponentiation\n",
+ "- `x: QArray[QBit]` - unsigned integer to multiply by the exponentiation\n",
"- `power: QArray[QBit]`- power of the exponentiation\n",
"\n",
- "So that the function implements:\n",
- "$|power\\rangle|x\\rangle \\rightarrow |power\\rangle|x \\cdot a ^ {power}\\mod n\\rangle$"
+ "So the function implements \n",
+ "$|power\\rangle|x\\rangle \\rightarrow |power\\rangle|x \\cdot a ^ {power}\\mod n\\rangle$."
]
},
{
@@ -97,10 +97,10 @@
"id": "23cf730e-17d2-4a76-b4d6-d39d4c9b865a",
"metadata": {},
"source": [
- "### The full algorithm:\n",
- "1. Prepare uniform superposition over the first 2 quantum variables `x1`, `x2`. Each variable should be with size $\\lceil \\log r\\rceil + \\log({1/{\\epsilon}})$. In the special case where $r$ is a power of 2, $\\log r$ is enough.\n",
- "3. Compute `discrete_log_oracle` on the `func_res` variable. `func_res` should be of size $\\lceil \\log N\\rceil$.\n",
- "4. Apply inverse Fourier transform `x1`, `x2`.\n",
+ "### Full Algorithm\n",
+ "1. Prepare uniform superposition over the first two quantum variables `x1`, `x2`. Each variable has size $\\lceil \\log r\\rceil + \\log({1/{\\epsilon}})$. In the special case where $r$ is a power of 2, $\\log r$ is enough.\n",
+ "3. Compute `discrete_log_oracle` on the `func_res` variable. `func_res` is of size $\\lceil \\log N\\rceil$.\n",
+ "4. Apply the inverse Fourier transform `x1`, `x2`.\n",
"5. Measure."
]
},
@@ -142,14 +142,14 @@
"id": "56b2c254-8894-4b05-9cf1-deded6ab15cc",
"metadata": {},
"source": [
- "After the inverse QFTs, we get in the variables (under the assumption of $r=2^m$ for some $m$):\n",
- "$$|\\psi\\rangle = \\sum_{\\nu\\in\\mathbb{Z}_r, \\delta\\in G}\\omega^{\\nu\\delta}|\\nu\\cdot log_gx\\rangle_{x_1}|\\nu\\rangle_{x_2}|\\delta>_{func\\_res}$$\n",
+ "After the inverse QFTs (under the assumption of $r=2^m$ for some $m$), the variables become\n",
+ "$$|\\psi\\rangle = \\sum_{\\nu\\in\\mathbb{Z}_r, \\delta\\in G}\\omega^{\\nu\\delta}|\\nu\\cdot log_gx\\rangle_{x_1}|\\nu\\rangle_{x_2}|\\delta>_{func\\_res}$$.\n",
"\n",
- "For every $\\nu$ that has a mutplicative inverse in $\\mathbb{Z}_r$, we can extract $s=\\log_xg$ by multiplying the first variable result by its inverse.\n",
+ "For every $\\nu$ that has a multiplicative inverse in $\\mathbb{Z}_r$, we can extract $s=\\log_xg$ by multiplying the first variable result by its inverse.\n",
"\n",
- "In the case where $r$ is not a power of 2, we get in the variables and approximation of: |$\\log_g(x)\\cdot \\nu/ r\\rangle_{x_1} |\\nu / r\\rangle_{x_2}$. So we can use the continued fractions algorithm [[5](#ContinuedFraction)] to compute $\\nu/r$, then using the same technique to calculate $\\log_gx$.\n",
+ "If $r$ is not a power of 2, the variables get an approximation of |$\\log_g(x)\\cdot \\nu/ r\\rangle_{x_1} |\\nu / r\\rangle_{x_2}$. So we can use the continued fractions algorithm [[5](#ContinuedFraction)] to compute $\\nu/r$, then use the same technique to calculate $\\log_gx$.\n",
"\n",
- "*Note: Alternatively, one might implement the $QFT_{\\mathbb{Z}_r}$ over general $r$, and instead of the uniform superposition prepare the states: $\\frac{1}{\\sqrt{r}}\\sum_{x\\in\\mathbb{r}}|x\\rangle$ in `x1`, `x2`. Then again no continued fractions post-process is required.*"
+ "*Note: Alternatively, you could implement the $QFT_{\\mathbb{Z}_r}$ over general $r$, and instead of the uniform superposition, prepare the states: $\\frac{1}{\\sqrt{r}}\\sum_{x\\in\\mathbb{r}}|x\\rangle$ in `x1`, `x2`. Then, again, no continued fractions postprocessing is required.*"
]
},
{
@@ -178,9 +178,9 @@
"id": "c8c1edc5-0271-48c6-ac7d-7bdc17598568",
"metadata": {},
"source": [
- "For this specific demonstration, we choose $G = \\mathbb{Z}_5^\\times$, with $g=3$ and $x=2$. Under this setting, $log_gx=3$.\n",
+ "For this specific demonstration, we choose $G = \\mathbb{Z}_5^\\times$, with $g=3$ and $x=2$. With this setting, $log_gx=3$.\n",
"\n",
- "We choose this specific example as the order of of the group $r=4$ is a power of $2$, and so we can get exactly the discrete logarithm, without continued-fractions post processing. In other cases, one has to use larger quantum variable for the exponents so the continued fractions post-processing will converge."
+ "We choose this specific example because the order of the group $r=4$ is a power of $2$, so we can get the exact discrete logarithm without continued-fractions postprocessing. In other cases, we use a larger quantum variable for the exponents so the continued fractions postprocessing converges."
]
},
{
@@ -248,10 +248,10 @@
"id": "c405feed-408f-4d91-a22c-0b445b2ff6c2",
"metadata": {},
"source": [
- "Notice that `func_res` is uncorrelated to the other variables, and we get uniform distribution, as expected. \n",
+ "Note that `func_res` is uncorrelated to the other variables, and we get uniform distribution, as expected. \n",
"\n",
"We take only the `x2` that are co-prime to $r=4$, so they have a multiplicative-inverse. Hence `x2=1,3` are the relevant results.\n",
- "So we get 2 relevant results (for all different $\\delta$s): $|1\\rangle|3\\rangle$, $|3\\rangle|1\\rangle$. All left to do to get the logarithm is to multiply `x1` by the inverse of `x2`:"
+ "So we get two relevant results (for all different $\\delta$s): $|1\\rangle|3\\rangle$, $|3\\rangle|1\\rangle$. All that remains to get the logarithm is to multiply `x1` by the inverse of `x2`:"
]
},
{
@@ -295,7 +295,7 @@
"id": "a83324a1-202e-4589-b663-e4b0e631e680",
"metadata": {},
"source": [
- "Verify we got the correct discrete logarithm:"
+ "Verify we received the correct discrete logarithm:"
]
},
{
@@ -321,7 +321,7 @@
"id": "3fd236be-032d-4513-806c-086a8623a40d",
"metadata": {},
"source": [
- "And indeed in both cases the same result, which is exactly the discrete logarithm: $\\log_32 \\mod 5 = 3$"
+ "And, indeed, both cases give the same result, which is exactly the discrete logarithm: $\\log_32 \\mod 5 = 3$."
]
},
{
@@ -337,9 +337,9 @@
"id": "1702d0f8-bca1-4e00-bffd-4b8c0ec4ddcb",
"metadata": {},
"source": [
- "Here we take the case were the order is not a power of 2. In the circuit creation, we will need to change the state preparation. Instead of creating the entire uniform distribution on the `x1`, `x2` variables, we will load them with the uniform superposition of only the first `#ORDER` states.\n",
+ "In this case the order is not a power of 2. During circuit creation, we change the state preparation: instead of creating the entire uniform distribution on the `x1`, `x2` variables, we load them with the uniform superposition of only the first `#ORDER` states.\n",
"\n",
- "In order to do that we can use the library function `prepare_uniform_trimmed_state` which prepare such a state efficiently."
+ "We do that using the `prepare_uniform_trimmed_state` library function, which efficiently prepares such a state."
]
},
{
@@ -367,7 +367,7 @@
") -> None:\n",
" reg_len = ceiling(log(order, 2)) + 1\n",
"\n",
- " # we define the variables with fraction places in order to ease the post-processing\n",
+ " # we define the variables with fraction places to ease the postprocessing\n",
" allocate_num(reg_len, False, reg_len, x1)\n",
" allocate_num(reg_len, False, reg_len, x2)\n",
"\n",
@@ -453,7 +453,7 @@
"id": "89ea05c0-7939-42a3-8cdf-4e46989ce401",
"metadata": {},
"source": [
- "#### Post process"
+ "#### Postprocessing"
]
},
{
@@ -461,7 +461,7 @@
"id": "74e6acb6-43c0-41ad-a0dc-eac9c9f5f5cc",
"metadata": {},
"source": [
- "We now have additional step in post-process. We translate each result to the closest fraction with denominator which is the order:"
+ "We now have an additional step in postprocessing. We translate each result to the closest fraction with a denominator, which is the order:"
]
},
{
@@ -526,7 +526,7 @@
"id": "e2e15760-1bbb-4d79-8499-d111a2009135",
"metadata": {},
"source": [
- "Now take a sample where `x2` is co-prime to the order, such that we can get the logarithm by multiplying `x1` by the modular inverse. If the the `x1`, `x2` registers are large enough, we are guaranteed to sample it with a good probability:"
+ "Now, we take a sample where `x2` is co-prime to the order, such that we can get the logarithm by multiplying `x1` by the modular inverse. If the `x1`, `x2` registers are large enough, we are guaranteed to sample it with a good probability:"
]
},
{
@@ -578,7 +578,7 @@
"\n",
"[1]: [Discrete Logarithm (Wikipedia)](https://en.wikipedia.org/wiki/Discrete_logarithm)\n",
"\n",
- "[2]: [Shor, Peter W. \"Algorithms for quantum computation: discrete logarithms and factoring.\" Proceedings 35th annual symposium on foundations of computer science. Ieee, 1994.](https://ieeexplore.ieee.org/abstract/document/365700)\n",
+ "[2]: [Shor, Peter W. \"Algorithms for quantum computation: discrete logarithms and factoring.\" Proceedings 35th annual symposium on foundations of computer science. IEEE, 1994.](https://ieeexplore.ieee.org/abstract/document/365700)\n",
"\n",
"[3]: [Diffie-Hellman Key Exchange (Wikipedia)](https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange)\n",
"\n",