cmsis_dsp/basic.rs
1//! Basic math functions
2
3use fixed::types::{I16F48, I18F14, I1F15, I1F31, I1F7, I34F30};
4
5use crate::check_length;
6
7/// Calculates the absolute value of multiple values
8///
9/// This is functionally equivalent to performing `dst[i] = abs(src[i])` for all values of i in
10/// range.
11///
12/// # Panics
13///
14/// This function panics if src and dst do not have the same length.
15pub fn abs_f32(src: &[f32], dst: &mut [f32]) {
16 let length = check_length((src.len(), dst.len()));
17 unsafe {
18 cmsis_dsp_sys::arm_abs_f32(src.as_ptr(), dst.as_mut_ptr(), length);
19 }
20}
21
22/// Calculates the absolute value of multiple values
23///
24/// This is functionally equivalent to performing `dst[i] = abs(src[i])` for all values of i in
25/// range.
26///
27/// # Panics
28///
29/// This function panics if src and dst do not have the same length.
30pub fn abs_q31(src: &[I1F31], dst: &mut [I1F31]) {
31 let length = check_length((src.len(), dst.len()));
32 unsafe {
33 cmsis_dsp_sys::arm_abs_q31(src.as_ptr() as *const _, dst.as_mut_ptr() as *mut _, length);
34 }
35}
36
37/// Calculates the absolute value of multiple values
38///
39/// This is functionally equivalent to performing `dst[i] = abs(src[i])` for all values of i in
40/// range.
41///
42/// # Panics
43///
44/// This function panics if src and dst do not have the same length.
45pub fn abs_q15(src: &[I1F15], dst: &mut [I1F15]) {
46 let length = check_length((src.len(), dst.len()));
47 unsafe {
48 cmsis_dsp_sys::arm_abs_q15(src.as_ptr() as *const _, dst.as_mut_ptr() as *mut _, length);
49 }
50}
51
52/// Calculates the absolute value of multiple values
53///
54/// This is functionally equivalent to performing `dst[i] = abs(src[i])` for all values of i in
55/// range.
56///
57/// # Panics
58///
59/// This function panics if src and dst do not have the same length.
60pub fn abs_q7(src: &[I1F7], dst: &mut [I1F7]) {
61 let length = check_length((src.len(), dst.len()));
62 unsafe {
63 cmsis_dsp_sys::arm_abs_q7(src.as_ptr() as *const _, dst.as_mut_ptr() as *mut _, length);
64 }
65}
66
67/// Calculates the absolute value of multiple values in place
68///
69/// This is functionally equivalent to performing `values[i] = abs(values[i])` for all values of i
70/// in range.
71pub fn abs_in_place_f32(values: &mut [f32]) {
72 let length = check_length(values.len());
73 // The CMSIS DSP function specifically does support argument aliasing. Is this really safe
74 // from the Rust perspective?
75 unsafe {
76 let ptr = values.as_mut_ptr();
77 cmsis_dsp_sys::arm_abs_f32(ptr, ptr, length);
78 }
79}
80
81/// Calculates the absolute value of multiple values in place
82///
83/// This is functionally equivalent to performing `values[i] = abs(values[i])` for all values of i
84/// in range.
85pub fn abs_in_place_q31(values: &mut [I1F31]) {
86 let length = check_length(values.len());
87 unsafe {
88 let ptr = values.as_mut_ptr();
89 cmsis_dsp_sys::arm_abs_q31(ptr as *const _, ptr as *mut _, length);
90 }
91}
92
93/// Calculates the absolute value of multiple values in place
94///
95/// This is functionally equivalent to performing `values[i] = abs(values[i])` for all values of i
96/// in range.
97pub fn abs_in_place_q15(values: &mut [I1F15]) {
98 let length = check_length(values.len());
99 unsafe {
100 let ptr = values.as_mut_ptr();
101 cmsis_dsp_sys::arm_abs_q15(ptr as *const _, ptr as *mut _, length);
102 }
103}
104
105/// Calculates the absolute value of multiple values in place
106///
107/// This is functionally equivalent to performing `values[i] = abs(values[i])` for all values of i
108/// in range.
109pub fn abs_in_place_q7(values: &mut [I1F7]) {
110 let length = check_length(values.len());
111 unsafe {
112 let ptr = values.as_mut_ptr();
113 cmsis_dsp_sys::arm_abs_q7(ptr as *const _, ptr as *mut _, length);
114 }
115}
116
117/// Adds multiple values
118///
119/// This is functionally equivalent to performing `dst[i] = src1[i] + src2[i]` for all values of i
120/// in range.
121///
122/// # Panics
123///
124/// This function panics if src1, src2, and dst do not have the same length.
125pub fn add_f32(src1: &[f32], src2: &[f32], dst: &mut [f32]) {
126 let length = check_length((src1.len(), src2.len(), dst.len()));
127 unsafe {
128 cmsis_dsp_sys::arm_add_f32(src1.as_ptr(), src2.as_ptr(), dst.as_mut_ptr(), length);
129 }
130}
131
132/// Adds multiple values
133///
134/// This is functionally equivalent to performing `dst[i] = src1[i] + src2[i]` for all values of i
135/// in range.
136///
137/// # Panics
138///
139/// This function panics if src1, src2, and dst do not have the same length.
140pub fn add_q31(src1: &[I1F31], src2: &[I1F31], dst: &mut [I1F31]) {
141 let length = check_length((src1.len(), src2.len(), dst.len()));
142 unsafe {
143 cmsis_dsp_sys::arm_add_q31(
144 src1.as_ptr() as *const _,
145 src2.as_ptr() as *const _,
146 dst.as_mut_ptr() as *mut _,
147 length,
148 );
149 }
150}
151
152/// Adds multiple values
153///
154/// This is functionally equivalent to performing `dst[i] = src1[i] + src2[i]` for all values of i
155/// in range.
156///
157/// # Panics
158///
159/// This function panics if src1, src2, and dst do not have the same length.
160pub fn add_q15(src1: &[I1F15], src2: &[I1F15], dst: &mut [I1F15]) {
161 let length = check_length((src1.len(), src2.len(), dst.len()));
162 unsafe {
163 cmsis_dsp_sys::arm_add_q15(
164 src1.as_ptr() as *const _,
165 src2.as_ptr() as *const _,
166 dst.as_mut_ptr() as *mut _,
167 length,
168 );
169 }
170}
171
172/// Adds multiple values
173///
174/// This is functionally equivalent to performing `dst[i] = src1[i] + src2[i]` for all values of i
175/// in range.
176///
177/// # Panics
178///
179/// This function panics if src1, src2, and dst do not have the same length.
180pub fn add_q7(src1: &[I1F7], src2: &[I1F7], dst: &mut [I1F7]) {
181 let length = check_length((src1.len(), src2.len(), dst.len()));
182 unsafe {
183 cmsis_dsp_sys::arm_add_q7(
184 src1.as_ptr() as *const _,
185 src2.as_ptr() as *const _,
186 dst.as_mut_ptr() as *mut _,
187 length,
188 );
189 }
190}
191
192/// Calculates the dot product of two vectors
193///
194/// The returned value is the sum of `src1[i] * src2[i]` over all values of i
195/// in range.
196///
197/// # Panics
198///
199/// This function panics if src1 and src2 do not have the same length.
200pub fn dot_product_f32(src1: &[f32], src2: &[f32]) -> f32 {
201 let length = check_length((src1.len(), src2.len()));
202 let mut result = 0.0;
203 unsafe {
204 cmsis_dsp_sys::arm_dot_prod_f32(src1.as_ptr(), src2.as_ptr(), length, &mut result);
205 }
206 result
207}
208
209/// Calculates the dot product of two vectors
210///
211/// The returned value is the sum of `src1[i] * src2[i]` over all values of i
212/// in range.
213///
214/// # Panics
215///
216/// This function panics if src1 and src2 do not have the same length.
217pub fn dot_product_q31(src1: &[I1F31], src2: &[I1F31]) -> I16F48 {
218 let length = check_length((src1.len(), src2.len()));
219 let mut result = I16F48::from_bits(0);
220 unsafe {
221 cmsis_dsp_sys::arm_dot_prod_q31(
222 src1.as_ptr() as *const _,
223 src2.as_ptr() as *const _,
224 length,
225 &mut result as *mut _ as *mut _,
226 );
227 }
228 result
229}
230
231/// Calculates the dot product of two vectors
232///
233/// The returned value is the sum of `src1[i] * src2[i]` over all values of i
234/// in range.
235///
236/// # Panics
237///
238/// This function panics if src1 and src2 do not have the same length.
239pub fn dot_product_q15(src1: &[I1F15], src2: &[I1F15]) -> I34F30 {
240 let length = check_length((src1.len(), src2.len()));
241 let mut result = I34F30::from_bits(0);
242 unsafe {
243 cmsis_dsp_sys::arm_dot_prod_q15(
244 src1.as_ptr() as *const _,
245 src2.as_ptr() as *const _,
246 length,
247 &mut result as *mut _ as *mut _,
248 );
249 }
250 result
251}
252
253/// Calculates the dot product of two vectors
254///
255/// The returned value is the sum of `src1[i] * src2[i]` over all values of i
256/// in range.
257///
258/// # Panics
259///
260/// This function panics if src1 and src2 do not have the same length.
261pub fn dot_product_q7(src1: &[I1F7], src2: &[I1F7]) -> I18F14 {
262 let length = check_length((src1.len(), src2.len()));
263 let mut result = I18F14::from_bits(0);
264 unsafe {
265 cmsis_dsp_sys::arm_dot_prod_q7(
266 src1.as_ptr() as *const _,
267 src2.as_ptr() as *const _,
268 length,
269 &mut result as *mut _ as *mut _,
270 );
271 }
272 result
273}
274
275/// Multiplies multiple values
276///
277/// This is functionally equivalent to performing `dst[i] = src1[i] * src2[i]` for all values of i
278/// in range.
279///
280/// # Panics
281///
282/// This function panics if src1, src2, and dst do not have the same length.
283pub fn multiply_f32(src1: &[f32], src2: &[f32], dst: &mut [f32]) {
284 let length = check_length((src1.len(), src2.len(), dst.len()));
285 unsafe {
286 cmsis_dsp_sys::arm_mult_f32(src1.as_ptr(), src2.as_ptr(), dst.as_mut_ptr(), length);
287 }
288}
289
290/// Multiplies multiple values
291///
292/// This is similar to performing `dst[i] = src1[i] * src2[i]` for all values of i
293/// in range. This function saturates on overflow.
294///
295/// # Panics
296///
297/// This function panics if src1, src2, and dst do not have the same length.
298pub fn multiply_q31(src1: &[I1F31], src2: &[I1F31], dst: &mut [I1F31]) {
299 let length = check_length((src1.len(), src2.len(), dst.len()));
300 unsafe {
301 cmsis_dsp_sys::arm_mult_q31(
302 src1.as_ptr() as *const _,
303 src2.as_ptr() as *const _,
304 dst.as_mut_ptr() as *mut _,
305 length,
306 );
307 }
308}
309
310/// Multiplies multiple values
311///
312/// This is similar to performing `dst[i] = src1[i] * src2[i]` for all values of i
313/// in range. This function saturates on overflow.
314///
315/// # Panics
316///
317/// This function panics if src1, src2, and dst do not have the same length.
318pub fn multiply_q15(src1: &[I1F15], src2: &[I1F15], dst: &mut [I1F15]) {
319 let length = check_length((src1.len(), src2.len(), dst.len()));
320 unsafe {
321 cmsis_dsp_sys::arm_mult_q15(
322 src1.as_ptr() as *const _,
323 src2.as_ptr() as *const _,
324 dst.as_mut_ptr() as *mut _,
325 length,
326 );
327 }
328}
329
330/// Multiplies multiple values
331///
332/// This is similar to performing `dst[i] = src1[i] * src2[i]` for all values of i
333/// in range. This function saturates on overflow.
334///
335/// # Panics
336///
337/// This function panics if src1, src2, and dst do not have the same length.
338pub fn multiply_q7(src1: &[I1F7], src2: &[I1F7], dst: &mut [I1F7]) {
339 let length = check_length((src1.len(), src2.len(), dst.len()));
340 unsafe {
341 cmsis_dsp_sys::arm_mult_q7(
342 src1.as_ptr() as *const _,
343 src2.as_ptr() as *const _,
344 dst.as_mut_ptr() as *mut _,
345 length,
346 );
347 }
348}