diff options
| author | hachem <im@hachem.wtf> | 2024-09-27 16:26:14 +0200 |
|---|---|---|
| committer | hachem <im@hachem.wtf> | 2024-09-27 16:26:14 +0200 |
| commit | 82e938a96cc6b38ac1a75215cae56f100d1e7bb8 (patch) | |
| tree | e7d1536731e607ac5cf2c7675817d1bd2986764b /libpsi-core/src/runtimes | |
| parent | 1070a7ee073471af8442826cec54e720be266c7c (diff) | |
BasicRT first implementation
Diffstat (limited to 'libpsi-core/src/runtimes')
| -rw-r--r-- | libpsi-core/src/runtimes/basic_rt.rs | 90 |
1 files changed, 88 insertions, 2 deletions
diff --git a/libpsi-core/src/runtimes/basic_rt.rs b/libpsi-core/src/runtimes/basic_rt.rs index 78d6122..ed16205 100644 --- a/libpsi-core/src/runtimes/basic_rt.rs +++ b/libpsi-core/src/runtimes/basic_rt.rs @@ -1,4 +1,7 @@ -use crate::{ClassicalRegister, ExecutationData, QuantumCircuit, Runtime, RuntimeBase}; +use crate::{ + ColumnVector, Complex, ExecutationData, Numeric, QuantumBit, QuantumCircuit, QuantumRegister, + Runtime, RuntimeBase, Vector, +}; pub struct BasicRT { circuit: QuantumCircuit, @@ -10,6 +13,45 @@ impl RuntimeBase for BasicRT { } } +impl BasicRT { + fn calculate_state(state: &ColumnVector<Complex<f64>>, n: usize) -> QuantumBit { + let num_states = 1 << n; + let half_states = num_states >> 1; + + let mut alpha = Complex::zero(); + let mut beta = Complex::zero(); + + for i in 0..num_states { + if i < half_states { + alpha += state[i]; + } else { + beta += state[i]; + } + } + + QuantumBit::new(vec![alpha, beta]) + } + + fn calculate_probabilities(state: &ColumnVector<Complex<f64>>, n: usize) -> (f64, f64) { + let num_states = 1 << n; + let half_states = num_states >> 1; + + let mut state_0 = 0.0; + let mut state_1 = 0.0; + + for i in 0..num_states { + let prob = state[i].norm() * state[i].norm(); + if i < half_states { + state_0 += prob; + } else { + state_1 += prob; + } + } + + (state_0, state_1) + } +} + impl Runtime for BasicRT { fn new(circuit: QuantumCircuit) -> BasicRT { BasicRT { circuit } @@ -18,7 +60,51 @@ impl Runtime for BasicRT { fn execute(&self, repeat: usize) -> Vec<ExecutationData> { let mut result: Vec<ExecutationData> = Vec::with_capacity(repeat); for _ in 0..repeat { - let executation_data = ExecutationData::new(Vec::new(), ClassicalRegister::new(1)); + let mut executation_data = ExecutationData::new( + self.circuit.get_quantum_bits(), + self.circuit.get_classical_registers(), + ); + + for instruction in self.circuit.get_instructions() { + let mut control_bits: Vec<QuantumBit> = Vec::new(); + let mut target_bits: Vec<QuantumBit> = Vec::new(); + let mut quantum_bits: Vec<QuantumBit> = Vec::new(); + + for index in instruction.control_indices.clone() { + control_bits.push(executation_data.quantum_states.clone()[index].clone()); + quantum_bits.push(executation_data.quantum_states.clone()[index].clone()); + } + + for index in instruction.target_indices.clone() { + target_bits.push(executation_data.quantum_states.clone()[index].clone()); + quantum_bits.push(executation_data.quantum_states.clone()[index].clone()); + } + + if control_bits.len() > 0 { + let control_register = QuantumRegister::from(&mut control_bits); + let control_register_state_vector = control_register.get_state(); + let (control_register_state_0, control_register_state_1) = + BasicRT::calculate_probabilities( + &control_register_state_vector, + control_register.get_bits().len(), + ); + + if control_register_state_0 > control_register_state_1 { + continue; + } + } + + let target_register = QuantumRegister::from(&mut quantum_bits); + let target_state_vector = target_register.apply(&instruction.gate); + let target_state = + BasicRT::calculate_state(&target_state_vector, quantum_bits.len()); + executation_data.quantum_states[instruction.target_indices.clone()[0]] = + target_state; + } + + let final_quantum_register = + QuantumRegister::from(&mut executation_data.quantum_states.clone()); + final_quantum_register.measure(&mut executation_data.classical_states); result.push(executation_data); } result |
