From 7cc3c78a24b51a58d44e1baff20b86292662390e Mon Sep 17 00:00:00 2001 From: hachem Date: Sun, 13 Oct 2024 15:13:17 +0200 Subject: Mass refactor --- libpsi-core/src/core/circuit.rs | 25 ++++++------- libpsi-core/src/core/component.rs | 68 ++++++++++++++++-------------------- libpsi-core/src/core/gates.rs | 41 +++++++++++++++------- libpsi-core/src/core/runtime.rs | 19 +++++----- libpsi-core/src/maths/matrix.rs | 2 +- libpsi-core/src/maths/mod.rs | 2 +- libpsi-core/src/maths/vector.rs | 32 +++-------------- libpsi-core/src/runtimes/basic_rt.rs | 31 +++++++++------- 8 files changed, 101 insertions(+), 119 deletions(-) (limited to 'libpsi-core') diff --git a/libpsi-core/src/core/circuit.rs b/libpsi-core/src/core/circuit.rs index 635066a..4d9d286 100644 --- a/libpsi-core/src/core/circuit.rs +++ b/libpsi-core/src/core/circuit.rs @@ -1,20 +1,19 @@ use super::{ClassicalRegister, QuantumGate, QuantumRegister}; #[derive(Clone)] -pub struct QuantumCircuitInstruction { - pub target_bit: usize, - pub control_indices: Vec, - pub gate: QuantumGate, +pub enum Instruction<'a> { + ApplyGate(&'a QuantumGate, &'a [usize], usize), + Measure(usize), } -pub struct QuantumCircuit { +pub struct QuantumCircuit<'a> { quantum_register: QuantumRegister, classical_register: ClassicalRegister, - instructions: Vec, + instructions: Vec>, } -impl QuantumCircuit { - pub fn new(quantum_bit_count: usize, classical_bit_count: usize) -> QuantumCircuit { +impl<'a> QuantumCircuit<'a> { + pub fn new(quantum_bit_count: usize, classical_bit_count: usize) -> QuantumCircuit<'a> { QuantumCircuit { quantum_register: QuantumRegister::new(quantum_bit_count), classical_register: ClassicalRegister::new(classical_bit_count), @@ -22,12 +21,8 @@ impl QuantumCircuit { } } - pub fn apply(&mut self, gate: &QuantumGate, control_bits: &[usize], target_bit: usize) { - self.instructions.push(QuantumCircuitInstruction { - gate: gate.clone(), - target_bit, - control_indices: control_bits.to_vec(), - }); + pub fn execute(&mut self, instruction: Instruction<'a>) { + self.instructions.push(instruction); } pub fn get_quantum_register(&self) -> QuantumRegister { @@ -38,7 +33,7 @@ impl QuantumCircuit { self.classical_register.clone() } - pub fn get_instructions(&self) -> Vec { + pub fn get_instructions(&self) -> Vec { self.instructions.clone() } } diff --git a/libpsi-core/src/core/component.rs b/libpsi-core/src/core/component.rs index d2dc781..7748ac5 100644 --- a/libpsi-core/src/core/component.rs +++ b/libpsi-core/src/core/component.rs @@ -1,11 +1,25 @@ -use rand::Rng; - use crate::{complex, ColumnVector, Complex, Matrix, Vector, VectorMatrix}; -use core::ops; +use core::{fmt, ops}; + +pub type QuantumState = ColumnVector>; +pub type QuantumBit = QuantumState; + +#[derive(Clone)] +pub struct QuantumGate { + pub name: &'static str, + pub matrix: Matrix>, +} -pub type QuantumBit = ColumnVector>; -pub type QuantumState = Matrix>; -pub type QuantumGate = (&'static str, QuantumState); +#[derive(Clone)] +pub struct ClassicalRegister { + bits: Vec, +} + +#[derive(Clone)] +pub struct QuantumRegister { + state_vector: QuantumState, + qubits: Vec, +} #[macro_export] macro_rules! count { @@ -37,35 +51,7 @@ macro_rules! quantum_register { }; } -#[derive(Clone)] -pub struct ClassicalRegister { - bits: Vec, -} - -#[derive(Clone)] -pub struct QuantumRegister { - state: ColumnVector>, - qubits: Vec, -} - impl QuantumBit { - pub fn measure(&self) -> i32 { - let alpha_abs = self[0].abs(); - let beta_abs = self[1].abs(); - - let alpha_norm = alpha_abs * alpha_abs; - let beta_norm = beta_abs * beta_abs; - - let mut rng = rand::thread_rng(); - let random_value = rng.gen_range(0.0..(alpha_norm as f32 + beta_norm as f32)); - - if random_value < alpha_norm as f32 { - 0 - } else { - 1 - } - } - pub fn state_0() -> QuantumBit { QuantumBit::new(vec![complex!(1.0, 0.0), complex!(0.0, 0.0)]) } @@ -75,6 +61,12 @@ impl QuantumBit { } } +impl fmt::Display for QuantumGate { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.name) + } +} + impl ClassicalRegister { pub fn new(count: usize) -> ClassicalRegister { ClassicalRegister { @@ -100,7 +92,7 @@ impl QuantumRegister { new_result = new_result.kronecker(matrix); } - self.state = ColumnVector::from_matrix(&new_result); + self.state_vector = ColumnVector::from_matrix(&new_result); } pub fn new(count: usize) -> QuantumRegister { @@ -110,7 +102,7 @@ impl QuantumRegister { pub fn from(bits: &mut [QuantumBit]) -> QuantumRegister { let mut register = QuantumRegister { qubits: bits.to_vec(), - state: ColumnVector::new(vec![]), + state_vector: ColumnVector::new(vec![]), }; register.update(); @@ -121,8 +113,8 @@ impl QuantumRegister { self.qubits.clone() } - pub fn get_state(&self) -> ColumnVector> { - self.state.clone() + pub fn get_state(&self) -> QuantumState { + self.state_vector.clone() } } diff --git a/libpsi-core/src/core/gates.rs b/libpsi-core/src/core/gates.rs index 094fec9..97254fc 100644 --- a/libpsi-core/src/core/gates.rs +++ b/libpsi-core/src/core/gates.rs @@ -2,21 +2,36 @@ use crate::{complex, matrix, QuantumGate}; #[rustfmt::skip] lazy_static::lazy_static! { - pub static ref HADAMARD: QuantumGate = ("H", 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 HADAMARD: QuantumGate = 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 = ("Pauli-X", 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_X: QuantumGate = 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 = ("Pauli-Y", 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_Y: QuantumGate = 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 = ("Pauli-Z", matrix!([complex!(1.0, 0.0), complex!( 0.0, 0.0)]; - [complex!(0.0, 0.0), complex!(-1.0, 0.0)])); + pub static ref PAULI_Z: QuantumGate = 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 = ("CNOT", 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)]; - [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), complex!(1.0, 0.0), complex!(0.0, 0.0)])); + pub static ref CNOT: QuantumGate = 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)]; + [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), complex!(1.0, 0.0), complex!(0.0, 0.0)]) + }; } diff --git a/libpsi-core/src/core/runtime.rs b/libpsi-core/src/core/runtime.rs index 19ac191..f3e52ac 100644 --- a/libpsi-core/src/core/runtime.rs +++ b/libpsi-core/src/core/runtime.rs @@ -1,25 +1,22 @@ -use super::{ClassicalRegister, QuantumCircuit, QuantumRegister}; +use super::{ClassicalRegister, QuantumCircuit, QuantumRegister, QuantumState}; -#[allow(unused)] -pub struct ExecutionData { +pub struct RuntimeData { pub quantum_register: QuantumRegister, pub classical_states: ClassicalRegister, } -impl ExecutionData { +impl RuntimeData { pub fn new(quantum_register: QuantumRegister, classical_states: ClassicalRegister) -> Self { - ExecutionData { + RuntimeData { quantum_register, classical_states, } } } -pub trait RuntimeBase { - fn get_circuit(&self) -> &QuantumCircuit; -} - -pub trait Runtime<'a, T: RuntimeBase = Self> { +pub trait Runtime<'a> { fn new(circuit: &'a QuantumCircuit) -> Self; - fn execute(&self, repeat: usize) -> Vec; + fn execute(&self, repeat: usize) -> Vec; + fn get_state(&self) -> QuantumState; + fn get_circuit(&self) -> &QuantumCircuit; } diff --git a/libpsi-core/src/maths/matrix.rs b/libpsi-core/src/maths/matrix.rs index c374a11..58492f9 100644 --- a/libpsi-core/src/maths/matrix.rs +++ b/libpsi-core/src/maths/matrix.rs @@ -230,7 +230,7 @@ impl fmt::Display for Matrix { .data .iter() .map(|element| { - let element_string = format!("{}", element); + let element_string = element.to_string(); if is_complex { let element_string = element_string.trim_end_matches('i').trim(); diff --git a/libpsi-core/src/maths/mod.rs b/libpsi-core/src/maths/mod.rs index 22fb558..5bc7f6d 100644 --- a/libpsi-core/src/maths/mod.rs +++ b/libpsi-core/src/maths/mod.rs @@ -1,10 +1,10 @@ pub mod complex; pub mod matrix; pub mod numeric; - pub mod vector; pub mod vector_ops; pub use complex::*; pub use matrix::*; pub use numeric::*; +pub use vector::*; diff --git a/libpsi-core/src/maths/vector.rs b/libpsi-core/src/maths/vector.rs index cb25ecd..87b5353 100644 --- a/libpsi-core/src/maths/vector.rs +++ b/libpsi-core/src/maths/vector.rs @@ -33,10 +33,11 @@ pub trait Vector { fn max(&self) -> T; fn min(&self) -> T; fn sum(&self) -> T; + + fn from_matrix(matrix: &Matrix) -> Self; } pub trait VectorMatrix { - fn from_matrix(matrix: &Matrix) -> Self; fn to_matrix(&self) -> Matrix; } @@ -97,23 +98,19 @@ impl VectorMatrix for RowVector { fn to_matrix(&self) -> Matrix { Matrix::new(1, self.size(), self.0.clone()) } - - fn from_matrix(matrix: &Matrix) -> Self { - Self::new(matrix.data.clone()) - } } impl VectorMatrix for ColumnVector { fn to_matrix(&self) -> Matrix { Matrix::new(self.size(), 1, self.0.clone()) } +} +impl Vector for VectorImpl { fn from_matrix(matrix: &Matrix) -> Self { Self::new(matrix.data.clone()) } -} -impl Vector for VectorImpl { fn new(data: Vec) -> Self { Self(data) } @@ -256,25 +253,6 @@ impl fmt::Display for RowVector { impl fmt::Display for ColumnVector { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let max_width = self - .0 - .iter() - .map(|x| format!("{:.2}", x).split('.').next().unwrap().len()) - .max() - .unwrap_or(0); - - for (i, x) in self.0.iter().enumerate() { - let formatted_x = format!("{:>width$.2}", x, width = max_width + 3); - - if i == 0 { - write!(f, "┌{}┐\n", formatted_x)?; - } else if i == self.0.len() - 1 { - write!(f, "└{}┘\n", formatted_x)?; - } else { - write!(f, "│{}│\n", formatted_x)?; - } - } - - Ok(()) + write!(f, "{}", self.to_matrix()) } } diff --git a/libpsi-core/src/runtimes/basic_rt.rs b/libpsi-core/src/runtimes/basic_rt.rs index 20befba..b8c412f 100644 --- a/libpsi-core/src/runtimes/basic_rt.rs +++ b/libpsi-core/src/runtimes/basic_rt.rs @@ -1,34 +1,39 @@ -use crate::{ExecutionData, QuantumCircuit, Runtime, RuntimeBase}; +use crate::{Instruction, QuantumCircuit, QuantumState, Runtime, RuntimeData}; pub struct BasicRT<'a> { - circuit: &'a QuantumCircuit, -} - -impl<'a> RuntimeBase for BasicRT<'a> { - fn get_circuit(&self) -> &QuantumCircuit { - &self.circuit - } + circuit: &'a QuantumCircuit<'a>, } impl<'a> Runtime<'a> for BasicRT<'a> { - fn new(circuit: &'a QuantumCircuit) -> BasicRT { + fn new(circuit: &'a QuantumCircuit) -> BasicRT<'a> { BasicRT { circuit } } - fn execute(&self, repeat: usize) -> Vec { - let mut result: Vec = Vec::with_capacity(repeat); + fn execute(&self, repeat: usize) -> Vec { + let mut result: Vec = Vec::with_capacity(repeat); for _ in 0..repeat { - let executation_data = ExecutionData::new( + let executation_data = RuntimeData::new( self.circuit.get_quantum_register(), self.circuit.get_classical_registers(), ); for instruction in self.circuit.get_instructions() { - println!("{} on q{}", instruction.gate.0, instruction.target_bit); + 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 + } } -- cgit v1.3