use quantrs2_ml::error::Result;
use quantrs2_ml::utils::encoding::amplitude_encode;
use scirs2_core::ndarray::{array, Array1};
use scirs2_core::Complex64;
fn main() -> Result<()> {
println!("=== Amplitude Encoding: Classical Data → Quantum State ===\n");
println!("--- Example 1: 4D vector (2 qubits) ---");
let v1 = array![1.0f64, 2.0, 3.0, 4.0];
let norm_v1: f64 = v1.iter().map(|x| x * x).sum::<f64>().sqrt();
let encoded1 = amplitude_encode(&v1)?;
let norm_enc1: f64 = encoded1.iter().map(|c| c.norm_sqr()).sum::<f64>().sqrt();
println!("Input vector : {:?}", v1.as_slice().expect("slice"));
println!("Input norm : {norm_v1:.6}");
println!("Encoded state:");
for (i, &) in encoded1.iter().enumerate() {
println!(
" |{i:02b}⟩ : amplitude = {:+.4}{:+.4}i (prob = {:.6})",
amp.re,
amp.im,
amp.norm_sqr()
);
}
println!("Encoded norm : {norm_enc1:.10} (should be 1.0)");
assert!(
(norm_enc1 - 1.0).abs() < 1e-10,
"Encoded state must be normalised, got norm={norm_enc1}"
);
println!("\n--- Example 2: 8D image patch (3 qubits) ---");
let image_patch = array![0.1f64, 0.5, 0.9, 0.3, 0.7, 0.2, 0.8, 0.4];
let encoded2 = amplitude_encode(&image_patch)?;
let norm_enc2: f64 = encoded2.iter().map(|c| c.norm_sqr()).sum::<f64>().sqrt();
println!(
"Image patch (8 pixels): {:?}",
image_patch.as_slice().expect("slice")
);
println!("Quantum state norms² :");
for (i, &) in encoded2.iter().enumerate() {
let bar = "#".repeat((amp.norm_sqr() * 20.0).round() as usize);
println!(" |{i:03b}⟩ : {:.4} {bar}", amp.norm_sqr());
}
println!("Norm check : {norm_enc2:.10} (should be 1.0)");
assert!((norm_enc2 - 1.0).abs() < 1e-10, "Norm must be 1.0");
println!("\n--- Example 3: Quantum Inner Product ---");
let a = array![1.0f64, 0.0, 0.0, 0.0]; let b = array![1.0f64, 0.0, 0.0, 0.0]; let c = array![0.0f64, 1.0, 0.0, 0.0]; let d = array![1.0f64, 1.0, 0.0, 0.0];
let enc_a = amplitude_encode(&a)?;
let enc_b = amplitude_encode(&b)?;
let enc_c = amplitude_encode(&c)?;
let enc_d = amplitude_encode(&d)?;
let fidelity_ab = quantum_fidelity(&enc_a, &enc_b);
let fidelity_ac = quantum_fidelity(&enc_a, &enc_c);
let fidelity_ad = quantum_fidelity(&enc_a, &enc_d);
println!(" ⟨e1|e1⟩² = {fidelity_ab:.6} (expected 1.0 — identical)");
println!(" ⟨e1|e2⟩² = {fidelity_ac:.6} (expected 0.0 — orthogonal)");
println!(" ⟨e1|d ⟩² = {fidelity_ad:.6} (expected 0.5 — 45°)");
assert!(
(fidelity_ab - 1.0).abs() < 1e-10,
"Identical vectors: fidelity=1"
);
assert!(fidelity_ac < 1e-10, "Orthogonal vectors: fidelity=0");
assert!((fidelity_ad - 0.5).abs() < 0.01, "45° angle: fidelity≈0.5");
println!("\n--- Example 4: Error handling (zero vector) ---");
let zero = array![0.0f64, 0.0, 0.0, 0.0];
match amplitude_encode(&zero) {
Err(e) => println!(" Zero vector rejected: {e} ✓"),
Ok(_) => panic!("Should have rejected zero vector"),
}
println!("\n=== Summary ===");
println!(" d=4 → 2 qubits (log₂(4) = 2)");
println!(" d=8 → 3 qubits (log₂(8) = 3)");
println!(" d=2^n data encoded in n qubits — exponential compression");
println!(" Quantum inner product computable in O(1) measurement shots");
println!("\nAll checks passed — OK");
Ok(())
}
fn quantum_fidelity(psi_a: &Array1<Complex64>, psi_b: &Array1<Complex64>) -> f64 {
let inner: Complex64 = psi_a
.iter()
.zip(psi_b.iter())
.map(|(&a, &b)| a.conj() * b)
.sum();
inner.norm_sqr()
}