use scirs2_core::random::ChaCha8Rng;
use scirs2_core::random::{Rng, SeedableRng};
use scirs2_core::Complex64;
use std::f64::consts::FRAC_1_SQRT_2;
use quantrs2_circuit::builder::{Circuit, Simulator};
use quantrs2_core::{qubit::QubitId, register::Register};
use crate::benchmark::generate_benchmark_circuit;
use crate::optimized_simulator::OptimizedSimulator;
use crate::optimized_simulator_chunked::OptimizedSimulatorChunked;
use crate::optimized_simulator_simple::OptimizedSimulatorSimple;
use crate::statevector::StateVectorSimulator;
#[test]
fn test_bell_state_all_simulators() {
let mut circuit = Circuit::<2>::new();
circuit
.h(QubitId::new(0))
.expect("Failed to apply Hadamard gate")
.cnot(QubitId::new(0), QubitId::new(1))
.expect("Failed to apply CNOT gate");
let standard_sim = StateVectorSimulator::new();
let standard_result = standard_sim
.run(&circuit)
.expect("Standard simulator failed");
let simple_opt_sim = OptimizedSimulatorSimple::new();
let simple_opt_result = simple_opt_sim
.run(&circuit)
.expect("Simple optimized simulator failed");
let chunked_sim = OptimizedSimulatorChunked::new();
let chunked_opt_result = chunked_sim.run(&circuit).expect("Chunked simulator failed");
let full_opt_sim = OptimizedSimulator::new();
let full_opt_result = full_opt_sim
.run(&circuit)
.expect("Full optimized simulator failed");
let expected_amplitudes = vec![
Complex64::new(FRAC_1_SQRT_2, 0.0),
Complex64::new(0.0, 0.0),
Complex64::new(0.0, 0.0),
Complex64::new(FRAC_1_SQRT_2, 0.0),
];
assert_state_vector_close(standard_result.amplitudes(), &expected_amplitudes, 1e-10);
assert_state_vector_close(simple_opt_result.amplitudes(), &expected_amplitudes, 1e-10);
assert_state_vector_close(chunked_opt_result.amplitudes(), &expected_amplitudes, 1e-10);
assert_state_vector_close(full_opt_result.amplitudes(), &expected_amplitudes, 1e-10);
}
#[test]
fn test_ghz_state_all_simulators() {
let mut circuit = Circuit::<3>::new();
circuit
.h(QubitId::new(0))
.expect("Failed to apply Hadamard gate")
.cnot(QubitId::new(0), QubitId::new(1))
.expect("Failed to apply CNOT gate")
.cnot(QubitId::new(1), QubitId::new(2))
.expect("Failed to apply CNOT gate");
let standard_sim = StateVectorSimulator::new();
let standard_result = standard_sim
.run(&circuit)
.expect("Standard simulator failed");
let simple_opt_sim = OptimizedSimulatorSimple::new();
let simple_opt_result = simple_opt_sim
.run(&circuit)
.expect("Simple optimized simulator failed");
let chunked_sim = OptimizedSimulatorChunked::new();
let chunked_opt_result = chunked_sim.run(&circuit).expect("Chunked simulator failed");
let full_opt_sim = OptimizedSimulator::new();
let full_opt_result = full_opt_sim
.run(&circuit)
.expect("Full optimized simulator failed");
let mut expected_amplitudes = [Complex64::new(0.0, 0.0); 8];
expected_amplitudes[0] = Complex64::new(FRAC_1_SQRT_2, 0.0);
expected_amplitudes[7] = Complex64::new(FRAC_1_SQRT_2, 0.0);
assert_state_vector_close(standard_result.amplitudes(), &expected_amplitudes, 1e-10);
assert_state_vector_close(simple_opt_result.amplitudes(), &expected_amplitudes, 1e-10);
assert_state_vector_close(chunked_opt_result.amplitudes(), &expected_amplitudes, 1e-10);
assert_state_vector_close(full_opt_result.amplitudes(), &expected_amplitudes, 1e-10);
}
#[test]
fn test_qft_like_circuit() {
let circuit = create_simple_qft_circuit::<3>();
let standard_sim = StateVectorSimulator::new();
let standard_result = standard_sim
.run(&circuit)
.expect("Standard simulator failed");
let simple_opt_sim = OptimizedSimulatorSimple::new();
let simple_opt_result = simple_opt_sim
.run(&circuit)
.expect("Simple optimized simulator failed");
let chunked_sim = OptimizedSimulatorChunked::new();
let chunked_opt_result = chunked_sim.run(&circuit).expect("Chunked simulator failed");
let full_opt_sim = OptimizedSimulator::new();
let full_opt_result = full_opt_sim
.run(&circuit)
.expect("Full optimized simulator failed");
assert_state_vector_close(
standard_result.amplitudes(),
simple_opt_result.amplitudes(),
1e-10,
);
assert_state_vector_close(
standard_result.amplitudes(),
chunked_opt_result.amplitudes(),
1e-10,
);
assert_state_vector_close(
standard_result.amplitudes(),
full_opt_result.amplitudes(),
1e-10,
);
}
#[test]
fn test_random_circuit_consistency() {
const QUBITS: usize = 5;
const NUM_GATES: usize = 20;
const TWO_QUBIT_RATIO: f64 = 0.3;
let circuit = generate_benchmark_circuit::<QUBITS>(NUM_GATES, TWO_QUBIT_RATIO);
let standard_sim = StateVectorSimulator::new();
let standard_result = standard_sim
.run(&circuit)
.expect("Standard simulator failed");
let simple_opt_sim = OptimizedSimulatorSimple::new();
let simple_opt_result = simple_opt_sim
.run(&circuit)
.expect("Simple optimized simulator failed");
let chunked_sim = OptimizedSimulatorChunked::new();
let chunked_opt_result = chunked_sim.run(&circuit).expect("Chunked simulator failed");
let full_opt_sim = OptimizedSimulator::new();
let full_opt_result = full_opt_sim
.run(&circuit)
.expect("Full optimized simulator failed");
assert_state_vector_close(
standard_result.amplitudes(),
simple_opt_result.amplitudes(),
1e-10,
);
assert_state_vector_close(
standard_result.amplitudes(),
chunked_opt_result.amplitudes(),
1e-10,
);
assert_state_vector_close(
standard_result.amplitudes(),
full_opt_result.amplitudes(),
1e-10,
);
}
#[test]
fn test_larger_circuit() {
const QUBITS: usize = 10;
let mut circuit = Circuit::<QUBITS>::new();
for i in 0..QUBITS {
circuit
.h(QubitId::new(i as u32))
.expect("Failed to apply Hadamard gate");
}
for i in 0..(QUBITS - 1) {
circuit
.cnot(QubitId::new(i as u32), QubitId::new((i + 1) as u32))
.expect("Failed to apply CNOT gate");
}
for i in 0..QUBITS {
circuit
.rz(
QubitId::new(i as u32),
std::f64::consts::PI / (i + 1) as f64,
)
.expect("Failed to apply RZ gate");
}
let simple_opt_sim = OptimizedSimulatorSimple::new();
let simple_opt_result = simple_opt_sim
.run(&circuit)
.expect("Simple optimized simulator failed");
let full_opt_sim = OptimizedSimulator::new();
let full_opt_result = full_opt_sim
.run(&circuit)
.expect("Full optimized simulator failed");
assert_state_vector_close(
simple_opt_result.amplitudes(),
full_opt_result.amplitudes(),
1e-10,
);
}
fn create_simple_qft_circuit<const N: usize>() -> Circuit<N> {
let mut circuit = Circuit::<N>::new();
for i in 0..N {
circuit
.h(QubitId::new(i as u32))
.expect("Failed to apply Hadamard gate");
}
for i in 0..(N - 1) {
circuit
.cz(QubitId::new(i as u32), QubitId::new((i + 1) as u32))
.expect("Failed to apply CZ gate");
}
for i in 0..N {
circuit
.rz(QubitId::new(i as u32), std::f64::consts::PI / 4.0)
.expect("Failed to apply RZ gate");
}
for i in 0..(N / 2) {
circuit
.swap(QubitId::new(i as u32), QubitId::new((N - i - 1) as u32))
.expect("Failed to apply SWAP gate");
}
circuit
}
fn assert_state_vector_close(actual: &[Complex64], expected: &[Complex64], epsilon: f64) {
assert_eq!(
actual.len(),
expected.len(),
"State vectors must have the same length"
);
for (i, (a, e)) in actual.iter().zip(expected.iter()).enumerate() {
assert!(
(a - e).norm() < epsilon,
"Amplitude at index {} differs: actual={}, expected={}, diff={}",
i,
a,
e,
(a - e).norm()
);
}
}