-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Examples PR 1: dense_coding, bell_inequalities, cswap #41
base: master
Are you sure you want to change the base?
Changes from all commits
a68f6b4
159fa4a
fc55645
e93e12c
f0473b6
cd008c5
dec9ce6
2eb3778
0f89ef2
dbdff4a
3df9d80
06d234c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
use qip::builder::StochasticMeasurementHandle; | ||
#[cfg(feature = "macros")] | ||
use qip::prelude::*; | ||
#[cfg(feature = "macros")] | ||
use qip::prelude::{CircuitBuilder, CircuitError}; | ||
#[cfg(feature = "macros")] | ||
use qip_macros::*; | ||
#[cfg(feature = "macros")] | ||
use qip::macros::program_ops::*; | ||
use std::num::NonZeroUsize; | ||
|
||
#[cfg(feature = "macros")] | ||
fn circuit1() -> &'static [f64]{ | ||
let mut b = LocalBuilder::<f64>::default(); | ||
let n = NonZeroUsize::new(2).unwrap(); | ||
|
||
let q = b.qubit(); | ||
let r1 = b.register(n); | ||
let r = program!(&mut b; r1; | ||
not r; | ||
h r[0]; | ||
control not r[0], r[1]; | ||
rz(std::f64::consts::FRAC_PI_3) r[1]; | ||
h r; | ||
).unwrap(); | ||
let (r, m_handle) = b.measure_stochastic(r); | ||
|
||
//run and get probabilities | ||
let (r, m_handle) = b.measure_stochastic(r); //returns (Self::Register, Self::StochasticMeasurementHandle) | ||
let (_, measurements) = b.calculate_state(); | ||
let stochastic_measurement_probability = measurements.get_stochastic_measurement(m_handle); | ||
return stochastic_measurement_probability; | ||
} | ||
|
||
#[cfg(feature = "macros")] | ||
fn circuit2() -> &'static [f64]{ | ||
let mut b = LocalBuilder::<f64>::default(); | ||
let n = NonZeroUsize::new(2).unwrap(); | ||
|
||
let r2 = b.register(n); | ||
let r = program!( &mut b; r2; | ||
not r; | ||
h r[0]; | ||
control not r[0], r[1]; | ||
rz(2. * std::f64::consts::FRAC_PI_3) r[1]; | ||
h r; | ||
).unwrap(); | ||
let (r, m_handle) = b.measure_stochastic(r); | ||
|
||
// run and get probabilities | ||
let (r, m_handle) = b.measure_stochastic(r); //returns (Self::Register, Self::StochasticMeasurementHandle) | ||
let (_, measurements) = b.calculate_state(); | ||
let stochastic_measurement_probability = measurements.get_stochastic_measurement(m_handle); | ||
return stochastic_measurement_probability; | ||
} | ||
#[cfg(feature = "macros")] | ||
fn circuit3() -> &'static [f64] { | ||
let mut b = LocalBuilder::<f64>::default(); | ||
let n = NonZeroUsize::new(2).unwrap(); | ||
let r3 = b.register(n); | ||
|
||
let r = program!(&mut b; r3; | ||
not r; | ||
h r[0]; | ||
control not r[0], r[1]; | ||
rz(std::f64::consts::FRAC_PI_3) r[0]; | ||
rz(2. * std::f64::consts::FRAC_PI_3) r[1]; | ||
h r; | ||
).unwrap(); | ||
let (r, m_handle) = b.measure_stochastic(r); //returns (Self::Register, Self::StochasticMeasurementHandle) | ||
let (_, measurements) = b.calculate_state(); | ||
let stochastic_measurement_probability = measurements.get_stochastic_measurement(m_handle); | ||
return stochastic_measurement_probability; | ||
|
||
} | ||
|
||
#[cfg(not(feature = "macros"))] | ||
fn main() -> () {} | ||
|
||
|
||
|
||
#[cfg(feature = "macros")] | ||
fn main() -> Result<(), CircuitError> { | ||
println!("Bell inequality: |P(a, b) - P(a, c)| - P(b, c) <= 1"); | ||
|
||
let a_b = circuit1(); | ||
let p_of_a_b = (a_b[0] + a_b[3]) - (a_b[1] + a_b[2]); | ||
println!("P(a, b) = {:.2}", p_of_a_b); | ||
|
||
let a_c = circuit2(); | ||
let p_of_a_c = (a_c[0] + a_c[3]) - (a_c[1] + a_c[2]); | ||
println!("P(a, c) = {:.2}", p_of_a_c); | ||
|
||
let b_c = circuit3(); | ||
println!("{:?}", b_c); | ||
let p_of_b_c = (b_c[0] + b_c[3]) - (b_c[1] + b_c[2]); | ||
println!("P(b, c) = {:.2}", p_of_b_c); | ||
|
||
let left_side = (p_of_a_b - p_of_a_c).abs() - p_of_b_c; | ||
println!( | ||
"|{:.2} - {:.2}| - ({:.2}) = {:.2} IS NOT <= 1", | ||
p_of_a_b, p_of_a_c, p_of_b_c, left_side | ||
); | ||
|
||
assert!(left_side > 1.0); | ||
|
||
Ok(()) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
use qip::prelude::*; | ||
use std::num::NonZeroUsize; | ||
|
||
fn main() -> Result<(), CircuitError> { | ||
let mut b = LocalBuilder::<f64>::default(); | ||
let n = NonZeroUsize::new(3).unwrap(); | ||
|
||
let q = b.qubit(); | ||
let ra = b.register(n); | ||
let rb = b.register(n); | ||
|
||
let q = b.h(q); | ||
|
||
let mut cb = b.condition_with(q); | ||
let (ra, rb) = cb.swap(ra, rb).unwrap(); | ||
let q = cb.dissolve(); | ||
|
||
let q = b.h(q); | ||
|
||
let (q, m_handle) = b.measure(q); | ||
|
||
let (_, measured) = b.calculate_state_with_init([(&ra, 0b000), (&rb, 0b001)]); | ||
let (result, p) = measured.get_measurement(m_handle); | ||
println!("Measured: {:?} (with chance {:?})", result, p); | ||
|
||
Ok(()) | ||
} |
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
@@ -0,0 +1,70 @@ | ||||
use qip::builder::Qudit; | ||||
use qip::prelude::*; | ||||
use std::num::NonZeroUsize; | ||||
|
||||
/// Encode the two classical bits Alice wants to communicate to Bob. | ||||
/// | ||||
/// Depending on the classical bits combination a different gate is applied: | ||||
/// 00: Do nothing (or apply Identity gate) | ||||
/// 01: Apply Pauli-X gate | ||||
/// 10: Apply Pauli-Z gate | ||||
/// 11: Apply Pauli-Y gate (or apply Pauli-Z gate followed by a Pauli-X gate) | ||||
/// | ||||
/// Returns Alice qubit with applied gate. | ||||
/// | ||||
/// https://en.wikipedia.org/wiki/Superdense_coding#Encoding | ||||
fn run_alice<P: Precision, CB: CliffordTBuilder<P>>( | ||||
b: &mut CB, | ||||
epr_alice: CB::Register, | ||||
bit_a: bool, | ||||
bit_b: bool, | ||||
) -> CB::Register { | ||||
match (bit_a, bit_b) { | ||||
(false, false) => epr_alice, | ||||
(false, true) => b.x(epr_alice), | ||||
(true, false) => b.z(epr_alice), | ||||
(true, true) => b.y(epr_alice), | ||||
} | ||||
} | ||||
|
||||
/// Decode the message Alice transmitted to Bob. | ||||
/// | ||||
/// Bob applies the restoration operation on his qubit and the one transmitted | ||||
/// by Alice to decode the original message. After restoration: | ||||
/// |00>: 00 | ||||
/// |10>: 10 | ||||
/// |01>: 01 | ||||
/// |11>: 11 | ||||
/// | ||||
/// Returns a pair of classical bits. | ||||
/// | ||||
/// https://en.wikipedia.org/wiki/Superdense_coding#Decoding | ||||
fn run_bob<P: Precision>(b: &mut LocalBuilder<P>, r_alice: Qudit, epr_bob: Qudit) -> (bool, bool) { | ||||
let (r_alice, r_bob) = b.cnot(r_alice, epr_bob).unwrap(); | ||||
let r_alice = b.h(r_alice); | ||||
let r = b.merge_two_registers(r_bob, r_alice); | ||||
let (r, m) = b.measure(r); | ||||
let (_, measurements) = b.calculate_state(); | ||||
let (m, _) = measurements.get_measurement(m); | ||||
((m & 2) == 2, (m & 1) == 1) | ||||
} | ||||
|
||||
fn main() { | ||||
let n = NonZeroUsize::new(1).unwrap(); | ||||
let bits_a = vec![true, false, true, false]; | ||||
let bits_b = vec![true, true, false, false]; | ||||
|
||||
for (bit_a, bit_b) in bits_a.into_iter().zip(bits_b.into_iter()) { | ||||
let mut b = LocalBuilder::<f64>::default(); | ||||
let epr_alice = b.register(n); | ||||
let epr_bob = b.register(n); | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You made a change here which broke the example: RustQIP/examples/dense_coding.rs Line 62 in 56757b5
I dont think the library currently has an EPR function, but I can add one later. You should look up how to make an EPR pair yourself and try implementing that as a helper function for this example. |
||||
|
||||
let r_alice = run_alice(&mut b, epr_alice, bit_a, bit_b); | ||||
let (bob_a, bob_b) = run_bob(&mut b, r_alice, epr_bob); | ||||
|
||||
println!( | ||||
"Alice: ({:?},{:?}) \tBob: ({:?}, {:?})", | ||||
bit_a, bit_b, bob_a, bob_b | ||||
); | ||||
} | ||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should put an error message here telling the user to run with the macro feature or
--all-features
.