From 10185527ecb93c237a9b9e359e67c23408f5833f Mon Sep 17 00:00:00 2001 From: 28Smiles Date: Tue, 5 Jul 2022 20:08:25 +0200 Subject: [PATCH] feat: Add example --- examples/quantum-teleportation.rs | 35 ++++++++++++++++++++ index.browser.d.ts | 2 ++ package.json | 1 + src/bindgen.rs | 2 +- src/quantum/computer.rs | 9 ++++-- src/quantum/ket.rs | 4 +-- src/quantum/operator/special/measurement.rs | 36 ++++++++++++++------- 7 files changed, 72 insertions(+), 17 deletions(-) create mode 100644 examples/quantum-teleportation.rs create mode 100644 index.browser.d.ts diff --git a/examples/quantum-teleportation.rs b/examples/quantum-teleportation.rs new file mode 100644 index 0000000..ec3192a --- /dev/null +++ b/examples/quantum-teleportation.rs @@ -0,0 +1,35 @@ +#![feature(generic_const_exprs)] + +use qukit::quantum::algorithm::QuantumAlgorithm; +use qukit::quantum::computer::QuantumComputer; +use qukit::quantum::operator::OperatorType; +use qukit::quantum::operator::simple::controlled::Controlled; +use qukit::quantum::operator::simple::hadamard::Hadamard; +use qukit::quantum::operator::simple::pauli_x::PauliX; +use qukit::quantum::operator::simple::pauli_z::PauliZ; +use qukit::quantum::operator::simple::Simple; +use qukit::quantum::operator::special::measurement::{Measurement, MeasurementBasis}; +use qukit::quantum::operator::special::Special; + +fn main() { + let mut quantum_computer = QuantumComputer::new(3, None); + for _ in 0..12 { + let mut algorithm = QuantumAlgorithm::new(Vec::new(), None); + + algorithm.add_gate(0, OperatorType::Simple(Simple::Hadamard(Hadamard::new(0)))); + + algorithm.add_gate(1, OperatorType::Simple(Simple::Hadamard(Hadamard::new(2)))); + algorithm.add_gate(2, OperatorType::Simple(Simple::ControlledPauliX(Controlled::new(2, PauliX::new(1))))); + + algorithm.add_gate(3, OperatorType::Simple(Simple::ControlledPauliX(Controlled::new(0, PauliX::new(1))))); + algorithm.add_gate(4, OperatorType::Simple(Simple::Hadamard(Hadamard::new(0)))); + algorithm.add_gate(5, OperatorType::Special(Special::Measurement(Measurement::new(0, Some(MeasurementBasis::Z), None, None)))); + algorithm.add_gate(5, OperatorType::Special(Special::Measurement(Measurement::new(1, Some(MeasurementBasis::Z), None, None)))); + + algorithm.add_gate(6, OperatorType::Simple(Simple::ControlledPauliX(Controlled::new(1, PauliX::new(2))))); + algorithm.add_gate(7, OperatorType::Simple(Simple::ControlledPauliZ(Controlled::new(0, PauliZ::new(2))))); + algorithm.run(&mut quantum_computer); + println!("{}", quantum_computer.state()); + quantum_computer.reset(); + } +} diff --git a/index.browser.d.ts b/index.browser.d.ts new file mode 100644 index 0000000..bbaf9d6 --- /dev/null +++ b/index.browser.d.ts @@ -0,0 +1,2 @@ +// @ts-ignore +export default import("./pkg.bundler/index.js"); diff --git a/package.json b/package.json index 34d307d..afbcbb7 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "pkg.web", "pkg.web-parallel", "index.browser.js", + "index.browser.d.ts", "README.md", "LICENCE" ], diff --git a/src/bindgen.rs b/src/bindgen.rs index 986f2d6..6cec3ab 100644 --- a/src/bindgen.rs +++ b/src/bindgen.rs @@ -31,7 +31,7 @@ impl QuantumComputer { /// Returns the state of the quantum computer pub fn state(&self) -> ComplexArray { - serde_wasm_bindgen::to_value(self.0.state()).unwrap().unchecked_into() + serde_wasm_bindgen::to_value(&self.0.state().vec).unwrap().unchecked_into() } /// Returns the probability of all states diff --git a/src/quantum/computer.rs b/src/quantum/computer.rs index 8d5f0a6..21e4c2a 100644 --- a/src/quantum/computer.rs +++ b/src/quantum/computer.rs @@ -2,7 +2,6 @@ use alloc::vec::Vec; use alloc::vec; use rand::SeedableRng; use rand::rngs::SmallRng; -use crate::complex::Complex; use crate::quantum::ket::Ket; pub struct QuantumComputer { @@ -18,8 +17,8 @@ impl QuantumComputer { } } - pub fn state(&self) -> &Vec { - &self.state.vec + pub fn state(&self) -> &Ket { + &self.state } pub fn amplitudes(&self) -> Vec { @@ -73,4 +72,8 @@ impl QuantumComputer { pub(crate) fn get_state(&self) -> &Ket { &self.state } + + pub fn reset(&mut self) { + self.state = Ket::new(self.state.size); + } } diff --git a/src/quantum/ket.rs b/src/quantum/ket.rs index 53f83e1..2f9ceee 100644 --- a/src/quantum/ket.rs +++ b/src/quantum/ket.rs @@ -89,10 +89,10 @@ impl Ket { impl Display for Ket { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { - for (i, a) in self.amplitudes().iter().enumerate() { + for (i, v) in self.vec.iter().enumerate() { let s = format!("{:#0width$b}", i, width = self.size as usize + 2); let (_, s) = s.split_at(2); - writeln!(f, "|{}> = {:05.2}%", s, a * 100.0)?; + writeln!(f, "|{}> = {}", s, v)?; } Ok(()) diff --git a/src/quantum/operator/special/measurement.rs b/src/quantum/operator/special/measurement.rs index 853c7c0..d88fa33 100644 --- a/src/quantum/operator/special/measurement.rs +++ b/src/quantum/operator/special/measurement.rs @@ -76,20 +76,34 @@ impl ApplyGate<1> for Measurement { MeasurementBasis::Z => {}, } - let proballily: f64 = computer.probability(self.wire); - let random_weight: f64 = 1.0 / (computer.seed.next_u64() as f64 + 1.0); - let state = proballily - random_weight > 0.0; + let probability: f64 = computer.probability(self.wire); + let random_weight: f64 = computer.seed.next_u32() as f64 / u32::MAX as f64; + let state = probability - random_weight > 0.0; if state { - Gate::new([ - [Complex::new(0.0, 0.0), Complex::new(0.0, 0.0)], - [Complex::new(0.0, 0.0), Complex::new(sqrt(1.0 / proballily), 0.0)], - ]) + if probability == 0.0 { + Gate::new([ + [Complex::new(0.0, 0.0), Complex::new(0.0, 0.0)], + [Complex::new(1.0, 0.0), Complex::new(0.0, 0.0)], + ]) + } else { + Gate::new([ + [Complex::new(0.0, 0.0), Complex::new(0.0, 0.0)], + [Complex::new(0.0, 0.0), Complex::new(sqrt(1.0 / probability), 0.0)], + ]) + } } else { - Gate::new([ - [Complex::new(sqrt(1.0 / proballily), 0.0), Complex::new(0.0, 0.0)], - [Complex::new(0.0, 0.0), Complex::new(0.0, 0.0)], - ]) + if probability == 0.0 { + Gate::new([ + [Complex::new(0.0, 0.0), Complex::new(1.0, 0.0)], + [Complex::new(0.0, 0.0), Complex::new(0.0, 0.0)], + ]) + } else { + Gate::new([ + [Complex::new(sqrt(1.0 / probability), 0.0), Complex::new(0.0, 0.0)], + [Complex::new(0.0, 0.0), Complex::new(0.0, 0.0)], + ]) + } }.apply(computer, self.wires()); match self.basis {