Browse Source

Display / Measure Many

Adam Kelly 6 years ago
parent
commit
7656d5c8b4
4 changed files with 129 additions and 4 deletions
  1. 32 0
      src/backends/opencl/mod.rs
  2. 46 1
      src/gate.rs
  3. 37 2
      src/lib.rs
  4. 14 1
      src/traits.rs

+ 32 - 0
src/backends/opencl/mod.rs

@@ -4,10 +4,12 @@ use gate::Gate;
 use ocl::{Buffer, MemFlags, ProQue};
 use num_complex::{Complex, Complex32};
 use rand::random;
+use std::fmt;
 
 // OpenCL Kernel
 pub static KERNEL: &'static str = include_str!("kernel.cl");
 
+#[derive(Debug)]
 pub struct OpenCL {
     /// OpenCL Buffer for the state vector
     pub buffer: Buffer<Complex<f32>>,
@@ -138,3 +140,33 @@ impl Backend for OpenCL {
         i as u8
     }
 }
+
+impl fmt::Display for OpenCL {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let mut first = true;
+
+        let mut vec_result = vec![Complex32::new(0.0, 0.0); self.buffer.len()];
+        self.buffer.read(&mut vec_result).enq().unwrap();
+
+        for (idx, item) in vec_result.iter().enumerate() {
+            if !first {
+                write!(f, ", ").unwrap();
+            } else {
+                first = false;
+            }
+
+            write!(f, "[{}]: ", idx).unwrap();
+
+            // Do we print the imaginary part?
+            if item.im == 0.0 {
+                write!(f, "{}", item.re).unwrap();
+            } else if item.re == 0.0 {
+                write!(f, "{}i", item.im).unwrap();
+            } else {
+                write!(f, "{}", item).unwrap();
+            }
+        }
+
+        Ok(())
+    }
+}

+ 46 - 1
src/gate.rs

@@ -2,6 +2,20 @@ use num_complex::Complex32;
 use std::fmt;
 use std::f32::consts::FRAC_1_SQRT_2;
 
+/// Representation of a gate
+///
+/// ```
+///# extern crate qcgpu;
+///# extern crate num_complex;
+///# use qcgpu::Gate;
+///# use num_complex::Complex32;
+/// Gate {
+///    a: Complex32::new(0.0, 0.0), b: Complex32::new(1.0, 0.0),
+///    c: Complex32::new(1.0, 0.0), d: Complex32::new(0.0, 0.0)
+/// };
+///
+///
+#[derive(Debug, Clone, Copy)]
 pub struct Gate {
     pub a: Complex32,
     pub b: Complex32,
@@ -43,4 +57,35 @@ pub fn x() -> Gate {
         c: Complex32::new(1.0, 0.0),
         d: Complex32::new(0.0, 0.0),
     }
-}
+}
+
+
+/// Pauli Y Gate
+///
+/// [0, -i]
+///
+/// [i, 0]
+#[inline]
+pub fn y() -> Gate {
+    Gate {
+        a: Complex32::new(0.0, 0.0),
+        b: Complex32::new(0.0, -1.0),
+        c: Complex32::new(0.0, 1.0),
+        d: Complex32::new(0.0, 0.0),
+    }
+}
+
+/// Pauli Z Gate
+///
+/// [1, 0]
+///
+/// [0, -1]
+#[inline]
+pub fn z() -> Gate {
+    Gate {
+        a: Complex32::new(1.0, 0.0),
+        b: Complex32::new(0.0, 0.0),
+        c: Complex32::new(0.0, 0.0),
+        d: Complex32::new(-1.0, 0.0),
+    }
+}

+ 37 - 2
src/lib.rs

@@ -7,23 +7,48 @@ pub mod traits;
 pub mod backends;
 
 use backends::OpenCL;
-use gate::{h, x};
+use gate::{Gate, h, x, y, z};
 
+use std::fmt;
+use std::collections::HashMap;
+
+#[derive(Debug)]
 pub struct Simulator {
     backend: Box<traits::Backend>,
+    num_qubits: u8,
 }
 
 impl Simulator {
     pub fn new_opencl(num_qubits: u8) -> Simulator {
         Simulator {
-            backend: Box::new(OpenCL::new(num_qubits))
+            backend: Box::new(OpenCL::new(num_qubits)),
+            num_qubits
+        }
+    }
+
+    pub fn apply_gate(&mut self, gate: Gate, target: u8) {
+        self.backend.apply_gate(gate, target);
+    }
+
+    pub fn apply_all(&mut self, gate: Gate) {
+        for i in 0..self.num_qubits { 
+            self.backend.apply_gate(gate, i);
         }
     }
 
+
     pub fn x(&mut self, target: u8) {
         self.backend.apply_gate(x(), target);
     }
 
+    pub fn y(&mut self, target: u8) {
+        self.backend.apply_gate(y(), target);
+    }
+    
+    pub fn z(&mut self, target: u8) {
+        self.backend.apply_gate(z(), target);
+    }
+
     pub fn h(&mut self, target: u8) {
         self.backend.apply_gate(h(), target);
     }
@@ -35,4 +60,14 @@ impl Simulator {
     pub fn measure(&self) -> u8 {
         self.backend.measure()
     }
+
+    pub fn measure_many(&self, iters: u32) -> HashMap<u8, u32> {
+        self.backend.measure_many(iters)
+    }
+}
+
+impl fmt::Display for Simulator {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "{}", self.backend)
+    }
 }

+ 14 - 1
src/traits.rs

@@ -1,7 +1,20 @@
 use gate::Gate;
+use std::fmt::{Debug, Display};
+use std::collections::HashMap;
 
-pub trait Backend {
+pub trait Backend: Debug + Display {
     fn apply_gate(&mut self, gate: Gate, target: u8);
     fn apply_controlled_gate(&mut self, gate: Gate, control: u8, target: u8);
     fn measure(&self) -> u8;
+    fn measure_many(&self, iters: u32) -> HashMap<u8, u32> {
+        let mut results = HashMap::new();
+
+        for _ in 0..iters {
+            let state = self.measure();
+            let count = results.entry(state).or_insert(0);
+            *count += 1;
+        }
+
+        results
+    }
 }