diff options
| -rw-r--r-- | libpsi-core/src/core/circuit.rs | 40 | ||||
| -rw-r--r-- | libpsi-core/src/core/classical_components.rs | 63 | ||||
| -rw-r--r-- | libpsi-core/src/core/gates.rs | 10 | ||||
| -rw-r--r-- | libpsi-core/src/core/mod.rs | 8 | ||||
| -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.rs | 22 | ||||
| -rw-r--r-- | libpsi-core/src/lib.rs | 7 | ||||
| -rw-r--r-- | libpsi-core/src/runtimes/basic_rt.rs | 39 | ||||
| -rw-r--r-- | libpsi-core/src/runtimes/mod.rs | 3 | ||||
| -rw-r--r-- | tester/src/main.rs | 18 |
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); } |
