Skip to content

Commit f828e35

Browse files
authored
Merge pull request #33 from qsharp-community/noise
Improved noise model
2 parents 485ab7d + e685f11 commit f828e35

9 files changed

Lines changed: 293 additions & 87 deletions

File tree

src/lib.rs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
uniffi::include_scaffolding!("qsharp-bridge");
22

3-
use crate::sim::qir;
3+
use crate::noise::Noise;
4+
use crate::noise::PauliNoiseDistribution;
5+
use crate::qasm::QasmGenerationOptions;
6+
use crate::qasm::QasmResetBehavior;
7+
use crate::qasm::qasm2;
8+
use crate::qasm::qasm2_expression;
9+
use crate::sim::ExecutionOptions;
10+
use crate::sim::ExecutionState;
11+
use crate::sim::QsError;
12+
use crate::sim::QubitState;
413
use crate::sim::estimate;
514
use crate::sim::estimate_expression;
6-
use crate::sim::qasm2;
7-
use crate::sim::qasm2_expression;
15+
use crate::sim::qir;
816
use crate::sim::run_qs;
917
use crate::sim::run_qs_with_options;
10-
use crate::sim::ExecutionState;
11-
use crate::sim::QsError;
12-
use crate::sim::QubitState;
13-
use crate::sim::ExecutionOptions;
14-
use crate::sim::PauliDistribution;
15-
use crate::qasm::QasmGenerationOptions;
16-
use crate::qasm::QasmResetBehavior;
1718

19+
pub mod noise;
20+
pub mod qasm;
1821
pub mod sim;
19-
pub mod qasm;

src/noise.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
use crate::sim::QsError;
2+
3+
#[derive(Debug, Clone)]
4+
pub enum Noise {
5+
Ideal,
6+
Pauli {
7+
noise: PauliNoiseDistribution,
8+
},
9+
BitFlip {
10+
p: f64,
11+
},
12+
PhaseFlip {
13+
p: f64,
14+
},
15+
Depolarizing {
16+
p: f64,
17+
},
18+
}
19+
20+
impl Noise {
21+
pub fn to_distribution(&self) -> Result<PauliNoiseDistribution, QsError> {
22+
match self {
23+
Noise::Ideal => PauliNoiseDistribution::new(0.0, 0.0, 0.0),
24+
Noise::Pauli { noise } => Ok(noise.clone()),
25+
Noise::BitFlip { p } => PauliNoiseDistribution::new(*p, 0.0, 0.0),
26+
Noise::PhaseFlip { p } => PauliNoiseDistribution::new(0.0, 0.0, *p),
27+
Noise::Depolarizing { p } => PauliNoiseDistribution::new(*p / 3.0, *p / 3.0, *p / 3.0),
28+
}
29+
}
30+
}
31+
32+
impl Default for Noise {
33+
fn default() -> Self {
34+
Noise::Ideal
35+
}
36+
}
37+
38+
#[derive(Debug, Clone)]
39+
pub struct PauliNoiseDistribution {
40+
pub x: f64,
41+
pub y: f64,
42+
pub z: f64,
43+
}
44+
45+
impl PauliNoiseDistribution {
46+
pub fn new(x: f64, y: f64, z: f64) -> Result<Self, QsError> {
47+
if x < 0.0 || y < 0.0 || z < 0.0 || x + y + z > 1.0 {
48+
return Err(QsError::ErrorMessage {
49+
error_text:
50+
"Invalid Pauli distribution: values must be non-negative and sum to <= 1.0"
51+
.to_string(),
52+
});
53+
}
54+
Ok(Self { x, y, z })
55+
}
56+
}

src/qasm.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,33 @@
11
use std::collections::HashSet;
22
use num_bigint::BigUint;
33
use num_complex::Complex;
4-
use qsc::{interpret::Value, Backend};
4+
use qsc::{interpret::{GenericReceiver, Value}, Backend, PackageType, TargetCapabilityFlags};
5+
6+
use crate::sim::{create_interpreter, QsError};
7+
8+
pub fn qasm2(source: &str, generation_options: QasmGenerationOptions) -> Result<String, QsError> {
9+
let mut stdout = vec![];
10+
let mut out = GenericReceiver::new(&mut stdout);
11+
let mut backend = Qasm2Backend::new(generation_options);
12+
13+
let mut interpreter = create_interpreter(Some(source), PackageType::Exe, TargetCapabilityFlags::empty())?;
14+
let _ = interpreter.eval_entry_with_sim(&mut backend, &mut out)?;
15+
16+
let qasm = backend.get_qasm().map_err(|errors| QsError::ErrorMessage { error_text: errors.join(", ") })?;
17+
Ok(qasm)
18+
}
19+
20+
pub fn qasm2_expression(expression: &str, generation_options: QasmGenerationOptions) -> Result<String, QsError> {
21+
let mut stdout = vec![];
22+
let mut out = GenericReceiver::new(&mut stdout);
23+
let mut backend = Qasm2Backend::new(generation_options);
24+
25+
let mut interpreter = create_interpreter(None, PackageType::Lib, TargetCapabilityFlags::empty())?;
26+
let _ = interpreter.run_with_sim(&mut backend, &mut out, Some(expression))?;
27+
28+
let qasm = backend.get_qasm().map_err(|errors| QsError::ErrorMessage { error_text: errors.join(", ") })?;
29+
Ok(qasm)
30+
}
531

632
pub(crate) struct Qasm2Backend {
733
code: Vec<String>,

src/qsharp-bridge.udl

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,32 @@ enum QasmResetBehavior {
3333
"Error"
3434
};
3535

36-
dictionary PauliDistribution {
36+
[Enum]
37+
interface Noise {
38+
Ideal();
39+
Pauli(PauliNoiseDistribution noise);
40+
BitFlip(f64 p);
41+
PhaseFlip(f64 p);
42+
Depolarizing(f64 p);
43+
};
44+
45+
dictionary PauliNoiseDistribution {
3746
f64 x;
3847
f64 y;
3948
f64 z;
4049
};
4150

4251
interface ExecutionOptions {
43-
constructor(u32 shots, PauliDistribution noise);
52+
constructor(u32 shots, Noise noise, f64? qubit_loss);
4453

4554
[Name=from_shots]
4655
constructor(u32 shots);
4756

4857
[Name=from_noise]
49-
constructor(PauliDistribution noise);
58+
constructor(Noise noise);
59+
60+
[Name=from_qubit_loss]
61+
constructor(f64 qubit_loss);
5062
};
5163

5264
[Error]

0 commit comments

Comments
 (0)