LCOV - code coverage report
Current view: top level - src/operations - multi_qubit_gate_operations.rs (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 37 37 100.0 %
Date: 2021-11-09 13:25:48 Functions: 18 18 100.0 %

          Line data    Source code
       1             : // Copyright © 2021 HQS Quantum Simulations GmbH. All Rights Reserved.
       2             : //
       3             : // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
       4             : // in compliance with the License. You may obtain a copy of the License at
       5             : //
       6             : //     http://www.apache.org/licenses/LICENSE-2.0
       7             : //
       8             : // Unless required by applicable law or agreed to in writing, software distributed under the
       9             : // License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
      10             : // express or implied. See the License for the specific language governing permissions and
      11             : // limitations under the License.
      12             : 
      13             : use crate::operations;
      14             : use crate::prelude::*;
      15             : use crate::Circuit;
      16             : use crate::RoqoqoError;
      17             : use ndarray::Array2;
      18             : use num_complex::Complex64;
      19             : use qoqo_calculator::CalculatorFloat;
      20             : #[cfg(feature = "overrotate")]
      21             : use rand_distr::{Distribution, Normal};
      22             : #[cfg(feature = "serialize")]
      23             : use serde::{Deserialize, Serialize};
      24             : 
      25             : /// The Molmer-Sorensen gate between multiple qubits.
      26             : ///
      27             : #[allow(clippy::upper_case_acronyms)]
      28             : #[derive(
      29           1 :     Debug,
      30           7 :     Clone,
      31           9 :     PartialEq,
      32           1 :     roqoqo_derive::InvolveQubits,
      33          35 :     roqoqo_derive::Operate,
      34           6 :     roqoqo_derive::Substitute,
      35           2 :     roqoqo_derive::OperateMultiQubit,
      36          24 :     roqoqo_derive::Rotate,
      37             : )]
      38             : #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
      39             : pub struct MultiQubitMS {
      40             :     /// The qubits involved in the multi qubit Molmer-Sorensen gate.
      41             :     qubits: Vec<usize>,
      42             :     /// The angle of the multi qubit Molmer-Sorensen gate.
      43             :     theta: CalculatorFloat,
      44             : }
      45             : 
      46             : #[allow(non_upper_case_globals)]
      47             : const TAGS_MultiQubitMS: &[&str; 4] = &[
      48             :     "Operation",
      49             :     "GateOperation",
      50             :     "MultiQubitGateOperation",
      51             :     "MultiQubitMS",
      52             : ];
      53             : 
      54             : impl OperateGate for MultiQubitMS {
      55           2 :     fn unitary_matrix(&self) -> Result<Array2<Complex64>, RoqoqoError> {
      56           2 :         let dim = 2_usize.pow(self.qubits.len() as u32);
      57           2 :         let mut array: Array2<Complex64> = Array2::zeros((dim, dim));
      58           2 :         let cos: Complex64 = Complex64::new((self.theta.float()? / 2.0).cos(), 0.0);
      59           2 :         let sin: Complex64 = Complex64::new(0.0, -(self.theta.float()? / 2.0).sin());
      60          12 :         for i in 0..dim {
      61          12 :             array[(i, i)] = cos;
      62          12 :             array[(i, dim - i - 1)] = sin;
      63          12 :         }
      64           2 :         Ok(array)
      65           2 :     }
      66             : }
      67             : 
      68             : impl OperateMultiQubitGate for MultiQubitMS {
      69             :     // Todo fill out circuit
      70           2 :     fn circuit(&self) -> Circuit {
      71           2 :         let dim = self.qubits.len();
      72           2 :         let mut circuit = Circuit::new();
      73           5 :         for q in self.qubits.iter() {
      74           5 :             circuit += operations::Hadamard::new(*q);
      75           5 :         }
      76           3 :         for q in self.qubits[1..].iter() {
      77           3 :             circuit += operations::CNOT::new(*q - 1, *q);
      78           3 :         }
      79           2 :         circuit += operations::RotateZ::new(dim - 1, self.theta.clone() / 2);
      80           3 :         for q in self.qubits[1..].iter() {
      81           3 :             circuit += operations::CNOT::new(dim - *q - 1, dim - *q);
      82           3 :         }
      83           5 :         for q in self.qubits.iter() {
      84           5 :             circuit += operations::Hadamard::new(*q);
      85           5 :         }
      86           2 :         circuit
      87           2 :     }
      88             : }

Generated by: LCOV version 1.13