array_object/convert/
into_complex.rs1use crate::adaptor::*;
2use crate::error::ArrayObjectError;
3use crate::storage::*;
4use num_complex::Complex;
5
6macro_rules! into_complex {
7 ($($ty:tt),*) => {
8 $(
9 impl TryFrom<ArrayObject> for Pair<$ty> {
10 type Error = ArrayObjectError;
11 fn try_from(mut val: ArrayObject) -> Result<Self, Self::Error> {
12 if !val.shape.is_empty() || val.datatype != DataType::Complex {
13 return Err(ArrayObjectError::WrongDataType(val.datatype, val.shape.len()));
14 }
15 match val.data.len() / 2 {
16 4 => {
17 let data_im = val.data.split_off(4);
18 let re = f32::from_le_bytes(val.data.try_into().unwrap()) as $ty;
19 let im = f32::from_le_bytes(data_im.try_into().unwrap()) as $ty;
20 Ok(Pair(re, im))
21 }
22 8 => {
23 #[cfg(not(feature = "allow_float_down_convert"))]
24 if size_of::<$ty>() < 8 {
25 return Err(ArrayObjectError::LossyConversion);
26 }
27 let data_im = val.data.split_off(8);
28 let re = f64::from_le_bytes(val.data.try_into().unwrap()) as $ty;
29 let im = f64::from_le_bytes(data_im.try_into().unwrap()) as $ty;
30 Ok(Pair(re, im))
31 }
32 _ => {panic!();}
33 }
34 }
35 }
36 impl TryFrom<ArrayObject> for Complex<$ty> {
37 type Error = ArrayObjectError;
38 fn try_from(val: ArrayObject) -> Result<Self, Self::Error> {
39 let Pair(re, im) = val.try_into()?;
40 Ok(Complex::new(re, im))
41 }
42 }
43 impl TryFrom<ArrayObject> for VecShape<Pair<$ty>> {
44 type Error = ArrayObjectError;
45 fn try_from(val: ArrayObject) -> Result<Self, Self::Error> {
46 if val.shape.is_empty() || val.datatype != DataType::Complex {
47 return Err(ArrayObjectError::WrongDataType(val.datatype, val.shape.len()));
48 }
49 let len = val.len();
50 if len == 0 {
51 return Ok(VecShape(vec![], val.shape));
52 }
53 match val.data.len() / (2 * len) {
54 4 => {
55 let data = val.data.chunks(8).map(|b| {
56 let mut iter = b.chunks(4);
57 let re = f32::from_le_bytes(iter.next().unwrap().to_vec().try_into().unwrap()) as $ty;
58 let im = f32::from_le_bytes(iter.next().unwrap().to_vec().try_into().unwrap()) as $ty;
59 Pair(re, im)
60 }).collect();
61 Ok(VecShape(data, val.shape))
62 }
63 8 => {
64 #[cfg(not(feature = "allow_float_down_convert"))]
65 if size_of::<$ty>() < 8 {
66 return Err(ArrayObjectError::LossyConversion);
67 }
68 let data = val.data.chunks(16).map(|b| {
69 let mut iter = b.chunks(8);
70 let re = f64::from_le_bytes(iter.next().unwrap().to_vec().try_into().unwrap()) as $ty;
71 let im = f64::from_le_bytes(iter.next().unwrap().to_vec().try_into().unwrap()) as $ty;
72 Pair(re, im)
73 }).collect();
74 Ok(VecShape(data, val.shape))
75 }
76 _ => {panic!();}
77 }
78 }
79 }
80 impl TryFrom<ArrayObject> for VecShape<Complex<$ty>> {
81 type Error = ArrayObjectError;
82 fn try_from(val: ArrayObject) -> Result<Self, Self::Error> {
83 if val.shape.is_empty() || val.datatype != DataType::Complex {
84 return Err(ArrayObjectError::WrongDataType(val.datatype, val.shape.len()));
85 }
86 let len = val.len();
87 if len == 0 {
88 return Ok(VecShape(vec![], val.shape));
89 }
90 match val.data.len() / (2 * len) {
91 4 => {
92 let data = val.data.chunks(8).map(|b| {
93 let mut iter = b.chunks(4);
94 let re = f32::from_le_bytes(iter.next().unwrap().to_vec().try_into().unwrap()) as $ty;
95 let im = f32::from_le_bytes(iter.next().unwrap().to_vec().try_into().unwrap()) as $ty;
96 Complex::<$ty>::new(re, im)
97 }).collect();
98 Ok(VecShape(data, val.shape))
99 }
100 8 => {
101 #[cfg(not(feature = "allow_float_down_convert"))]
102 if size_of::<$ty>() < 8 {
103 return Err(ArrayObjectError::LossyConversion);
104 }
105 let data = val.data.chunks(16).map(|b| {
106 let mut iter = b.chunks(8);
107 let re = f64::from_le_bytes(iter.next().unwrap().to_vec().try_into().unwrap()) as $ty;
108 let im = f64::from_le_bytes(iter.next().unwrap().to_vec().try_into().unwrap()) as $ty;
109 Complex::<$ty>::new(re, im)
110 }).collect();
111 Ok(VecShape(data, val.shape))
112 }
113 _ => {panic!();}
114 }
115 }
116 }
117 impl TryFrom<ArrayObject> for VecVecShape<$ty> {
118 type Error = ArrayObjectError;
119 fn try_from(val: ArrayObject) -> Result<Self, Self::Error> {
120 if val.shape.is_empty() || val.datatype != DataType::Complex {
121 return Err(ArrayObjectError::WrongDataType(val.datatype, val.shape.len()));
122 }
123 let len = val.len();
124 if len == 0 {
125 return Ok(VecVecShape(vec![], vec![], val.shape));
126 }
127 let mut re = Vec::<$ty>::with_capacity(len * 2);
128 let mut im = Vec::<$ty>::with_capacity(len * 2);
129 match val.data.len() / (2 * len) {
130 4 => {
131 for b in val.data.chunks(8) {
132 let mut iter = b.chunks(4);
133 re.push(f32::from_le_bytes(iter.next().unwrap().to_vec().try_into().unwrap()) as $ty);
134 im.push(f32::from_le_bytes(iter.next().unwrap().to_vec().try_into().unwrap()) as $ty);
135 }
136 }
137 8 => {
138 #[cfg(not(feature = "allow_float_down_convert"))]
139 if size_of::<$ty>() < 8 {
140 return Err(ArrayObjectError::LossyConversion);
141 }
142 for b in val.data.chunks(16) {
143 let mut iter = b.chunks(8);
144 re.push(f64::from_le_bytes(iter.next().unwrap().to_vec().try_into().unwrap()) as $ty);
145 im.push(f64::from_le_bytes(iter.next().unwrap().to_vec().try_into().unwrap()) as $ty);
146 }
147 }
148 _ => {panic!();}
149 }
150 Ok(VecVecShape(re, im, val.shape))
151 }
152 }
153 impl TryFrom<ArrayObject> for Vec<Complex<$ty>> {
154 type Error = ArrayObjectError;
155 fn try_from(val: ArrayObject) -> Result<Self, Self::Error> {
156 if val.shape.len() != 1 {
157 return Err(ArrayObjectError::WrongDataType(val.datatype, val.shape.len()));
158 }
159 let VecShape::<Complex<$ty>>(data, _) = val.try_into()?;
160 Ok(data)
161 }
162 }
163 impl<const N: usize> TryFrom<ArrayObject> for [Complex<$ty>; N] {
164 type Error = ArrayObjectError;
165 fn try_from(val: ArrayObject) -> Result<Self, Self::Error> {
166 if val.len() != N {
167 return Err(ArrayObjectError::WrongDataType(val.datatype, val.shape.len()));
168 }
169 let data: Vec<Complex<$ty>> = val.try_into()?;
170 Ok(data.try_into().unwrap())
171 }
172 }
173 )*
174 };
175}
176
177into_complex!(f32, f64);