diff options
Diffstat (limited to 'libpsi')
| -rw-r--r-- | libpsi/src/core/component.rs | 91 | ||||
| -rw-r--r-- | libpsi/src/core/gates.rs | 26 | ||||
| -rw-r--r-- | libpsi/src/core/mod.rs | 2 | ||||
| -rw-r--r-- | libpsi/src/lib.rs | 5 | ||||
| -rw-r--r-- | libpsi/src/maths/vector.rs | 3 |
5 files changed, 94 insertions, 33 deletions
diff --git a/libpsi/src/core/component.rs b/libpsi/src/core/component.rs index 51e0551..331021f 100644 --- a/libpsi/src/core/component.rs +++ b/libpsi/src/core/component.rs @@ -1,14 +1,9 @@ -use crate::{ColumnVector, Complex, Matrix, VectorMatrix}; +use crate::{complex, ColumnVector, Complex, Matrix, Vector, VectorMatrix}; use std::ops; pub type QuantumBit = ColumnVector<Complex<f64>>; pub type QuantumGate = Matrix<Complex<f64>>; -pub struct QuantumRegister { - state: ColumnVector<Complex<f64>>, - qubits: Vec<QuantumBit>, -} - #[macro_export] macro_rules! count { () => { 0 }; @@ -39,29 +34,81 @@ macro_rules! quantum_register { }; } +pub struct ClassicalRegister { + bits: Vec<i32>, +} + +pub struct QuantumRegister { + state: ColumnVector<Complex<f64>>, + qubits: Vec<QuantumBit>, +} + impl QuantumBit { - pub fn get_state(&self) -> i32 { - (self[1] != Complex::new(0.0, 0.0)) as i32 + 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 { - pub fn from(bits: &mut [QuantumBit]) -> QuantumRegister { - let matrices: Vec<Matrix<Complex<f64>>> = bits.iter().map(|bit| bit.to_matrix()).collect(); - let mut result = matrices[0].clone(); + 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..] { - result = result.kronecker(matrix); + new_result = new_result.kronecker(matrix); } - QuantumRegister { + self.state = ColumnVector::from_matrix(&new_result); + } + + pub fn from(bits: &mut [QuantumBit]) -> QuantumRegister { + let mut register = QuantumRegister { qubits: bits.to_vec(), - state: ColumnVector::from_matrix(&result), - } + 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(); } } @@ -78,3 +125,17 @@ impl ops::IndexMut<usize> for QuantumRegister { &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/src/core/gates.rs b/libpsi/src/core/gates.rs index 227df9a..e9077ad 100644 --- a/libpsi/src/core/gates.rs +++ b/libpsi/src/core/gates.rs @@ -2,21 +2,21 @@ use crate::{complex, matrix, QuantumGate}; #[rustfmt::skip] lazy_static::lazy_static! { - 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 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); - 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_X: QuantumGate = matrix!([complex!(0.0, 0.0), complex!(1.0, 0.0)]; + [complex!(1.0, 0.0), complex!(0.0, 0.0)]); - 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_Y: QuantumGate = matrix!([complex!(0.0, 0.0), complex!(0.0, -1.0)]; + [complex!(0.0, 1.0), complex!(0.0, 0.0)]); - 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 PAULI_Z: QuantumGate = matrix!([complex!(1.0, 0.0), complex!( 0.0, 0.0)]; + [complex!(0.0, 0.0), complex!(-1.0, 0.0)]); - 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)]); + 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/src/core/mod.rs b/libpsi/src/core/mod.rs index 86ddfaa..374c555 100644 --- a/libpsi/src/core/mod.rs +++ b/libpsi/src/core/mod.rs @@ -1,2 +1,4 @@ pub mod component; pub mod gates; + +pub use gates::*; diff --git a/libpsi/src/lib.rs b/libpsi/src/lib.rs index 1d0d125..af50663 100644 --- a/libpsi/src/lib.rs +++ b/libpsi/src/lib.rs @@ -1,5 +1,5 @@ -mod core; -mod maths; +pub mod core; +pub mod maths; pub use maths::complex::*; pub use maths::matrix::*; @@ -7,3 +7,4 @@ pub use maths::numeric_traits::*; pub use maths::vector::*; pub use core::component::*; +pub use core::gates; diff --git a/libpsi/src/maths/vector.rs b/libpsi/src/maths/vector.rs index a21cf36..07ff7fb 100644 --- a/libpsi/src/maths/vector.rs +++ b/libpsi/src/maths/vector.rs @@ -1,6 +1,3 @@ -// TODO(Hachem): Operators Matrix/Vector don't work -// TODO(Hachem): Refactor - use super::{Float, Matrix}; use core::{fmt, ops}; |
