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/instrument/tests.rs

95lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use super::Instrument;
5use crate::{
6 SquareMatrix,
7 instrument::vectorize,
8 operation::{Operation, operation},
9 tests::assert_approx_eq,
10};
11use nalgebra::ComplexField;
12use rand::{Rng, SeedableRng, rngs::StdRng};
13
14/// Seed for the random number generators.
15const SEED: u64 = 42;
16
17#[test]
18fn check_vectorize() {
19 let m = nalgebra::dmatrix![1, 2, 3;
20 4, 5, 6];
21 assert_eq!(nalgebra::dvector![1, 4, 2, 5, 3, 6], vectorize(&m));
22}
23
24#[test]
25#[should_panic(expected = "instrument should be invalid")]
26fn check_ill_formed_instrument_throws_error() {
27 let op0 = operation!([1., 0.;
28 0., 0.;])
29 .expect("operation should be valid");
30 let op1 = operation!([1., 0., 0., 0.;
31 0., 0., 0., 0.;
32 0., 0., 0., 0.;
33 0., 0., 0., 0.;])
34 .expect("operation should be valid");
35
36 let _instrument = Instrument::new(vec![op0, op1]).expect("instrument should be invalid");
37}
38
39/// Check that the inner matrices of the instrument are constructed correctly.
40#[test]
41fn check_non_selective_operation_matrix_is_computed_correctly() {
42 let mut rng = StdRng::seed_from_u64(SEED);
43 let mut rng = || rng.r#gen::<f64>();
44
45 let op0 = operation!([rng(), rng(); rng(), rng();]).expect("operation should be valid");
46 let op1 = operation!([rng(), rng(); rng(), rng();]).expect("operation should be valid");
47 let instrument = Instrument::new(vec![op0, op1]).expect("instrument should be valid");
48 let sum = instrument.non_selective_operation_matrix();
49 let op0 = instrument.operation(0);
50 let op1 = instrument.operation(1);
51
52 for row in 0..4 {
53 for col in 0..4 {
54 assert_approx_eq(
55 0.,
56 (sum[(row, col)] - (op0.matrix()[(row, col)] + op1.matrix()[(row, col)])).abs(),
57 );
58 }
59 }
60}
61
62#[test]
63fn check_non_selective_evolution_operator_is_computed_correctly() {
64 let dim = 8;
65 let mut rng = StdRng::seed_from_u64(SEED);
66 let mut rng = || rng.r#gen::<f64>();
67
68 // Create dim^2 random kraus operators.
69 let kraus_operators: Vec<SquareMatrix> = (0..dim * dim)
70 .map(|_| SquareMatrix::from_fn(dim, dim, |_, _| (0.5 - rng()).into()))
71 .collect();
72 let op0 = Operation::new(kraus_operators).expect("operation should be valid");
73 let instrument_0 = Instrument::new(vec![op0]).expect("instrument should be valid");
74
75 // Performance note: We reverse the transposition made by
76 // the performance optimization related to nalgebra column major
77 // order before passing the kraus_operators again into Operator::new.
78 //
79 // See noisy_simulator/src/operation.rs/Operation::new for more details.
80 let kraus_operators: Vec<SquareMatrix> = instrument_0
81 .non_selective_kraus_operators()
82 .iter()
83 .map(nalgebra::Matrix::transpose)
84 .collect();
85
86 let op1 = Operation::new(kraus_operators).expect("operation should be valid");
87 let instrument_1 = Instrument::new(vec![op1]).expect("instrument should be valid");
88 let m0 = instrument_0.non_selective_operation_matrix();
89 let m1 = instrument_1.non_selective_operation_matrix();
90
91 for (x0, x1) in m0.iter().zip(m1.iter()) {
92 assert_approx_eq(x0.re, x1.re);
93 assert_approx_eq(x0.im, x1.im);
94 }
95}
96