aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libpsi-core/src/core/circuit.rs40
-rw-r--r--libpsi-core/src/core/classical_components.rs63
-rw-r--r--libpsi-core/src/core/gates.rs10
-rw-r--r--libpsi-core/src/core/mod.rs8
-rw-r--r--libpsi-core/src/core/quantum_components.rs (renamed from libpsi-core/src/core/component.rs)130
-rw-r--r--libpsi-core/src/core/runtime.rs22
-rw-r--r--libpsi-core/src/lib.rs7
-rw-r--r--libpsi-core/src/runtimes/basic_rt.rs39
-rw-r--r--libpsi-core/src/runtimes/mod.rs3
-rw-r--r--tester/src/main.rs18
10 files changed, 157 insertions, 183 deletions
diff --git a/libpsi-core/src/core/circuit.rs b/libpsi-core/src/core/circuit.rs
index 4d9d286..27c106d 100644
--- a/libpsi-core/src/core/circuit.rs
+++ b/libpsi-core/src/core/circuit.rs
@@ -1,39 +1,19 @@
-use super::{ClassicalRegister, QuantumGate, QuantumRegister};
-
-#[derive(Clone)]
-pub enum Instruction<'a> {
- ApplyGate(&'a QuantumGate, &'a [usize], usize),
- Measure(usize),
-}
+use super::{ClassicalRegister, QuantumRegister};
+#[allow(unused)]
pub struct QuantumCircuit<'a> {
- quantum_register: QuantumRegister,
- classical_register: ClassicalRegister,
- instructions: Vec<Instruction<'a>>,
+ quantum_registers: &'a [QuantumRegister<'a>],
+ classical_registers: &'a [ClassicalRegister<'a>],
}
impl<'a> QuantumCircuit<'a> {
- pub fn new(quantum_bit_count: usize, classical_bit_count: usize) -> QuantumCircuit<'a> {
+ pub fn new(
+ quantum_registers: &'a [QuantumRegister<'a>],
+ classical_registers: &'a [ClassicalRegister<'a>],
+ ) -> QuantumCircuit<'a> {
QuantumCircuit {
- quantum_register: QuantumRegister::new(quantum_bit_count),
- classical_register: ClassicalRegister::new(classical_bit_count),
- instructions: Vec::new(),
+ quantum_registers,
+ classical_registers,
}
}
-
- pub fn execute(&mut self, instruction: Instruction<'a>) {
- self.instructions.push(instruction);
- }
-
- pub fn get_quantum_register(&self) -> QuantumRegister {
- self.quantum_register.clone()
- }
-
- pub fn get_classical_registers(&self) -> ClassicalRegister {
- self.classical_register.clone()
- }
-
- pub fn get_instructions(&self) -> Vec<Instruction> {
- self.instructions.clone()
- }
}
diff --git a/libpsi-core/src/core/classical_components.rs b/libpsi-core/src/core/classical_components.rs
new file mode 100644
index 0000000..6710e9d
--- /dev/null
+++ b/libpsi-core/src/core/classical_components.rs
@@ -0,0 +1,63 @@
+use core::ops;
+
+#[derive(Clone, Copy)]
+pub struct ClassicalBit<'a> {
+ state: bool,
+ name: &'a str,
+}
+
+#[derive(Clone)]
+pub struct ClassicalRegister<'a> {
+ bits: Vec<ClassicalBit<'a>>,
+ name: &'a str,
+}
+
+impl<'a> ClassicalBit<'a> {
+ pub fn new(name: &'a str, state: bool) -> ClassicalBit {
+ ClassicalBit { name, state }
+ }
+
+ pub fn get_name(&self) -> &'a str {
+ self.name
+ }
+
+ pub fn get_state(&self) -> bool {
+ self.state
+ }
+}
+
+impl<'a> ClassicalRegister<'a> {
+ pub fn new(name: &'a str, names: &'a [&'a str]) -> ClassicalRegister<'a> {
+ let mut bits: Vec<ClassicalBit<'a>> = Vec::new();
+ for i in 0..names.len() {
+ bits.push(ClassicalBit::new(names[i], false));
+ }
+ ClassicalRegister { name, bits }
+ }
+
+ pub fn set_bits(&mut self, bits: Vec<ClassicalBit<'a>>) {
+ self.bits = bits;
+ }
+
+ pub fn get_bits(&self) -> Vec<ClassicalBit<'a>> {
+ self.bits.clone()
+ }
+
+ pub fn get_name(&self) -> &'a str {
+ self.name
+ }
+}
+
+impl<'a> ops::Index<usize> for ClassicalRegister<'a> {
+ type Output = ClassicalBit<'a>;
+
+ fn index(&self, index: usize) -> &Self::Output {
+ &self.bits[index]
+ }
+}
+
+impl<'a> ops::IndexMut<usize> for ClassicalRegister<'a> {
+ fn index_mut(&mut self, index: usize) -> &mut Self::Output {
+ &mut self.bits[index]
+ }
+}
diff --git a/libpsi-core/src/core/gates.rs b/libpsi-core/src/core/gates.rs
index 97254fc..854313d 100644
--- a/libpsi-core/src/core/gates.rs
+++ b/libpsi-core/src/core/gates.rs
@@ -2,32 +2,32 @@ use crate::{complex, matrix, QuantumGate};
#[rustfmt::skip]
lazy_static::lazy_static! {
- pub static ref HADAMARD: QuantumGate = QuantumGate {
+ pub static ref HADAMARD: QuantumGate<'static> = QuantumGate {
name: "H",
matrix: matrix!([complex!(1.0, 0.0), complex!( 1.0, 0.0)];
[complex!(1.0, 0.0), complex!(-1.0, 0.0)]) *
complex!(1.0/2.0_f64.sqrt(), 0.0)
};
- pub static ref PAULI_X: QuantumGate = QuantumGate {
+ pub static ref PAULI_X: QuantumGate<'static> = QuantumGate {
name: "Pauli-X",
matrix: matrix!([complex!(0.0, 0.0), complex!(1.0, 0.0)];
[complex!(1.0, 0.0), complex!(0.0, 0.0)])
};
- pub static ref PAULI_Y: QuantumGate = QuantumGate {
+ pub static ref PAULI_Y: QuantumGate<'static> = QuantumGate {
name: "Pauli-Y",
matrix: matrix!([complex!(0.0, 0.0), complex!(0.0, -1.0)];
[complex!(0.0, 1.0), complex!(0.0, 0.0)])
};
- pub static ref PAULI_Z: QuantumGate = QuantumGate {
+ pub static ref PAULI_Z: QuantumGate<'static> = QuantumGate {
name: "Pauli-Z",
matrix: matrix!([complex!(1.0, 0.0), complex!( 0.0, 0.0)];
[complex!(0.0, 0.0), complex!(-1.0, 0.0)])
};
- pub static ref CNOT: QuantumGate = QuantumGate {
+ pub static ref CNOT: QuantumGate<'static> = QuantumGate {
name: "CNOT",
matrix: matrix!([complex!(1.0, 0.0), complex!(0.0, 0.0), complex!(0.0, 0.0), complex!(0.0, 0.0)];
[complex!(0.0, 0.0), complex!(1.0, 0.0), complex!(0.0, 0.0), complex!(0.0, 0.0)];
diff --git a/libpsi-core/src/core/mod.rs b/libpsi-core/src/core/mod.rs
index e8e2a4b..6936487 100644
--- a/libpsi-core/src/core/mod.rs
+++ b/libpsi-core/src/core/mod.rs
@@ -1,9 +1,9 @@
pub mod circuit;
-pub mod component;
+pub mod classical_components;
pub mod gates;
-pub mod runtime;
+pub mod quantum_components;
pub use circuit::*;
-pub use component::*;
+pub use classical_components::*;
pub use gates::*;
-pub use runtime::*;
+pub use quantum_components::*;
diff --git a/libpsi-core/src/core/component.rs b/libpsi-core/src/core/quantum_components.rs
index 7748ac5..e6931a0 100644
--- a/libpsi-core/src/core/component.rs
+++ b/libpsi-core/src/core/quantum_components.rs
@@ -1,26 +1,7 @@
-use crate::{complex, ColumnVector, Complex, Matrix, Vector, VectorMatrix};
+use crate::{column_vector, complex, ColumnVector, Complex, Matrix, Vector, VectorMatrix};
use core::{fmt, ops};
-pub type QuantumState = ColumnVector<Complex<f64>>;
-pub type QuantumBit = QuantumState;
-
-#[derive(Clone)]
-pub struct QuantumGate {
- pub name: &'static str,
- pub matrix: Matrix<Complex<f64>>,
-}
-
-#[derive(Clone)]
-pub struct ClassicalRegister {
- bits: Vec<i32>,
-}
-
-#[derive(Clone)]
-pub struct QuantumRegister {
- state_vector: QuantumState,
- qubits: Vec<QuantumBit>,
-}
-
+// TODO(Hachem): Redo these macros to work with the new function definition.
#[macro_export]
macro_rules! count {
() => { 0 };
@@ -51,56 +32,63 @@ macro_rules! quantum_register {
};
}
-impl QuantumBit {
- pub fn state_0() -> QuantumBit {
- QuantumBit::new(vec![complex!(1.0, 0.0), complex!(0.0, 0.0)])
+pub type QuantumState = ColumnVector<Complex<f64>>;
+impl QuantumState {
+ pub fn state_0() -> QuantumState {
+ column_vector![complex!(1.0, 0.0), complex!(0.0, 0.0)]
}
- pub fn state_1() -> QuantumBit {
- QuantumBit::new(vec![complex!(0.0, 0.0), complex!(1.0, 0.0)])
+ pub fn state_1() -> QuantumState {
+ column_vector![complex!(0.0, 0.0), complex!(1.0, 0.0)]
}
}
-impl fmt::Display for QuantumGate {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- write!(f, "{}", self.name)
- }
+#[derive(Clone)]
+pub struct QuantumBit<'a> {
+ state: QuantumState,
+ name: &'a str,
}
-impl ClassicalRegister {
- pub fn new(count: usize) -> ClassicalRegister {
- ClassicalRegister {
- bits: Vec::with_capacity(count),
- }
+#[derive(Clone)]
+pub struct QuantumRegister<'a> {
+ state_vector: QuantumState,
+ name: &'a str,
+ qubits: Vec<QuantumBit<'a>>,
+}
+
+#[derive(Clone)]
+pub struct QuantumGate<'a> {
+ pub name: &'a str,
+ pub matrix: Matrix<Complex<f64>>,
+}
+
+impl<'a> QuantumBit<'a> {
+ pub fn new(name: &'a str, state: QuantumState) -> QuantumBit<'a> {
+ QuantumBit { name, state }
}
- pub fn set_bits(&mut self, bits: Vec<i32>) {
- self.bits = bits;
+ pub fn get_state(&self) -> QuantumState {
+ self.state.clone()
}
- pub fn get_bits(&self) -> Vec<i32> {
- self.bits.clone()
+ pub fn get_name(&self) -> &'a str {
+ self.name
}
}
-impl QuantumRegister {
- fn update(&mut self) {
- let matrices: Vec<Matrix<Complex<f64>>> =
- self.qubits.iter().map(|qubit| qubit.to_matrix()).collect();
- let mut new_result = matrices[0].clone();
- for matrix in &matrices[1..] {
- new_result = new_result.kronecker(matrix);
+impl<'a> QuantumRegister<'a> {
+ pub fn new(name: &'a str, names: &[&'a str]) -> QuantumRegister<'a> {
+ let mut bits: Vec<QuantumBit<'a>> = Vec::new();
+ for i in 0..names.len() {
+ bits.push(QuantumBit::new(names[i], QuantumState::state_0()))
}
- self.state_vector = ColumnVector::from_matrix(&new_result);
- }
-
- pub fn new(count: usize) -> QuantumRegister {
- QuantumRegister::from(&mut vec![QuantumBit::state_0(); count])
+ QuantumRegister::from(name, &mut bits)
}
- pub fn from(bits: &mut [QuantumBit]) -> QuantumRegister {
+ pub fn from(name: &'a str, bits: &mut [QuantumBit<'a>]) -> QuantumRegister<'a> {
let mut register = QuantumRegister {
+ name,
qubits: bits.to_vec(),
state_vector: ColumnVector::new(vec![]),
};
@@ -109,6 +97,20 @@ impl QuantumRegister {
register
}
+ fn update(&mut self) {
+ let matrices: Vec<Matrix<Complex<f64>>> = self
+ .qubits
+ .iter()
+ .map(|qubit| qubit.state.to_matrix())
+ .collect();
+ let mut new_result = matrices[0].clone();
+ for matrix in &matrices[1..] {
+ new_result = new_result.kronecker(matrix);
+ }
+
+ self.state_vector = ColumnVector::from_matrix(&new_result);
+ }
+
pub fn get_bits(&self) -> Vec<QuantumBit> {
self.qubits.clone()
}
@@ -116,32 +118,28 @@ impl QuantumRegister {
pub fn get_state(&self) -> QuantumState {
self.state_vector.clone()
}
+
+ pub fn get_name(&self) -> &'a str {
+ self.name
+ }
}
-impl ops::Index<usize> for QuantumRegister {
- type Output = QuantumBit;
+impl<'a> ops::Index<usize> for QuantumRegister<'a> {
+ type Output = QuantumBit<'a>;
fn index(&self, index: usize) -> &Self::Output {
&self.qubits[index]
}
}
-impl ops::IndexMut<usize> for QuantumRegister {
+impl<'a> ops::IndexMut<usize> for QuantumRegister<'a> {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
&mut self.qubits[index]
}
}
-impl ops::Index<usize> for ClassicalRegister {
- type Output = i32;
-
- fn index(&self, index: usize) -> &Self::Output {
- &self.bits[index]
- }
-}
-
-impl ops::IndexMut<usize> for ClassicalRegister {
- fn index_mut(&mut self, index: usize) -> &mut Self::Output {
- &mut self.bits[index]
+impl<'a> fmt::Display for QuantumGate<'a> {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "{}", self.name)
}
}
diff --git a/libpsi-core/src/core/runtime.rs b/libpsi-core/src/core/runtime.rs
deleted file mode 100644
index f3e52ac..0000000
--- a/libpsi-core/src/core/runtime.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-use super::{ClassicalRegister, QuantumCircuit, QuantumRegister, QuantumState};
-
-pub struct RuntimeData {
- pub quantum_register: QuantumRegister,
- pub classical_states: ClassicalRegister,
-}
-
-impl RuntimeData {
- pub fn new(quantum_register: QuantumRegister, classical_states: ClassicalRegister) -> Self {
- RuntimeData {
- quantum_register,
- classical_states,
- }
- }
-}
-
-pub trait Runtime<'a> {
- fn new(circuit: &'a QuantumCircuit) -> Self;
- fn execute(&self, repeat: usize) -> Vec<RuntimeData>;
- fn get_state(&self) -> QuantumState;
- fn get_circuit(&self) -> &QuantumCircuit;
-}
diff --git a/libpsi-core/src/lib.rs b/libpsi-core/src/lib.rs
index 91b853e..81c9fe2 100644
--- a/libpsi-core/src/lib.rs
+++ b/libpsi-core/src/lib.rs
@@ -1,6 +1,5 @@
pub mod core;
pub mod maths;
-pub mod runtimes;
pub use maths::complex::*;
pub use maths::matrix::*;
@@ -8,8 +7,6 @@ pub use maths::numeric::*;
pub use maths::vector::*;
pub use core::circuit::*;
-pub use core::component::*;
+pub use core::classical_components::*;
pub use core::gates;
-pub use core::runtime::*;
-
-pub use runtimes::*;
+pub use core::quantum_components::*;
diff --git a/libpsi-core/src/runtimes/basic_rt.rs b/libpsi-core/src/runtimes/basic_rt.rs
deleted file mode 100644
index b8c412f..0000000
--- a/libpsi-core/src/runtimes/basic_rt.rs
+++ /dev/null
@@ -1,39 +0,0 @@
-use crate::{Instruction, QuantumCircuit, QuantumState, Runtime, RuntimeData};
-
-pub struct BasicRT<'a> {
- circuit: &'a QuantumCircuit<'a>,
-}
-
-impl<'a> Runtime<'a> for BasicRT<'a> {
- fn new(circuit: &'a QuantumCircuit) -> BasicRT<'a> {
- BasicRT { circuit }
- }
-
- fn execute(&self, repeat: usize) -> Vec<RuntimeData> {
- let mut result: Vec<RuntimeData> = Vec::with_capacity(repeat);
- for _ in 0..repeat {
- let executation_data = RuntimeData::new(
- self.circuit.get_quantum_register(),
- self.circuit.get_classical_registers(),
- );
-
- for instruction in self.circuit.get_instructions() {
- match instruction {
- Instruction::ApplyGate(_gate, _control_bits, _target) => print!(""),
- Instruction::Measure(_bit) => print!(""),
- }
- }
-
- result.push(executation_data);
- }
- result
- }
-
- fn get_state(&self) -> QuantumState {
- todo!()
- }
-
- fn get_circuit(&self) -> &QuantumCircuit {
- &self.circuit
- }
-}
diff --git a/libpsi-core/src/runtimes/mod.rs b/libpsi-core/src/runtimes/mod.rs
deleted file mode 100644
index 4c2030c..0000000
--- a/libpsi-core/src/runtimes/mod.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-pub mod basic_rt;
-
-pub use basic_rt::*;
diff --git a/tester/src/main.rs b/tester/src/main.rs
index 3840c23..2c2e72c 100644
--- a/tester/src/main.rs
+++ b/tester/src/main.rs
@@ -1,15 +1,15 @@
use libpsi_core::*;
-use libpsi_visualizer::*;
fn main() {
- let mut circuit = QuantumCircuit::new(2, 2);
- circuit.execute(Instruction::ApplyGate(&gates::HADAMARD, &[], 0));
- circuit.execute(Instruction::ApplyGate(&gates::CNOT, &[0], 1));
- circuit.execute(Instruction::ApplyGate(&gates::HADAMARD, &[], 0));
+ let quantum_registers = [
+ QuantumRegister::new("qr0", &["q0", "q1", "q2", "q3"]),
+ QuantumRegister::new("qr1", &["k0", "k1", "k2", "k3"]),
+ ];
- circuit.execute(Instruction::Measure(0));
- circuit.execute(Instruction::Measure(1));
+ let classical_registers = [
+ ClassicalRegister::new("cr0", &["c0", "c1", "c2", "c3"]),
+ ClassicalRegister::new("cr1", &["a0", "a1", "a2", "a3"]),
+ ];
- HorizontalCLIVisualizer::new(&circuit).render();
- BasicRT::new(&circuit).execute(1024);
+ QuantumCircuit::new(&quantum_registers, &classical_registers);
}