Repository: Qiskit/qiskit
Pull request #14161: Porting `synth_qft_line` to Rust
Author: login: Barath-T
Labels: name: Changelog: None
description: Do not include in the GitHub Release changelog.
name: synthesis
name: Rust
description: This PR or issue is related to Rust code in the repository
name: Community PR
description: PRs from contributors that are not 'members' of the Qiskit repo
Created: 2025-04-02T17:53:39Z | Merged: 2025-04-29T07:56:24Z

<!--
⚠️ If you do not respect this template, your pull request will be closed.
⚠️ Your pull request title should be short detailed and understandable for all.
⚠️ Also, please add a release note file using reno if the change needs to be
  documented in the release notes.
⚠️ If your pull request fixes an open issue, please link to the issue.

- [x] I have added the tests to cover my changes.
- [x] I have updated the documentation accordingly.
- [x] I have read the CONTRIBUTING document.
-->

### Summary
This PR ports `synth_qft_line` in `qiskit/synthesis/qft/qft_decompose_lnn.py` to Rust (Closes #12245).


### Details and comments
The functionality remains the same and no new optimisations or logic is introduced.

Comment needed: PR #13929 introduces `SynthesisData`, which would allow for a cleaner refactoring.



Linked issue #12245: Port `synth_qft_line` to Rust
Port `synth_qft_line` in `qiskit/synthesis/qft/qft_decompose_lnn.py` to Rust.
Linked issue comments: user: login: Barath-T
created_at: 2025-04-02T06:00:41Z
body: @Cryoris I’ve checked it out. I’ll start working on it. Could you please assign me to it?
author_association: CONTRIBUTOR

Diff:
diff --git a/crates/accelerate/src/synthesis/mod.rs b/crates/accelerate/src/synthesis/mod.rs
index b3647222f8d9..c809153c1a7b 100644
--- a/crates/accelerate/src/synthesis/mod.rs
+++ b/crates/accelerate/src/synthesis/mod.rs
@@ -16,6 +16,7 @@ pub mod linear;
 pub mod linear_phase;
 mod multi_controlled;
 mod permutation;
+mod qft;
 
 use pyo3::prelude::*;
 
@@ -44,5 +45,9 @@ pub fn synthesis(m: &Bound<PyModule>) -> PyResult<()> {
     evolution::evolution(&evolution_mod)?;
     m.add_submodule(&evolution_mod)?;
 
+    let qft_mod = PyModule::new(m.py(), "qft")?;
+    qft::qft(&qft_mod)?;
+    m.add_submodule(&qft_mod)?;
+
     Ok(())
 }
diff --git a/crates/accelerate/src/synthesis/permutation/mod.rs b/crates/accelerate/src/synthesis/permutation/mod.rs
index 9220b6113cd9..bbdf0f1ddcd0 100644
--- a/crates/accelerate/src/synthesis/permutation/mod.rs
+++ b/crates/accelerate/src/synthesis/permutation/mod.rs
@@ -156,7 +156,7 @@ pub(crate) fn _append_cx_stage2(gates: &mut LnnGatesVec, n: usize) {
 
 /// Append reverse permutation to a QuantumCircuit for linear nearest-neighbor architectures
 /// using Kutin, Moulton, Smithline method.
-fn _append_reverse_permutation_lnn_kms(gates: &mut LnnGatesVec, num_qubits: usize) {
+pub(crate) fn _append_reverse_permutation_lnn_kms(gates: &mut LnnGatesVec, num_qubits: usize) {
     (0..num_qubits.div_ceil(2)).for_each(|_| {
         _append_cx_stage1(gates, num_qubits);
         _append_cx_stage2(gates, num_qubits);
diff --git a/crates/accelerate/src/synthesis/qft/mod.rs b/crates/accelerate/src/synthesis/qft/mod.rs
new file mode 100644
index 000000000000..700f91439b81
--- /dev/null
+++ b/crates/accelerate/src/synthesis/qft/mod.rs
@@ -0,0 +1,21 @@
+// This code is part of Qiskit.
+//
+// (C) Copyright IBM 2025
+//
+// This code is licensed under the Apache License, Version 2.0. You may
+// obtain a copy of this license in the LICENSE.txt file in the root directory
+// of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
+//
+// Any modifications or derivative works of this code must retain this
+// copyright notice, and modified files need to carry a notice indicating
+// that they have been altered from the originals.
+
+mod qft_decompose_lnn;
+
+use pyo3::prelude::*;
+use qft_decompose_lnn::synth_qft_line;
+
+pub fn qft(m: &Bound<PyModule>) -> PyResult<()> {
+    m.add_function(wrap_pyfunction!(synth_qft_line, m)?)?;
+    Ok(())
+}
diff --git a/crates/accelerate/src/synthesis/qft/qft_decompose_lnn.rs b/crates/accelerate/src/synthesis/qft/qft_decompose_lnn.rs
new file mode 100644
index 000000000000..7c29b0ab8b87
--- /dev/null
+++ b/crates/accelerate/src/synthesis/qft/qft_decompose_lnn.rs
@@ -0,0 +1,125 @@
+// This code is part of Qiskit.
+//
+// (C) Copyright IBM 2025.
+//
+// This code is licensed under the Apache License, Version 2.0. You may
+// obtain a copy of this license in the LICENSE.txt file in the root directory
+// of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
+//
+// Any modifications or derivative works of this code must retain this
+// copyright notice, and modified files need to carry a notice indicating
+// that they have been altered from the originals.
+
+use crate::synthesis::linear_phase::cz_depth_lnn::LnnGatesVec;
+use crate::synthesis::permutation::_append_reverse_permutation_lnn_kms;
+use pyo3::prelude::*;
+use qiskit_circuit::circuit_data::CircuitData;
+use qiskit_circuit::operations::{Param, StandardGate};
+use qiskit_circuit::Qubit;
+use smallvec::smallvec;
+use std::f64::consts::PI;
+
+/// Construct a circuit for the Quantum Fourier Transform using linear
+/// neighbor connectivity.
+///
+/// The construction is based on Fig 2.b in Fowler et al. [1].
+///
+/// .. note::
+///
+///     With the default value of ``do_swaps = True``, this synthesis algorithm creates a
+///     circuit that faithfully implements the QFT operation. When ``do_swaps = False``,
+///     this synthesis algorithm creates a circuit that corresponds to "QFT-with-reversal":
+///     applying the QFT and reversing the order of its output qubits.
+///
+/// Args:
+///     num_qubits: The number of qubits on which the Quantum Fourier Transform acts.
+///     approximation_degree: The degree of approximation (0 for no approximation).
+///         It is possible to implement the QFT approximately by ignoring
+///         controlled-phase rotations with the angle beneath a threshold. This is discussed
+///         in more detail in https://arxiv.org/abs/quant-ph/9601018 or
+///         https://arxiv.org/abs/quant-ph/0403071.
+///     do_swaps: Whether to synthesize the "QFT" or the "QFT-with-reversal" operation.
+///
+/// Returns:
+///     A circuit implementing the QFT operation.
+///
+/// References:
+///     1. A. G. Fowler, S. J. Devitt, and L. C. L. Hollenberg,
+///        *Implementation of Shor's algorithm on a linear nearest neighbour qubit array*,
+///        Quantum Info. Comput. 4, 4 (July 2004), 237–251.
+///        `arXiv:quant-ph/0402196 [quant-ph] <https://arxiv.org/abs/quant-ph/0402196>`_
+#[pyfunction]
+#[pyo3(signature=(num_qubits, do_swaps=true, approximation_degree=0))]
+pub fn synth_qft_line(
+    py: Python,
+    num_qubits: usize,
+    do_swaps: bool,
+    approximation_degree: usize,
+) -> PyResult<CircuitData> {
+    // Total number of compound gates required = L(L-1)/2
+    // Compound gate: H + 3CX + 3P or 3CX + 3P
+    // For approximation degree D, D(D+1)/2 * 3 gates will be reduced
+    let mut no_of_gates = num_qubits + (num_qubits * (num_qubits - 1) / 2) * 6
+        - (approximation_degree * (approximation_degree + 1) / 2) * 3;
+
+    if !do_swaps {
+        // `_append_reverse_permutation_lnn_kms` would add
+        no_of_gates += num_qubits * num_qubits - 1;
+    }
+
+    let mut instructions: LnnGatesVec = Vec::with_capacity(no_of_gates);
+
+    for i in 0..num_qubits {
+        append_h(&mut instructions, num_qubits - 1);
+
+        for j in i..num_qubits - 1 {
+            let q0 = num_qubits - j + i - 1;
+            let q1 = num_qubits - j + i - 2;
+            let phase = PI / (2_u32.pow((j - i + 2) as u32) as f64);
+
+            if j - i + 2 < num_qubits - approximation_degree + 1 {
+                append_phase(&mut instructions, q0, phase);
+                append_cx(&mut instructions, q0, q1);
+                append_phase(&mut instructions, q1, -phase);
+                append_cx(&mut instructions, q1, q0);
+                append_cx(&mut instructions, q0, q1);
+                append_phase(&mut instructions, q0, phase);
+            } else {
+                // Swap
+                append_cx(&mut instructions, q0, q1);
+                append_cx(&mut instructions, q1, q0);
+                append_cx(&mut instructions, q0, q1);
+            }
+        }
+    }
+    if !do_swaps {
+        // Add a reversal network for LNN connectivity in depth 2*n+2,
+        // based on Kutin at al., https://arxiv.org/abs/quant-ph/0701194, Section 5.
+        _append_reverse_permutation_lnn_kms(&mut instructions, num_qubits);
+    }
+
+    CircuitData::from_standard_gates(py, num_qubits as u32, instructions, Param::Float(0.0))
+}
+
+#[inline]
+fn append_h(instructions: &mut LnnGatesVec, q0: usize) {
+    instructions.push((StandardGate::H, smallvec![], smallvec![Qubit::new(q0)]));
+}
+
+#[inline]
+fn append_cx(instructions: &mut LnnGatesVec, q0: usize, q1: usize) {
+    instructions.push((
+        StandardGate::CX,
+        smallvec![],
+        smallvec![Qubit::new(q0), Qubit::new(q1)],
+    ));
+}
+
+#[inline]
+fn append_phase(instructions: &mut LnnGatesVec, q0: usize, phase: f64) {
+    instructions.push((
+        StandardGate::Phase,
+        smallvec![Param::Float(phase)],
+        smallvec![Qubit::new(q0)],
+    ));
+}
diff --git a/qiskit/__init__.py b/qiskit/__init__.py
index 13a8d6f1b4c0..87d6043ee322 100644
--- a/qiskit/__init__.py
+++ b/qiskit/__init__.py
@@ -101,6 +101,7 @@
 sys.modules["qiskit._accelerate.synthesis.multi_controlled"] = (
     _accelerate.synthesis.multi_controlled
 )
+sys.modules["qiskit._accelerate.synthesis.qft"] = _accelerate.synthesis.qft
 sys.modules["qiskit._accelerate.split_2q_unitaries"] = _accelerate.split_2q_unitaries
 sys.modules["qiskit._accelerate.gate_direction"] = _accelerate.gate_direction
 sys.modules["qiskit._accelerate.inverse_cancellation"] = _accelerate.inverse_cancellation
diff --git a/qiskit/synthesis/qft/qft_decompose_lnn.py b/qiskit/synthesis/qft/qft_decompose_lnn.py
index 3b1ed1f6ddf6..c536d8ef0ee1 100644
--- a/qiskit/synthesis/qft/qft_decompose_lnn.py
+++ b/qiskit/synthesis/qft/qft_decompose_lnn.py
@@ -13,9 +13,9 @@
 Circuit synthesis for a QFT circuit.
 """
 
-import numpy as np
 from qiskit.circuit import QuantumCircuit
-from qiskit.synthesis.permutation.permutation_reverse_lnn import _append_reverse_permutation_lnn_kms
+from qiskit._accelerate.synthesis.qft import synth_qft_line as _synth_qft_line
+
 from .qft_decompose_full import _warn_if_precision_loss
 
 
@@ -53,27 +53,9 @@ def synth_qft_line(
            `arXiv:quant-ph/0402196 [quant-ph] <https://arxiv.org/abs/quant-ph/0402196>`_
     """
     _warn_if_precision_loss(num_qubits - approximation_degree - 1)
-    qc = QuantumCircuit(num_qubits)
-
-    for i in range(num_qubits):
-        qc.h(num_qubits - 1)
-
-        for j in range(i, num_qubits - 1):
-            if j - i + 2 < num_qubits - approximation_degree + 1:
-                qc.p(np.pi / 2 ** (j - i + 2), num_qubits - j + i - 1)
-                qc.cx(num_qubits - j + i - 1, num_qubits - j + i - 2)
-                qc.p(-np.pi / 2 ** (j - i + 2), num_qubits - j + i - 2)
-                qc.cx(num_qubits - j + i - 2, num_qubits - j + i - 1)
-                qc.cx(num_qubits - j + i - 1, num_qubits - j + i - 2)
-                qc.p(np.pi / 2 ** (j - i + 2), num_qubits - j + i - 1)
-            else:
-                qc.cx(num_qubits - j + i - 1, num_qubits - j + i - 2)
-                qc.cx(num_qubits - j + i - 2, num_qubits - j + i - 1)
-                qc.cx(num_qubits - j + i - 1, num_qubits - j + i - 2)
-
-    if not do_swaps:
-        # Add a reversal network for LNN connectivity in depth 2*n+2,
-        # based on Kutin at al., https://arxiv.org/abs/quant-ph/0701194, Section 5.
-        _append_reverse_permutation_lnn_kms(qc, num_qubits)
 
-    return qc
+    return QuantumCircuit._from_circuit_data(
+        # From rust
+        _synth_qft_line(num_qubits, do_swaps, approximation_degree),
+        add_regs=True,
+    )


Reviews:
user: login: Cryoris
body: This looks very good! I only have two small comments below 🙂 
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-03T14:11:48Z
user: login: Cryoris
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-04T13:46:39Z
user: login: Barath-T
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-04T13:51:59Z
user: login: alexanderivrii
body: Thanks for the contribution @Barath-T! I think this is in a good shape, modulo needing to adjust the Rust-level docstrings a bit.

Fyi, I have reworked #13929 to work with `CircuitData` directly (and in particular added convenience functions to append `h`, `cp`, `cx` gates), but for your PR keeping it in terms of `LnnGatesVec` is definitely better. 
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-08T08:16:59Z
user: login: alexanderivrii
body: Thanks for the changes! This looks good on my side, @Cryoris do you have any additional comments?
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-09T07:31:53Z
user: login: ShellyGarion
body: LGTM. @Cryoris - do you have any further comments?
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-27T11:17:28Z
user: login: Cryoris
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-04-28T07:34:11Z

Review comments:
diff_hunk: @@ -0,0 +1,112 @@
+// This code is part of Qiskit.
+//
+// (C) Copyright IBM 2023.
+//
+// This code is licensed under the Apache License, Version 2.0. You may
+// obtain a copy of this license in the LICENSE.txt file in the root directory
+// of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
+//
+// Any modifications or derivative works of this code must retain this
+// copyright notice, and modified files need to carry a notice indicating
+// that they have been altered from the originals.
+
+use crate::synthesis::linear_phase::cz_depth_lnn::LnnGatesVec;
+use crate::synthesis::permutation::_append_reverse_permutation_lnn_kms;
+use pyo3::prelude::*;
+use qiskit_circuit::circuit_data::CircuitData;
+use qiskit_circuit::operations::{Param, StandardGate};
+use qiskit_circuit::Qubit;
+use smallvec::smallvec;
+use std::f64::consts::PI;
+
+/// Construct a circuit for the Quantum Fourier Transform using linear
+/// neighbor connectivity.
+///
+/// The construction is based on Fig 2.b in Fowler et al. [1].
+///
+/// .. note::
+///
+///     With the default value of ``do_swaps = True``, this synthesis algorithm creates a
+///     circuit that faithfully implements the QFT operation. When ``do_swaps = False``,
+///     this synthesis algorithm creates a circuit that corresponds to "QFT-with-reversal":
+///     applying the QFT and reversing the order of its output qubits.
+///
+/// Args:
+///     num_qubits: The number of qubits on which the Quantum Fourier Transform acts.
+///     approximation_degree: The degree of approximation (0 for no approximation).
+///         It is possible to implement the QFT approximately by ignoring
+///         controlled-phase rotations with the angle beneath a threshold. This is discussed
+///         in more detail in https://arxiv.org/abs/quant-ph/9601018 or
+///         https://arxiv.org/abs/quant-ph/0403071.
+///     do_swaps: Whether to synthesize the "QFT" or the "QFT-with-reversal" operation.
+///
+/// Returns:
+///     A circuit implementing the QFT operation.
+///
+/// References:
+///     1. A. G. Fowler, S. J. Devitt, and L. C. L. Hollenberg,
+///        *Implementation of Shor's algorithm on a linear nearest neighbour qubit array*,
+///        Quantum Info. Comput. 4, 4 (July 2004), 237–251.
+///        `arXiv:quant-ph/0402196 [quant-ph] <https://arxiv.org/abs/quant-ph/0402196>`_
+
+#[pyfunction]
+#[pyo3(signature=(num_qubits, do_swaps=true, approximation_degree=0))]
+pub(super) fn _synth_qft_line(
+    py: Python,
+    num_qubits: usize,
+    do_swaps: bool,
+    approximation_degree: usize,
+) -> PyResult<CircuitData> {
+    let mut instructions: LnnGatesVec = Vec::new();
path: crates/accelerate/src/synthesis/qft/qft_decompose_lnn.rs
user: login: Cryoris
body: Since the number of gates is deterministic it would be nice to use `Vec::with_capacity` and the number of gates here, so we can avoid resizing the vector 🙂 
created_at: 2025-04-03T14:08:04Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,112 @@
+// This code is part of Qiskit.
+//
+// (C) Copyright IBM 2023.
+//
+// This code is licensed under the Apache License, Version 2.0. You may
+// obtain a copy of this license in the LICENSE.txt file in the root directory
+// of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
+//
+// Any modifications or derivative works of this code must retain this
+// copyright notice, and modified files need to carry a notice indicating
+// that they have been altered from the originals.
+
+use crate::synthesis::linear_phase::cz_depth_lnn::LnnGatesVec;
+use crate::synthesis::permutation::_append_reverse_permutation_lnn_kms;
+use pyo3::prelude::*;
+use qiskit_circuit::circuit_data::CircuitData;
+use qiskit_circuit::operations::{Param, StandardGate};
+use qiskit_circuit::Qubit;
+use smallvec::smallvec;
+use std::f64::consts::PI;
+
+/// Construct a circuit for the Quantum Fourier Transform using linear
+/// neighbor connectivity.
+///
+/// The construction is based on Fig 2.b in Fowler et al. [1].
+///
+/// .. note::
+///
+///     With the default value of ``do_swaps = True``, this synthesis algorithm creates a
+///     circuit that faithfully implements the QFT operation. When ``do_swaps = False``,
+///     this synthesis algorithm creates a circuit that corresponds to "QFT-with-reversal":
+///     applying the QFT and reversing the order of its output qubits.
+///
+/// Args:
+///     num_qubits: The number of qubits on which the Quantum Fourier Transform acts.
+///     approximation_degree: The degree of approximation (0 for no approximation).
+///         It is possible to implement the QFT approximately by ignoring
+///         controlled-phase rotations with the angle beneath a threshold. This is discussed
+///         in more detail in https://arxiv.org/abs/quant-ph/9601018 or
+///         https://arxiv.org/abs/quant-ph/0403071.
+///     do_swaps: Whether to synthesize the "QFT" or the "QFT-with-reversal" operation.
+///
+/// Returns:
+///     A circuit implementing the QFT operation.
+///
+/// References:
+///     1. A. G. Fowler, S. J. Devitt, and L. C. L. Hollenberg,
+///        *Implementation of Shor's algorithm on a linear nearest neighbour qubit array*,
+///        Quantum Info. Comput. 4, 4 (July 2004), 237–251.
+///        `arXiv:quant-ph/0402196 [quant-ph] <https://arxiv.org/abs/quant-ph/0402196>`_
+
+#[pyfunction]
+#[pyo3(signature=(num_qubits, do_swaps=true, approximation_degree=0))]
+pub(super) fn _synth_qft_line(
path: crates/accelerate/src/synthesis/qft/qft_decompose_lnn.rs
user: login: Cryoris
body: The leading underscore seems more like a Python thing, I don't think we need this custom here and rely on the `pub` qualifier to control function privacy
```suggestion
pub(super) fn synth_qft_line(
```
created_at: 2025-04-03T14:10:38Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,123 @@
+// This code is part of Qiskit.
+//
+// (C) Copyright IBM 2023.
+//
+// This code is licensed under the Apache License, Version 2.0. You may
+// obtain a copy of this license in the LICENSE.txt file in the root directory
+// of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
+//
+// Any modifications or derivative works of this code must retain this
+// copyright notice, and modified files need to carry a notice indicating
+// that they have been altered from the originals.
+
+use crate::synthesis::linear_phase::cz_depth_lnn::LnnGatesVec;
+use crate::synthesis::permutation::_append_reverse_permutation_lnn_kms;
+use pyo3::prelude::*;
+use qiskit_circuit::circuit_data::CircuitData;
+use qiskit_circuit::operations::{Param, StandardGate};
+use qiskit_circuit::Qubit;
+use smallvec::smallvec;
+use std::f64::consts::PI;
+
+/// Construct a circuit for the Quantum Fourier Transform using linear
+/// neighbor connectivity.
+///
+/// The construction is based on Fig 2.b in Fowler et al. [1].
+///
+/// .. note::
+///
+///     With the default value of ``do_swaps = True``, this synthesis algorithm creates a
+///     circuit that faithfully implements the QFT operation. When ``do_swaps = False``,
+///     this synthesis algorithm creates a circuit that corresponds to "QFT-with-reversal":
+///     applying the QFT and reversing the order of its output qubits.
+///
+/// Args:
+///     num_qubits: The number of qubits on which the Quantum Fourier Transform acts.
+///     approximation_degree: The degree of approximation (0 for no approximation).
+///         It is possible to implement the QFT approximately by ignoring
+///         controlled-phase rotations with the angle beneath a threshold. This is discussed
+///         in more detail in https://arxiv.org/abs/quant-ph/9601018 or
+///         https://arxiv.org/abs/quant-ph/0403071.
+///     do_swaps: Whether to synthesize the "QFT" or the "QFT-with-reversal" operation.
+///
+/// Returns:
+///     A circuit implementing the QFT operation.
+///
+/// References:
+///     1. A. G. Fowler, S. J. Devitt, and L. C. L. Hollenberg,
+///        *Implementation of Shor's algorithm on a linear nearest neighbour qubit array*,
+///        Quantum Info. Comput. 4, 4 (July 2004), 237–251.
+///        `arXiv:quant-ph/0402196 [quant-ph] <https://arxiv.org/abs/quant-ph/0402196>`_
+
+#[pyfunction]
+#[pyo3(signature=(num_qubits, do_swaps=true, approximation_degree=0))]
+pub fn synth_qft_line(
+    py: Python,
+    num_qubits: usize,
+    do_swaps: bool,
+    approximation_degree: usize,
+) -> PyResult<CircuitData> {
+    // Total number of compound gates required = L(L-1)/2
+    // For each compound gate -> H + 3CX + 3P
+    // For approximation degree D, D(D+1)/2 * 3 gates will be reduced
+    let mut no_of_gates = num_qubits + (num_qubits * (num_qubits - 1) / 2) * 6
+        - (approximation_degree * (approximation_degree + 1) / 2) * 3;
path: crates/accelerate/src/synthesis/qft/qft_decompose_lnn.rs
user: login: Cryoris
body: Neat thanks! Did you verify this formula by looking at the outcomes of `synth_qft_line(num_qubits).count_ops()`? For example, I think there's not 1 H gate per compound block, but there should only be `num_qubits` H gates in total 🤔 
created_at: 2025-04-04T13:46:39Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,123 @@
+// This code is part of Qiskit.
+//
+// (C) Copyright IBM 2023.
+//
+// This code is licensed under the Apache License, Version 2.0. You may
+// obtain a copy of this license in the LICENSE.txt file in the root directory
+// of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
+//
+// Any modifications or derivative works of this code must retain this
+// copyright notice, and modified files need to carry a notice indicating
+// that they have been altered from the originals.
+
+use crate::synthesis::linear_phase::cz_depth_lnn::LnnGatesVec;
+use crate::synthesis::permutation::_append_reverse_permutation_lnn_kms;
+use pyo3::prelude::*;
+use qiskit_circuit::circuit_data::CircuitData;
+use qiskit_circuit::operations::{Param, StandardGate};
+use qiskit_circuit::Qubit;
+use smallvec::smallvec;
+use std::f64::consts::PI;
+
+/// Construct a circuit for the Quantum Fourier Transform using linear
+/// neighbor connectivity.
+///
+/// The construction is based on Fig 2.b in Fowler et al. [1].
+///
+/// .. note::
+///
+///     With the default value of ``do_swaps = True``, this synthesis algorithm creates a
+///     circuit that faithfully implements the QFT operation. When ``do_swaps = False``,
+///     this synthesis algorithm creates a circuit that corresponds to "QFT-with-reversal":
+///     applying the QFT and reversing the order of its output qubits.
+///
+/// Args:
+///     num_qubits: The number of qubits on which the Quantum Fourier Transform acts.
+///     approximation_degree: The degree of approximation (0 for no approximation).
+///         It is possible to implement the QFT approximately by ignoring
+///         controlled-phase rotations with the angle beneath a threshold. This is discussed
+///         in more detail in https://arxiv.org/abs/quant-ph/9601018 or
+///         https://arxiv.org/abs/quant-ph/0403071.
+///     do_swaps: Whether to synthesize the "QFT" or the "QFT-with-reversal" operation.
+///
+/// Returns:
+///     A circuit implementing the QFT operation.
+///
+/// References:
+///     1. A. G. Fowler, S. J. Devitt, and L. C. L. Hollenberg,
+///        *Implementation of Shor's algorithm on a linear nearest neighbour qubit array*,
+///        Quantum Info. Comput. 4, 4 (July 2004), 237–251.
+///        `arXiv:quant-ph/0402196 [quant-ph] <https://arxiv.org/abs/quant-ph/0402196>`_
+
+#[pyfunction]
+#[pyo3(signature=(num_qubits, do_swaps=true, approximation_degree=0))]
+pub fn synth_qft_line(
+    py: Python,
+    num_qubits: usize,
+    do_swaps: bool,
+    approximation_degree: usize,
+) -> PyResult<CircuitData> {
+    // Total number of compound gates required = L(L-1)/2
+    // For each compound gate -> H + 3CX + 3P
+    // For approximation degree D, D(D+1)/2 * 3 gates will be reduced
+    let mut no_of_gates = num_qubits + (num_qubits * (num_qubits - 1) / 2) * 6
+        - (approximation_degree * (approximation_degree + 1) / 2) * 3;
path: crates/accelerate/src/synthesis/qft/qft_decompose_lnn.rs
user: login: Barath-T
body: i did check with `count_ops()`, but the comment is unclear, compound block can be `H+3CX+3P` or `3CX+3P`. ill update the comment. The calculation itself is correct in the code.
created_at: 2025-04-04T13:51:59Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,123 @@
+// This code is part of Qiskit.
+//
+// (C) Copyright IBM 2023.
+//
+// This code is licensed under the Apache License, Version 2.0. You may
+// obtain a copy of this license in the LICENSE.txt file in the root directory
+// of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
+//
+// Any modifications or derivative works of this code must retain this
+// copyright notice, and modified files need to carry a notice indicating
+// that they have been altered from the originals.
+
+use crate::synthesis::linear_phase::cz_depth_lnn::LnnGatesVec;
+use crate::synthesis::permutation::_append_reverse_permutation_lnn_kms;
+use pyo3::prelude::*;
+use qiskit_circuit::circuit_data::CircuitData;
+use qiskit_circuit::operations::{Param, StandardGate};
+use qiskit_circuit::Qubit;
+use smallvec::smallvec;
+use std::f64::consts::PI;
+
+/// Construct a circuit for the Quantum Fourier Transform using linear
+/// neighbor connectivity.
+///
+/// The construction is based on Fig 2.b in Fowler et al. [1].
+///
+/// .. note::
+///
+///     With the default value of ``do_swaps = True``, this synthesis algorithm creates a
+///     circuit that faithfully implements the QFT operation. When ``do_swaps = False``,
+///     this synthesis algorithm creates a circuit that corresponds to "QFT-with-reversal":
+///     applying the QFT and reversing the order of its output qubits.
+///
+/// Args:
+///     num_qubits: The number of qubits on which the Quantum Fourier Transform acts.
+///     approximation_degree: The degree of approximation (0 for no approximation).
+///         It is possible to implement the QFT approximately by ignoring
+///         controlled-phase rotations with the angle beneath a threshold. This is discussed
+///         in more detail in https://arxiv.org/abs/quant-ph/9601018 or
+///         https://arxiv.org/abs/quant-ph/0403071.
+///     do_swaps: Whether to synthesize the "QFT" or the "QFT-with-reversal" operation.
+///
+/// Returns:
+///     A circuit implementing the QFT operation.
+///
+/// References:
+///     1. A. G. Fowler, S. J. Devitt, and L. C. L. Hollenberg,
+///        *Implementation of Shor's algorithm on a linear nearest neighbour qubit array*,
+///        Quantum Info. Comput. 4, 4 (July 2004), 237–251.
+///        `arXiv:quant-ph/0402196 [quant-ph] <https://arxiv.org/abs/quant-ph/0402196>`_
path: crates/accelerate/src/synthesis/qft/qft_decompose_lnn.rs
user: login: alexanderivrii
body: I believe you may want to adapt the docstrings a little bit for the Rust code.
created_at: 2025-04-08T08:10:01Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,123 @@
+// This code is part of Qiskit.
+//
+// (C) Copyright IBM 2023.
+//
+// This code is licensed under the Apache License, Version 2.0. You may
+// obtain a copy of this license in the LICENSE.txt file in the root directory
+// of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
+//
+// Any modifications or derivative works of this code must retain this
+// copyright notice, and modified files need to carry a notice indicating
+// that they have been altered from the originals.
+
+use crate::synthesis::linear_phase::cz_depth_lnn::LnnGatesVec;
+use crate::synthesis::permutation::_append_reverse_permutation_lnn_kms;
+use pyo3::prelude::*;
+use qiskit_circuit::circuit_data::CircuitData;
+use qiskit_circuit::operations::{Param, StandardGate};
+use qiskit_circuit::Qubit;
+use smallvec::smallvec;
+use std::f64::consts::PI;
+
+/// Construct a circuit for the Quantum Fourier Transform using linear
+/// neighbor connectivity.
+///
+/// The construction is based on Fig 2.b in Fowler et al. [1].
+///
+/// .. note::
+///
+///     With the default value of ``do_swaps = True``, this synthesis algorithm creates a
+///     circuit that faithfully implements the QFT operation. When ``do_swaps = False``,
+///     this synthesis algorithm creates a circuit that corresponds to "QFT-with-reversal":
+///     applying the QFT and reversing the order of its output qubits.
+///
+/// Args:
+///     num_qubits: The number of qubits on which the Quantum Fourier Transform acts.
+///     approximation_degree: The degree of approximation (0 for no approximation).
+///         It is possible to implement the QFT approximately by ignoring
+///         controlled-phase rotations with the angle beneath a threshold. This is discussed
+///         in more detail in https://arxiv.org/abs/quant-ph/9601018 or
+///         https://arxiv.org/abs/quant-ph/0403071.
+///     do_swaps: Whether to synthesize the "QFT" or the "QFT-with-reversal" operation.
+///
+/// Returns:
+///     A circuit implementing the QFT operation.
+///
+/// References:
+///     1. A. G. Fowler, S. J. Devitt, and L. C. L. Hollenberg,
+///        *Implementation of Shor's algorithm on a linear nearest neighbour qubit array*,
+///        Quantum Info. Comput. 4, 4 (July 2004), 237–251.
+///        `arXiv:quant-ph/0402196 [quant-ph] <https://arxiv.org/abs/quant-ph/0402196>`_
+
+#[pyfunction]
+#[pyo3(signature=(num_qubits, do_swaps=true, approximation_degree=0))]
+pub fn synth_qft_line(
+    py: Python,
+    num_qubits: usize,
+    do_swaps: bool,
+    approximation_degree: usize,
+) -> PyResult<CircuitData> {
+    // Total number of compound gates required = L(L-1)/2
+    // Compound gate: H + 3CX + 3P or 3CX + 3P
+    // For approximation degree D, D(D+1)/2 * 3 gates will be reduced
+    let mut no_of_gates = num_qubits + (num_qubits * (num_qubits - 1) / 2) * 6
+        - (approximation_degree * (approximation_degree + 1) / 2) * 3;
+
+    if !do_swaps {
+        // `_append_reverse_permutation_lnn_kms` would add
+        no_of_gates += num_qubits * num_qubits - 1;
+    }
+
+    let mut instructions: LnnGatesVec = Vec::with_capacity(no_of_gates);
+
+    for i in 0..num_qubits {
+        // Hadamard
+        instructions.push((
+            StandardGate::H,
+            smallvec![],
+            smallvec![Qubit::new(num_qubits - 1)],
+        ));
path: crates/accelerate/src/synthesis/qft/qft_decompose_lnn.rs
user: login: alexanderivrii
body: Just for consistency, you could create a convenience method `append_h` like you do for other functions.
created_at: 2025-04-08T08:16:50Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,21 @@
+// This code is part of Qiskit.
+//
+// (C) Copyright IBM 2024
path: crates/accelerate/src/synthesis/qft/mod.rs
user: login: ShellyGarion
body: 2025
created_at: 2025-04-27T11:12:05Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,125 @@
+// This code is part of Qiskit.
+//
+// (C) Copyright IBM 2023.
path: crates/accelerate/src/synthesis/qft/qft_decompose_lnn.rs
user: login: ShellyGarion
body: 2025
created_at: 2025-04-27T11:12:28Z
author_association: MEMBER

PR comments:
user: login: qiskit-bot
created_at: 2025-04-02T17:53:44Z
body: Thank you for opening a new pull request.

Before your PR can be merged it will first need to pass continuous integration tests and be reviewed. Sometimes the review process can be slow, so please be patient.

While you're waiting, please feel free to review other open PRs. While only a subset of people are authorized to approve pull requests for merging, everyone is encouraged to review open pull requests. Doing reviews helps reduce the burden on the core team and helps make the project's code better for everyone.

One or more of the following people are relevant to this code:
- `@Qiskit/terra-core`

author_association: COLLABORATOR
user: login: coveralls
created_at: 2025-04-03T21:42:09Z
body: ## Pull Request Test Coverage Report for [Build 14700264921](https://coveralls.io/builds/73407656)


### Details

* **71** of **71**   **(100.0%)**  changed or added relevant lines in **6** files are covered.
* **20** unchanged lines in **2** files lost coverage.
* Overall coverage decreased (**-0.01%**) to **87.914%**

---


|  Files with Coverage Reduction | New Missed Lines | % |
| :-----|--------------|--: |
| [crates/qasm2/src/lex.rs](https://coveralls.io/builds/73407656/source?filename=crates%2Fqasm2%2Fsrc%2Flex.rs#L186) | 5 | 92.23% |
| [qiskit/synthesis/permutation/permutation_reverse_lnn.py](https://coveralls.io/builds/73407656/source?filename=qiskit%2Fsynthesis%2Fpermutation%2Fpermutation_reverse_lnn.py#L24) | 15 | 31.82% |
<!-- | **Total:** | **20** |  | -->

|  Totals | [![Coverage Status](https://coveralls.io/builds/73407656/badge)](https://coveralls.io/builds/73407656) |
| :-- | --: |
| Change from base [Build 14693758171](https://coveralls.io/builds/73402052): |  -0.01% |
| Covered Lines: | 74393 |
| Relevant Lines: | 84620 |

---
##### 💛  - [Coveralls](https://coveralls.io)

author_association: NONE
user: login: Barath-T
created_at: 2025-04-08T20:12:38Z
body: @alexanderivrii and @Cryoris Thank you for the review. I have updated the PR with the suggested changes. Please let me know if further refinements are needed. I'd also appreciate it if you can point me to other issues that i can contribute. Thank you in advance! :)
author_association: CONTRIBUTOR
user: login: alexanderivrii
created_at: 2025-04-09T06:56:05Z
body: @Barath-T, sorry, my suggestion in the previous review was incorrect:
since
```
#[pyfunction]
#[pyo3(signature=(num_qubits, do_swaps=true, approximation_degree=0))]
pub fn synth_qft_line(
```
is treated as a Python function, it actually needs sphinx style documentation, exactly like you had previously (thanks to @Cryoris for explaining that to me). Could you please revert this change (but keep the one to `append_h`)? In some sense, this does not even matter, as the main documentation includes the one from `synthesis/qft/qft_decompose_lnn.py` and not the one from `qft_decompose_lnn.rs`, but it might be good to keep it correct just in case.
author_association: MEMBER