1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Copyright © 2023 HQS Quantum Simulations GmbH. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
// express or implied. See the License for the specific language governing permissions and
// limitations under the License.

//! Noise models for qoqo/roqoqo
//!
//! A collection of noise models that describe the physical noise present of quantum computers.
//!

mod continuous_decoherence;
pub use continuous_decoherence::ContinuousDecoherenceModel;
mod imperfect_readout;
pub use imperfect_readout::ImperfectReadoutModel;
mod decoherence_on_gate;
use super::operations::SupportedVersion;
pub use decoherence_on_gate::DecoherenceOnGateModel;
mod overrotation;
pub use overrotation::{SingleQubitOverrotationDescription, SingleQubitOverrotationOnGate};
mod decoherence_on_idle;
pub use decoherence_on_idle::DecoherenceOnIdleModel;

/// Collection of all available noise models in this version of qoqo/roqoqo
///
/// Intended as common interface to exchange noise models.
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
pub enum NoiseModel {
    /// Continuous decoherence model
    ContinuousDecoherenceModel(ContinuousDecoherenceModel),
    /// Readout error model (probabilities to measure 0 instead of 1 and vice-versa).
    ImperfectReadoutModel(ImperfectReadoutModel),
    /// Additional error only when applying gate
    DecoherenceOnGateModel(DecoherenceOnGateModel),
    /// Additional error only when applying gate
    SingleQubitOverrotationOnGate(SingleQubitOverrotationOnGate),
    /// Dechoherence on idle qubits model
    DecoherenceOnIdleModel(DecoherenceOnIdleModel),
}

impl From<ContinuousDecoherenceModel> for NoiseModel {
    fn from(value: ContinuousDecoherenceModel) -> Self {
        Self::ContinuousDecoherenceModel(value)
    }
}

impl From<ImperfectReadoutModel> for NoiseModel {
    fn from(value: ImperfectReadoutModel) -> Self {
        Self::ImperfectReadoutModel(value)
    }
}

impl From<DecoherenceOnGateModel> for NoiseModel {
    fn from(value: DecoherenceOnGateModel) -> Self {
        Self::DecoherenceOnGateModel(value)
    }
}

impl From<SingleQubitOverrotationOnGate> for NoiseModel {
    fn from(value: SingleQubitOverrotationOnGate) -> Self {
        Self::SingleQubitOverrotationOnGate(value)
    }
}

impl From<DecoherenceOnIdleModel> for NoiseModel {
    fn from(value: DecoherenceOnIdleModel) -> Self {
        Self::DecoherenceOnIdleModel(value)
    }
}

impl SupportedVersion for NoiseModel {
    fn minimum_supported_roqoqo_version(&self) -> (u32, u32, u32) {
        match self {
            NoiseModel::ContinuousDecoherenceModel(internal) => {
                internal.minimum_supported_roqoqo_version()
            }
            NoiseModel::ImperfectReadoutModel(internal) => {
                internal.minimum_supported_roqoqo_version()
            }
            NoiseModel::DecoherenceOnGateModel(internal) => {
                internal.minimum_supported_roqoqo_version()
            }
            NoiseModel::SingleQubitOverrotationOnGate(internal) => {
                internal.minimum_supported_roqoqo_version()
            }
            NoiseModel::DecoherenceOnIdleModel(internal) => {
                internal.minimum_supported_roqoqo_version()
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn minimum_supported_roqoqo_version_continuous() {
        let continuous_decoherence = ContinuousDecoherenceModel::new();
        let noise_model: NoiseModel = continuous_decoherence.into();
        assert_eq!(noise_model.minimum_supported_roqoqo_version(), (1, 6, 0));
    }
    #[test]
    fn minimum_supported_roqoqo_version_on_gate() {
        let noise = DecoherenceOnGateModel::new();
        let noise_model: NoiseModel = noise.into();
        assert_eq!(noise_model.minimum_supported_roqoqo_version(), (1, 6, 0));
    }
    #[test]
    fn minimum_supported_roqoqo_version_readout() {
        let noise = ImperfectReadoutModel::new();
        let noise_model: NoiseModel = noise.into();
        assert_eq!(noise_model.minimum_supported_roqoqo_version(), (1, 6, 0));
    }
    #[test]
    fn minimum_supported_roqoqo_version_overrotations() {
        let noise = SingleQubitOverrotationOnGate::new();
        let noise_model: NoiseModel = noise.into();
        assert_eq!(noise_model.minimum_supported_roqoqo_version(), (1, 11, 0));
    }
    #[test]
    fn minimum_supported_roqoqo_version_on_idle() {
        let noise = DecoherenceOnIdleModel::new();
        let noise_model: NoiseModel = noise.into();
        assert_eq!(noise_model.minimum_supported_roqoqo_version(), (1, 11, 0));
    }
}