microsoft/qdk

Public

mirrored fromhttps://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
iadavis/pipeline-issue-debugging

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

source/noisy_simulator/src/tests/noisy_tests.rs

74lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use crate::{
5 NoisySimulator, SquareMatrix, operation::Operation, tests::assert_approx_eq_with_tolerance,
6};
7use nalgebra::dmatrix;
8use num_complex::Complex;
9
10use super::noiseless_tests;
11
12const I: Complex<f64> = Complex::I;
13const ZERO: Complex<f64> = Complex::ZERO;
14const ONE: Complex<f64> = Complex::ONE;
15
16fn pauli_identity() -> SquareMatrix {
17 SquareMatrix::identity(2, 2)
18}
19
20fn pauli_x() -> SquareMatrix {
21 dmatrix![ZERO, ONE;
22 ONE, ZERO;]
23}
24
25fn pauli_y() -> SquareMatrix {
26 dmatrix![ZERO, -I;
27 I, ZERO;]
28}
29
30fn pauli_z() -> SquareMatrix {
31 dmatrix![ONE, ZERO;
32 ZERO, -ONE;]
33}
34
35/// Returns a noisy identity gate.
36fn depolarizing_channel(lambda: f64) -> Operation {
37 // 0 <= 𝜆 <= 1 + 1 / (d^2 - 1)
38 const LAMBDA_UPPER_BOUND: f64 = 1. + 1. / (4. - 1.);
39 assert!((0. ..=LAMBDA_UPPER_BOUND).contains(&lambda));
40
41 let lambda: Complex<f64> = lambda.into();
42
43 // Define kraus matrices of the depolarizing channel.
44 let k0 = pauli_identity() * (1. - 3. * lambda / 4.).sqrt();
45 let k1 = pauli_x() * (lambda / 4.).sqrt();
46 let k2 = pauli_y() * (lambda / 4.).sqrt();
47 let k3 = pauli_z() * (lambda / 4.).sqrt();
48
49 Operation::new(vec![k0, k1, k2, k3]).expect("operation should be valid")
50}
51
52pub fn check_noisy_identity_yields_same_qubit_with_right_probability<NS: NoisySimulator>() {
53 const SHOTS: u64 = 500_000;
54
55 let depolarizing_channel = depolarizing_channel(0.1);
56 let mz = noiseless_tests::noiseless_mz();
57
58 let mut total_outcome: usize = 0;
59
60 // Run `SHOTS` simulations, on average we should measure the wrong outcome, i.e. 1,
61 // 5% of the times (𝜆 / 2).
62 for seed in 0..SHOTS {
63 let mut sim = NS::new_with_seed(1, seed);
64 sim.apply_operation(&depolarizing_channel, &[0])
65 .expect("operation should succeed");
66 total_outcome += sim
67 .sample_instrument(&mz, &[0])
68 .expect("operation should succeed");
69 }
70
71 #[allow(clippy::cast_precision_loss)]
72 let expected_outcome: f64 = (total_outcome as f64) / (SHOTS as f64);
73 assert_approx_eq_with_tolerance(0.05, expected_outcome, 0.001);
74}
75