Skip to main content

quantrs2_ml/torchquantum/layer/
tqqftlayer_traits.rs

1//! # TQQFTLayer - Trait Implementations
2//!
3//! This module contains trait implementations for `TQQFTLayer`.
4//!
5//! ## Implemented Traits
6//!
7//! - `TQModule`
8//!
9//! 🤖 Generated with [SplitRS](https://github.com/cool-japan/splitrs)
10
11use crate::error::{MLError, Result};
12use crate::torchquantum::{
13    gates::{
14        TQHadamard, TQPauliX, TQPauliY, TQPauliZ, TQRx, TQRy, TQRz, TQCNOT, TQCRX, TQCRY, TQCRZ,
15        TQCZ, TQRXX, TQRYY, TQRZX, TQRZZ, TQS, TQSWAP, TQSX, TQT,
16    },
17    CType, TQDevice, TQModule, TQOperator, TQParameter,
18};
19
20use super::functions::{create_single_qubit_gate, create_two_qubit_gate};
21use super::types::TQQFTLayer;
22
23impl TQModule for TQQFTLayer {
24    fn forward(&mut self, qdev: &mut TQDevice) -> Result<()> {
25        use crate::torchquantum::gates::{TQHadamard, TQCU1, TQSWAP};
26        use std::f64::consts::PI;
27        if self.inverse {
28            if self.do_swaps {
29                for wire in 0..(self.n_wires / 2) {
30                    let mut swap_gate = TQSWAP::new();
31                    swap_gate.apply(
32                        qdev,
33                        &[self.wires[wire], self.wires[self.n_wires - wire - 1]],
34                    )?;
35                }
36            }
37            for top_wire in (0..self.n_wires).rev() {
38                for wire in ((top_wire + 1)..self.n_wires).rev() {
39                    let lam = -PI / (1 << (wire - top_wire)) as f64;
40                    let mut cu1_gate = TQCU1::new(true, false);
41                    cu1_gate.apply_with_params(
42                        qdev,
43                        &[self.wires[wire], self.wires[top_wire]],
44                        Some(&[lam]),
45                    )?;
46                }
47                let mut h_gate = TQHadamard::new();
48                h_gate.apply(qdev, &[self.wires[top_wire]])?;
49            }
50        } else {
51            for top_wire in 0..self.n_wires {
52                let mut h_gate = TQHadamard::new();
53                h_gate.apply(qdev, &[self.wires[top_wire]])?;
54                for wire in (top_wire + 1)..self.n_wires {
55                    let lam = PI / (1 << (wire - top_wire)) as f64;
56                    let mut cu1_gate = TQCU1::new(true, false);
57                    cu1_gate.apply_with_params(
58                        qdev,
59                        &[self.wires[wire], self.wires[top_wire]],
60                        Some(&[lam]),
61                    )?;
62                }
63            }
64            if self.do_swaps {
65                for wire in 0..(self.n_wires / 2) {
66                    let mut swap_gate = TQSWAP::new();
67                    swap_gate.apply(
68                        qdev,
69                        &[self.wires[wire], self.wires[self.n_wires - wire - 1]],
70                    )?;
71                }
72            }
73        }
74        Ok(())
75    }
76    fn parameters(&self) -> Vec<TQParameter> {
77        Vec::new()
78    }
79    fn n_wires(&self) -> Option<usize> {
80        Some(self.n_wires)
81    }
82    fn set_n_wires(&mut self, n_wires: usize) {
83        self.n_wires = n_wires;
84        self.wires = (0..n_wires).collect();
85    }
86    fn is_static_mode(&self) -> bool {
87        self.static_mode
88    }
89    fn static_on(&mut self) {
90        self.static_mode = true;
91    }
92    fn static_off(&mut self) {
93        self.static_mode = false;
94    }
95    fn name(&self) -> &str {
96        if self.inverse {
97            "InverseQFTLayer"
98        } else {
99            "QFTLayer"
100        }
101    }
102}