aboutsummaryrefslogtreecommitdiff
path: root/libpsi-core
diff options
context:
space:
mode:
Diffstat (limited to 'libpsi-core')
-rw-r--r--libpsi-core/src/core/circuit.rs25
-rw-r--r--libpsi-core/src/core/component.rs68
-rw-r--r--libpsi-core/src/core/gates.rs41
-rw-r--r--libpsi-core/src/core/runtime.rs19
-rw-r--r--libpsi-core/src/maths/matrix.rs2
-rw-r--r--libpsi-core/src/maths/mod.rs2
-rw-r--r--libpsi-core/src/maths/vector.rs32
-rw-r--r--libpsi-core/src/runtimes/basic_rt.rs31
8 files changed, 101 insertions, 119 deletions
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<usize>,
- 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<QuantumCircuitInstruction>,
+ instructions: Vec<Instruction<'a>>,
}
-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<QuantumCircuitInstruction> {
+ pub fn get_instructions(&self) -> Vec<Instruction> {
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<Complex<f64>>;
+pub type QuantumBit = QuantumState;
+
+#[derive(Clone)]
+pub struct QuantumGate {
+ pub name: &'static str,
+ pub matrix: Matrix<Complex<f64>>,
+}
-pub type QuantumBit = ColumnVector<Complex<f64>>;
-pub type QuantumState = Matrix<Complex<f64>>;
-pub type QuantumGate = (&'static str, QuantumState);
+#[derive(Clone)]
+pub struct ClassicalRegister {
+ bits: Vec<i32>,
+}
+
+#[derive(Clone)]
+pub struct QuantumRegister {
+ state_vector: QuantumState,
+ qubits: Vec<QuantumBit>,
+}
#[macro_export]
macro_rules! count {
@@ -37,35 +51,7 @@ macro_rules! quantum_register {
};
}
-#[derive(Clone)]
-pub struct ClassicalRegister {
- bits: Vec<i32>,
-}
-
-#[derive(Clone)]
-pub struct QuantumRegister {
- state: ColumnVector<Complex<f64>>,
- qubits: Vec<QuantumBit>,
-}
-
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<Complex<f64>> {
- 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<ExecutionData>;
+ fn execute(&self, repeat: usize) -> Vec<RuntimeData>;
+ 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<T: Float + fmt::Display> fmt::Display for Matrix<T> {
.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<T: Float> {
fn max(&self) -> T;
fn min(&self) -> T;
fn sum(&self) -> T;
+
+ fn from_matrix(matrix: &Matrix<T>) -> Self;
}
pub trait VectorMatrix<T: Float> {
- fn from_matrix(matrix: &Matrix<T>) -> Self;
fn to_matrix(&self) -> Matrix<T>;
}
@@ -97,23 +98,19 @@ impl<T: Float> VectorMatrix<T> for RowVector<T> {
fn to_matrix(&self) -> Matrix<T> {
Matrix::new(1, self.size(), self.0.clone())
}
-
- fn from_matrix(matrix: &Matrix<T>) -> Self {
- Self::new(matrix.data.clone())
- }
}
impl<T: Float> VectorMatrix<T> for ColumnVector<T> {
fn to_matrix(&self) -> Matrix<T> {
Matrix::new(self.size(), 1, self.0.clone())
}
+}
+impl<T: Float, const ROWS: usize, const COLS: usize> Vector<T> for VectorImpl<T, ROWS, COLS> {
fn from_matrix(matrix: &Matrix<T>) -> Self {
Self::new(matrix.data.clone())
}
-}
-impl<T: Float, const ROWS: usize, const COLS: usize> Vector<T> for VectorImpl<T, ROWS, COLS> {
fn new(data: Vec<T>) -> Self {
Self(data)
}
@@ -256,25 +253,6 @@ impl<T: Float + fmt::Display> fmt::Display for RowVector<T> {
impl<T: Float + fmt::Display> fmt::Display for ColumnVector<T> {
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<ExecutionData> {
- let mut result: Vec<ExecutionData> = Vec::with_capacity(repeat);
+ fn execute(&self, repeat: usize) -> Vec<RuntimeData> {
+ let mut result: Vec<RuntimeData> = 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
+ }
}