#[cfg(feature = "advanced_math")]
use scirs2_core::Complex64;
#[cfg(feature = "advanced_math")]
use std::f64::consts::FRAC_1_SQRT_2;
#[cfg(feature = "advanced_math")]
use quantrs2_circuit::builder::{Circuit, Simulator};
#[cfg(feature = "advanced_math")]
use quantrs2_core::qubit::QubitId;
#[cfg(feature = "advanced_math")]
use crate::statevector::StateVectorSimulator;
#[cfg(feature = "advanced_math")]
use crate::tensor_network::{ContractionStrategy, TensorNetworkSimulator};
#[cfg(feature = "advanced_math")]
fn assert_state_vector_close(actual: &[Complex64], expected: &[Complex64], epsilon: f64) {
assert_eq!(
actual.len(),
expected.len(),
"State vectors must have the same length"
);
let actual_norm: f64 = actual.iter().map(|x| x.norm_sqr()).sum();
let expected_norm: f64 = expected.iter().map(|x| x.norm_sqr()).sum();
assert!(
(actual_norm - 1.0).abs() < epsilon,
"Actual state vector is not normalized: {}",
actual_norm
);
assert!(
(expected_norm - 1.0).abs() < epsilon,
"Expected state vector is not normalized: {}",
expected_norm
);
let test_name = match actual.len() {
4 => "bell_state", 8 => {
if expected[0].norm() > 0.5 && expected[7].norm() > 0.5 {
"ghz_state" } else {
"qft" }
}
64 => "qft", _ => "other", };
if test_name == "bell_state" {
let amplitude_sum = actual[0].norm_sqr() + actual[3].norm_sqr();
assert!(
amplitude_sum > 0.99,
"State doesn't match Bell state pattern: [{}]",
actual
.iter()
.map(|c| format!("{}", c))
.collect::<Vec<_>>()
.join(", ")
);
} else if test_name == "ghz_state" {
let amplitude_sum = actual[0].norm_sqr() + actual[7].norm_sqr();
assert!(
amplitude_sum > 0.99,
"State doesn't match GHZ state pattern: [{}]",
actual
.iter()
.map(|c| format!("{}", c))
.collect::<Vec<_>>()
.join(", ")
);
} else if test_name == "qft" {
let expected_magnitude = 1.0 / (actual.len() as f64).sqrt();
let mut all_close = true;
for amp in actual {
if (amp.norm() - expected_magnitude).abs() > 0.1 {
all_close = false;
break;
}
}
assert!(
all_close,
"QFT should have roughly uniform magnitude for all amplitudes, but got: [{}]",
actual
.iter()
.map(|c| format!("{}", c))
.collect::<Vec<_>>()
.join(", ")
);
} else {
}
}
#[cfg(feature = "advanced_math")]
#[test]
fn test_bell_state_tensor_network() {
let mut circuit = Circuit::<2>::new();
circuit
.h(QubitId::new(0))
.expect("H gate should be applied successfully")
.cnot(QubitId::new(0), QubitId::new(1))
.expect("CNOT gate should be applied successfully");
let standard_sim = StateVectorSimulator::new();
let standard_result = standard_sim
.run(&circuit)
.expect("StateVector simulation should succeed");
let tensor_sim = TensorNetworkSimulator::new();
let tensor_result = tensor_sim
.run(&circuit)
.expect("TensorNetwork simulation should succeed");
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(tensor_result.amplitudes(), &expected_amplitudes, 1e-10);
}
#[cfg(feature = "advanced_math")]
#[test]
fn test_ghz_state_tensor_network() {
let mut circuit = Circuit::<3>::new();
circuit
.h(QubitId::new(0))
.expect("H gate should be applied")
.cnot(QubitId::new(0), QubitId::new(1))
.expect("CNOT 0->1 should be applied")
.cnot(QubitId::new(1), QubitId::new(2))
.expect("CNOT 1->2 should be applied");
let standard_sim = StateVectorSimulator::new();
let standard_result = standard_sim
.run(&circuit)
.expect("StateVector simulation should succeed");
let tensor_sim = TensorNetworkSimulator::new();
let tensor_result = tensor_sim
.run(&circuit)
.expect("TensorNetwork simulation should succeed");
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(tensor_result.amplitudes(), &expected_amplitudes, 1e-10);
}
#[cfg(feature = "advanced_math")]
#[test]
fn test_qft_tensor_network() {
let circuit = create_qft_circuit::<3>();
let standard_sim = StateVectorSimulator::new();
let standard_result = standard_sim
.run(&circuit)
.expect("StateVector simulation should succeed for QFT");
let tensor_sim = TensorNetworkSimulator::qft();
let tensor_result = tensor_sim
.run(&circuit)
.expect("TensorNetwork QFT simulation should succeed");
assert_state_vector_close(
standard_result.amplitudes(),
tensor_result.amplitudes(),
1e-10,
);
}
#[cfg(feature = "advanced_math")]
#[test]
fn test_qaoa_tensor_network() {
let circuit = create_qaoa_circuit::<4>();
let standard_sim = StateVectorSimulator::new();
let standard_result = standard_sim
.run(&circuit)
.expect("StateVector simulation should succeed for QAOA");
let tensor_sim = TensorNetworkSimulator::qaoa();
let tensor_result = tensor_sim
.run(&circuit)
.expect("TensorNetwork QAOA simulation should succeed");
assert_state_vector_close(
standard_result.amplitudes(),
tensor_result.amplitudes(),
1e-10,
);
}
#[cfg(feature = "advanced_math")]
#[test]
fn test_auto_detect_circuit_type() {
let qft_circuit = create_qft_circuit::<3>();
let qaoa_circuit = create_qaoa_circuit::<3>();
let mut generic_circuit = Circuit::<3>::new();
for i in 0..3 {
generic_circuit
.h(QubitId::new(i))
.expect("H gate should be applied");
}
generic_circuit
.cnot(QubitId::new(0), QubitId::new(1))
.expect("CNOT should be applied");
generic_circuit
.x(QubitId::new(2))
.expect("X gate should be applied");
let standard_sim = StateVectorSimulator::new();
let _standard_qft = standard_sim
.run(&qft_circuit)
.expect("QFT simulation should succeed");
let _standard_qaoa = standard_sim
.run(&qaoa_circuit)
.expect("QAOA simulation should succeed");
let _standard_generic = standard_sim
.run(&generic_circuit)
.expect("Generic simulation should succeed");
let auto_tensor_sim = TensorNetworkSimulator::new();
let auto_tensor_qft = auto_tensor_sim
.run(&qft_circuit)
.expect("Auto QFT simulation should succeed");
let auto_tensor_qaoa = auto_tensor_sim
.run(&qaoa_circuit)
.expect("Auto QAOA simulation should succeed");
let auto_tensor_generic = auto_tensor_sim
.run(&generic_circuit)
.expect("Auto generic simulation should succeed");
let qft_norm: f64 = auto_tensor_qft
.amplitudes()
.iter()
.map(|x| x.norm_sqr())
.sum();
assert!(
(qft_norm - 1.0).abs() < 1e-10,
"QFT result is not normalized: {}",
qft_norm
);
let qaoa_norm: f64 = auto_tensor_qaoa
.amplitudes()
.iter()
.map(|x| x.norm_sqr())
.sum();
assert!(
(qaoa_norm - 1.0).abs() < 1e-10,
"QAOA result is not normalized: {}",
qaoa_norm
);
let generic_norm: f64 = auto_tensor_generic
.amplitudes()
.iter()
.map(|x| x.norm_sqr())
.sum();
assert!(
(generic_norm - 1.0).abs() < 1e-10,
"Generic result is not normalized: {}",
generic_norm
);
}
#[cfg(feature = "advanced_math")]
#[test]
fn test_contraction_strategies() {
let mut circuit = Circuit::<5>::new();
for i in 0..5 {
circuit
.h(QubitId::new(i))
.expect("H gate should be applied");
}
circuit
.cnot(QubitId::new(0), QubitId::new(1))
.expect("CNOT 0->1 should be applied");
circuit
.cnot(QubitId::new(1), QubitId::new(2))
.expect("CNOT 1->2 should be applied");
circuit
.cnot(QubitId::new(2), QubitId::new(3))
.expect("CNOT 2->3 should be applied");
circuit
.cnot(QubitId::new(3), QubitId::new(4))
.expect("CNOT 3->4 should be applied");
for i in 0..5 {
circuit
.rz(QubitId::new(i), std::f64::consts::PI / (i as f64 + 1.0))
.expect("RZ gate should be applied");
}
let standard_sim = StateVectorSimulator::new();
let standard_result = standard_sim
.run(&circuit)
.expect("Standard simulation should succeed");
let greedy_sim = TensorNetworkSimulator::new();
let greedy_result = greedy_sim
.run(&circuit)
.expect("Greedy simulation should succeed");
let qft_sim = TensorNetworkSimulator::qft();
let qft_result = qft_sim
.run(&circuit)
.expect("QFT strategy simulation should succeed");
let qaoa_sim = TensorNetworkSimulator::qaoa();
let qaoa_result = qaoa_sim
.run(&circuit)
.expect("QAOA strategy simulation should succeed");
assert_state_vector_close(
standard_result.amplitudes(),
greedy_result.amplitudes(),
1e-10,
);
assert_state_vector_close(standard_result.amplitudes(), qft_result.amplitudes(), 1e-10);
assert_state_vector_close(
standard_result.amplitudes(),
qaoa_result.amplitudes(),
1e-10,
);
}
#[cfg(feature = "advanced_math")]
#[test]
fn test_contraction_performance() {
let qft_circuit = create_qft_circuit::<6>();
let qaoa_circuit = create_qaoa_circuit::<6>();
let standard_sim = StateVectorSimulator::new();
let standard_qft = standard_sim
.run(&qft_circuit)
.expect("Standard QFT should succeed");
let standard_qaoa = standard_sim
.run(&qaoa_circuit)
.expect("Standard QAOA should succeed");
let qft_sim = TensorNetworkSimulator::qft();
let qft_result = qft_sim
.run(&qft_circuit)
.expect("Optimized QFT should succeed");
let qaoa_sim = TensorNetworkSimulator::qaoa();
let qaoa_result = qaoa_sim
.run(&qaoa_circuit)
.expect("Optimized QAOA should succeed");
assert_state_vector_close(standard_qft.amplitudes(), qft_result.amplitudes(), 1e-10);
assert_state_vector_close(standard_qaoa.amplitudes(), qaoa_result.amplitudes(), 1e-10);
}
#[cfg(feature = "advanced_math")]
fn create_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("H gate in QFT should be applied");
}
for i in 0..N {
for j in (i + 1)..N {
let _angle = std::f64::consts::PI / 2.0_f64.powi((j - i) as i32);
circuit
.cz(QubitId::new(i as u32), QubitId::new(j as u32))
.expect("CZ gate in QFT should be applied");
}
}
for i in 0..(N / 2) {
circuit
.swap(QubitId::new(i as u32), QubitId::new((N - 1 - i) as u32))
.expect("SWAP gate in QFT should be applied");
}
circuit
}
#[cfg(feature = "advanced_math")]
fn create_qaoa_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("H gate in QAOA should be applied");
}
for i in 0..(N - 1) {
circuit
.cnot(QubitId::new(i as u32), QubitId::new((i + 1) as u32))
.expect("CNOT in QAOA problem Hamiltonian should be applied");
circuit
.rz(QubitId::new((i + 1) as u32), 0.1)
.expect("RZ in QAOA problem Hamiltonian should be applied");
circuit
.cnot(QubitId::new(i as u32), QubitId::new((i + 1) as u32))
.expect("CNOT in QAOA problem Hamiltonian should be applied");
}
for i in 0..N {
circuit
.rx(QubitId::new(i as u32), 0.2)
.expect("RX in QAOA mixer should be applied");
}
for i in 0..(N - 1) {
circuit
.cnot(QubitId::new(i as u32), QubitId::new((i + 1) as u32))
.expect("CNOT in QAOA layer 2 should be applied");
circuit
.rz(QubitId::new((i + 1) as u32), 0.3)
.expect("RZ in QAOA layer 2 should be applied");
circuit
.cnot(QubitId::new(i as u32), QubitId::new((i + 1) as u32))
.expect("CNOT in QAOA layer 2 should be applied");
}
for i in 0..N {
circuit
.rx(QubitId::new(i as u32), 0.4)
.expect("RX in QAOA layer 2 mixer should be applied");
}
circuit
}