use quantrs2_core::{
error::QuantRS2Result,
gate::{multi::CNOT, single::Hadamard, GateOp},
qubit::QubitId,
register::Register,
};
use scirs2_core::Complex64;
fn main() -> QuantRS2Result<()> {
println!("=== Bell Pair (|Φ+⟩) Creation ===\n");
let mut state = [
Complex64::new(1.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), ];
println!("Initial state: |00⟩");
print_state(&state);
let h_gate = Hadamard { target: QubitId(0) };
let h_matrix = h_gate.matrix()?;
apply_single_qubit_gate_q0(&mut state, &h_matrix);
println!("\nAfter H on qubit 0:");
print_state(&state);
let cnot_gate = CNOT {
control: QubitId(0),
target: QubitId(1),
};
let _cnot_matrix = cnot_gate.matrix()?;
state.swap(2, 3);
println!("\nAfter CNOT(control=0, target=1):");
print_state(&state);
let sqrt2_inv = 1.0 / std::f64::consts::SQRT_2;
let prob_00 = state[0].norm_sqr(); let prob_11 = state[3].norm_sqr(); let norm: f64 = state.iter().map(|a| a.norm_sqr()).sum();
println!("\n=== Verification ===");
println!("P(|00⟩) = {prob_00:.6} (expected 0.5)");
println!("P(|11⟩) = {prob_11:.6} (expected 0.5)");
println!("Norm² = {norm:.6} (expected 1.0)");
let register = Register::<2>::with_amplitudes(state.to_vec())?;
let ez0 = register.expectation_z(0u32)?;
let ez1 = register.expectation_z(1u32)?;
println!("⟨Z₀⟩ = {ez0:+.6} (expected 0.0 — maximally uncertain)");
println!("⟨Z₁⟩ = {ez1:+.6} (expected 0.0 — maximally uncertain)");
assert!((prob_00 - 0.5).abs() < 1e-10, "P(|00⟩) should be 0.5");
assert!((prob_11 - 0.5).abs() < 1e-10, "P(|11⟩) should be 0.5");
assert!((norm - 1.0).abs() < 1e-10, "State not normalized");
assert!(state[1].norm_sqr() < 1e-20, "P(|01⟩) should be 0");
assert!(state[2].norm_sqr() < 1e-20, "P(|10⟩) should be 0");
assert!(ez0.abs() < 1e-10, "⟨Z₀⟩ should be 0 for Bell state");
assert!(ez1.abs() < 1e-10, "⟨Z₁⟩ should be 0 for Bell state");
println!("\nAll assertions passed — Bell state |Φ+⟩ verified!");
Ok(())
}
fn apply_single_qubit_gate_q0(state: &mut [Complex64; 4], matrix: &[Complex64]) {
let m00 = matrix[0];
let m01 = matrix[1];
let m10 = matrix[2];
let m11 = matrix[3];
let (new_00, new_10) = (
m00 * state[0] + m01 * state[2],
m10 * state[0] + m11 * state[2],
);
let (new_01, new_11) = (
m00 * state[1] + m01 * state[3],
m10 * state[1] + m11 * state[3],
);
state[0] = new_00;
state[1] = new_01;
state[2] = new_10;
state[3] = new_11;
}
fn print_state(state: &[Complex64; 4]) {
for (i, &) in state.iter().enumerate() {
let prob = amp.norm_sqr();
if prob > 1e-12 {
println!(
" |{:02b}⟩: {:.4}{:+.4}i (prob = {:.6})",
i, amp.re, amp.im, prob
);
}
}
}