Skip to content

Commit

Permalink
feat: Add example
Browse files Browse the repository at this point in the history
  • Loading branch information
28Smiles committed Jul 13, 2022
1 parent dac42e6 commit 1018552
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 17 deletions.
35 changes: 35 additions & 0 deletions examples/quantum-teleportation.rs
Original file line number Diff line number Diff line change
@@ -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();
}
}
2 changes: 2 additions & 0 deletions index.browser.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// @ts-ignore
export default import("./pkg.bundler/index.js");
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"pkg.web",
"pkg.web-parallel",
"index.browser.js",
"index.browser.d.ts",
"README.md",
"LICENCE"
],
Expand Down
2 changes: 1 addition & 1 deletion src/bindgen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 6 additions & 3 deletions src/quantum/computer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -18,8 +17,8 @@ impl QuantumComputer {
}
}

pub fn state(&self) -> &Vec<Complex> {
&self.state.vec
pub fn state(&self) -> &Ket {
&self.state
}

pub fn amplitudes(&self) -> Vec<f64> {
Expand Down Expand Up @@ -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);
}
}
4 changes: 2 additions & 2 deletions src/quantum/ket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(())
Expand Down
36 changes: 25 additions & 11 deletions src/quantum/operator/special/measurement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 1018552

Please sign in to comment.