Skip to main content

ppvm_traits/traits/branch/
rot2.rs

1// SPDX-FileCopyrightText: 2026 The PPVM Authors
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::config::Config;
5
6macro_rules! def_rotation {
7    ($name:ident, $batch:ident, $x_a:expr, $z_a:expr, $x_b:expr, $z_b:expr, $doc:literal) => {
8        #[doc = $doc]
9        fn $name(&mut self, a: usize, b: usize, theta: impl Into<T::Coeff>) {
10            self.rotate_2([$x_a, $z_a], [$x_b, $z_b], a, b, theta.into())
11        }
12
13        #[doc = concat!("Explicit batched form of [`", stringify!($name), "`].")]
14        fn $batch(&mut self, pairs: &[(usize, usize)], theta: impl Into<T::Coeff>) {
15            let theta = theta.into();
16            for &(a, b) in pairs {
17                self.$name(a, b, theta.clone())
18            }
19        }
20    };
21}
22
23/// Two-qubit Pauli rotations, generated by `P_a ⊗ P_b` for any pair of
24/// non-identity Paulis. Provides the named convenience methods
25/// `rxx`, `rxy`, …, `rzz` on top of the generic [`rotate_2`].
26///
27/// [`rotate_2`]: RotationTwo::rotate_2
28pub trait RotationTwo<T: Config> {
29    /// Two-qubit Pauli rotation: `exp(-i * theta/2 * P_a ⊗ P_b)`.
30    ///
31    /// Each axis is encoded as `[x, z]` bits:
32    /// `[0,0]` = I, `[1,0]` = X, `[0,1]` = Z, `[1,1]` = Y.
33    fn rotate_2(&mut self, axis_a: [u8; 2], axis_b: [u8; 2], a: usize, b: usize, theta: T::Coeff);
34
35    //                 x, z, x, z
36    def_rotation!(rxx, rxx_many, 1, 0, 1, 0, "`exp(-i θ/2 · X_a X_b)`.");
37    def_rotation!(rxy, rxy_many, 1, 0, 1, 1, "`exp(-i θ/2 · X_a Y_b)`.");
38    def_rotation!(rxz, rxz_many, 1, 0, 0, 1, "`exp(-i θ/2 · X_a Z_b)`.");
39
40    def_rotation!(ryx, ryx_many, 1, 1, 1, 0, "`exp(-i θ/2 · Y_a X_b)`.");
41    def_rotation!(ryy, ryy_many, 1, 1, 1, 1, "`exp(-i θ/2 · Y_a Y_b)`.");
42    def_rotation!(ryz, ryz_many, 1, 1, 0, 1, "`exp(-i θ/2 · Y_a Z_b)`.");
43
44    def_rotation!(rzx, rzx_many, 0, 1, 1, 0, "`exp(-i θ/2 · Z_a X_b)`.");
45    def_rotation!(rzy, rzy_many, 0, 1, 1, 1, "`exp(-i θ/2 · Z_a Y_b)`.");
46    def_rotation!(rzz, rzz_many, 0, 1, 0, 1, "`exp(-i θ/2 · Z_a Z_b)`.");
47}