quantrs2_ml/torchquantum/layer/
tqqftlayer_traits.rs1use 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}