quantrs2_ml/utils/
encoding.rs1use crate::error::{MLError, Result};
4use scirs2_core::ndarray::{Array1, Array2};
5use scirs2_core::Complex64;
6
7use super::*;
8pub fn amplitude_encode(data: &Array1<f64>) -> Result<Array1<Complex64>> {
10 let norm: f64 = data.iter().map(|x| x * x).sum::<f64>().sqrt();
11 if norm < 1e-10 {
12 return Err(MLError::ComputationError(
13 "Cannot amplitude encode zero vector".to_string(),
14 ));
15 }
16 let encoded = data.mapv(|x| Complex64::new(x / norm, 0.0));
17 Ok(encoded)
18}
19pub fn angle_encode(data: &Array1<f64>, scale: f64) -> Result<Array1<f64>> {
21 let pi = std::f64::consts::PI;
22 let encoded = data.mapv(|x| (x * scale).rem_euclid(2.0 * pi));
23 Ok(encoded)
24}
25pub fn basis_encode(data: &Array1<usize>, num_qubits: usize) -> Result<Array2<u8>> {
28 let max_val = 1 << num_qubits;
29 for &val in data.iter() {
30 if val >= max_val {
31 return Err(MLError::InvalidInput(format!(
32 "Value {} exceeds maximum {} for {} qubits",
33 val,
34 max_val - 1,
35 num_qubits
36 )));
37 }
38 }
39 let mut encoded = Array2::zeros((data.len(), num_qubits));
40 for (i, &val) in data.iter().enumerate() {
41 for j in 0..num_qubits {
42 encoded[(i, num_qubits - 1 - j)] = ((val >> j) & 1) as u8;
43 }
44 }
45 Ok(encoded)
46}
47pub fn product_encode(data: &Array1<f64>) -> Result<Array1<f64>> {
50 let pi = std::f64::consts::PI;
51 let min_val = data.iter().cloned().fold(f64::INFINITY, f64::min);
52 let max_val = data.iter().cloned().fold(f64::NEG_INFINITY, f64::max);
53 let range = max_val - min_val;
54 if range < 1e-10 {
55 return Ok(Array1::from_elem(data.len(), pi / 2.0));
56 }
57 let encoded = data.mapv(|x| ((x - min_val) / range) * pi);
58 Ok(encoded)
59}
60pub fn dense_angle_encode(data: &Array1<f64>) -> Result<Array1<f64>> {
63 let pi = std::f64::consts::PI;
64 let encoded = data.mapv(|x| {
65 let normalized = (x.atan() / (pi / 2.0) + 1.0) * pi;
66 normalized
67 });
68 Ok(encoded)
69}
70pub fn iqp_encode(data: &Array1<f64>, degree: usize) -> Result<Array1<f64>> {
73 let n = data.len();
74 let mut encoded = Vec::new();
75 for &x in data.iter() {
76 encoded.push(x);
77 }
78 if degree >= 2 {
79 for i in 0..n {
80 for j in i..n {
81 encoded.push(data[i] * data[j]);
82 }
83 }
84 }
85 if degree >= 3 {
86 for i in 0..n {
87 for j in i..n {
88 for k in j..n {
89 encoded.push(data[i] * data[j] * data[k]);
90 }
91 }
92 }
93 }
94 Ok(Array1::from_vec(encoded))
95}
96pub fn pauli_feature_map_encode(data: &Array1<f64>, reps: usize) -> Result<Array1<f64>> {
99 let pi = std::f64::consts::PI;
100 let n = data.len();
101 let mut encoded = Vec::new();
102 for _ in 0..reps {
103 for &x in data.iter() {
104 encoded.push(2.0 * x);
105 }
106 for i in 0..n {
107 for j in (i + 1)..n {
108 let angle = (pi - data[i]) * (pi - data[j]);
109 encoded.push(2.0 * angle);
110 }
111 }
112 }
113 Ok(Array1::from_vec(encoded))
114}