diff options
| author | hachem <im@hachem.wtf> | 2024-09-24 21:33:51 +0200 |
|---|---|---|
| committer | hachem <im@hachem.wtf> | 2024-09-24 21:33:51 +0200 |
| commit | c07ab7911bd50d0060841690a863333a9a3f226d (patch) | |
| tree | 5deb12fc8234d553318e4615ae21ddfcc6db4ab4 /libpsi-core/src/core | |
| parent | 26010345eedc716c70e8a4219005db19b266c960 (diff) | |
rename project
Diffstat (limited to 'libpsi-core/src/core')
| -rw-r--r-- | libpsi-core/src/core/component.rs | 141 | ||||
| -rw-r--r-- | libpsi-core/src/core/gates.rs | 22 | ||||
| -rw-r--r-- | libpsi-core/src/core/mod.rs | 4 |
3 files changed, 167 insertions, 0 deletions
diff --git a/libpsi-core/src/core/component.rs b/libpsi-core/src/core/component.rs new file mode 100644 index 0000000..41b7cc7 --- /dev/null +++ b/libpsi-core/src/core/component.rs @@ -0,0 +1,141 @@ +use crate::{complex, ColumnVector, Complex, Matrix, Vector, VectorMatrix}; +use core::{fmt, ops}; + +pub type QuantumBit = ColumnVector<Complex<f64>>; +pub type QuantumGate = Matrix<Complex<f64>>; + +#[macro_export] +macro_rules! count { + () => { 0 }; + ($head:expr $(,$tail:expr)*) => { 1 + count!($( $tail ),*) }; +} + +#[macro_export] +macro_rules! qubit { + ($(($re:expr, $im:expr)),*) => { + { + let mut vector = Vec::new(); + $( + vector.push(complex!($re, $im)); + )* + QuantumBit::new(vector) + } + }; +} + +#[macro_export] +macro_rules! quantum_register { + ($($bit:expr),*) => { + { + const N: usize = count!($($bit),*); + let mut bits: [QuantumBit; N] = [$($bit),*]; + QuantumRegister::from(&mut bits) + } + }; +} + +pub struct ClassicalRegister { + bits: Vec<i32>, +} + +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; + + if alpha_norm > beta_norm { + 0 + } else { + 1 + } + } + + pub fn state_0() -> QuantumBit { + QuantumBit::new(vec![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)]) + } +} + +impl ClassicalRegister { + pub fn new(count: usize) -> ClassicalRegister { + ClassicalRegister { + bits: Vec::with_capacity(count), + } + } + + pub fn set_bits(&mut self, bits: Vec<i32>) { + self.bits = bits; + } +} + +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); + } + + self.state = ColumnVector::from_matrix(&new_result); + } + + pub fn from(bits: &mut [QuantumBit]) -> QuantumRegister { + let mut register = QuantumRegister { + qubits: bits.to_vec(), + state: ColumnVector::new(vec![]), + }; + + register.update(); + register + } + + pub fn measure(&self, classical_register: &mut ClassicalRegister) { + classical_register.set_bits(self.qubits.iter().map(|qubit| qubit.measure()).collect()); + } + + pub fn apply(&mut self, gate: &QuantumGate, index: usize) { + let result: ColumnVector<Complex<f64>> = self.state.mul_matrix(gate).unwrap(); + self.qubits[index] = result; + self.update(); + } +} + +impl ops::Index<usize> for QuantumRegister { + type Output = QuantumBit; + + fn index(&self, index: usize) -> &Self::Output { + &self.qubits[index] + } +} + +impl ops::IndexMut<usize> for QuantumRegister { + 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] + } +} diff --git a/libpsi-core/src/core/gates.rs b/libpsi-core/src/core/gates.rs new file mode 100644 index 0000000..e9077ad --- /dev/null +++ b/libpsi-core/src/core/gates.rs @@ -0,0 +1,22 @@ +use crate::{complex, matrix, QuantumGate}; + +#[rustfmt::skip] +lazy_static::lazy_static! { + pub static ref HADAMARD: QuantumGate = 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 = 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 = 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 = 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 = 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/mod.rs b/libpsi-core/src/core/mod.rs new file mode 100644 index 0000000..374c555 --- /dev/null +++ b/libpsi-core/src/core/mod.rs @@ -0,0 +1,4 @@ +pub mod component; +pub mod gates; + +pub use gates::*; |
