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}