embedded_dsp/
statistics.rs1#[allow(unused_imports)]
4use crate::math::FloatMath;
5use crate::types::*;
6
7pub fn mean_f32(src: &[f32], result: &mut f32) -> Status {
10 if src.is_empty() {
11 return Status::LengthError;
12 }
13 let mut sum = 0.0f32;
14 for &val in src {
15 sum += val;
16 }
17 *result = sum / (src.len() as f32);
18 Status::Success
19}
20
21pub fn mean_f64(src: &[f64], result: &mut f64) -> Status {
22 if src.is_empty() {
23 return Status::LengthError;
24 }
25 let mut sum = 0.0f64;
26 for &val in src {
27 sum += val;
28 }
29 *result = sum / (src.len() as f64);
30 Status::Success
31}
32
33pub fn mean_q31(src: &[q31], result: &mut q31) -> Status {
34 if src.is_empty() {
35 return Status::LengthError;
36 }
37 let mut sum: q63 = 0;
38 for &val in src {
39 sum += val as q63;
40 }
41 *result = (sum / (src.len() as q63)) as q31;
42 Status::Success
43}
44
45pub fn mean_q15(src: &[q15], result: &mut q15) -> Status {
46 if src.is_empty() {
47 return Status::LengthError;
48 }
49 let mut sum: i32 = 0;
50 for &val in src {
51 sum += val as i32;
52 }
53 *result = (sum / (src.len() as i32)) as q15;
54 Status::Success
55}
56
57pub fn mean_q7(src: &[q7], result: &mut q7) -> Status {
58 if src.is_empty() {
59 return Status::LengthError;
60 }
61 let mut sum: i32 = 0;
62 for &val in src {
63 sum += val as i32;
64 }
65 *result = (sum / (src.len() as i32)) as q7;
66 Status::Success
67}
68
69pub fn var_f32(src: &[f32], result: &mut f32) -> Status {
72 if src.len() <= 1 {
73 return Status::LengthError;
74 }
75 let mut mean = 0.0f32;
76 mean_f32(src, &mut mean);
77 let mut sum_sq = 0.0f32;
78 for &val in src {
79 let diff = val - mean;
80 sum_sq += diff * diff;
81 }
82 *result = sum_sq / ((src.len() - 1) as f32);
83 Status::Success
84}
85
86pub fn var_f64(src: &[f64], result: &mut f64) -> Status {
87 if src.len() <= 1 {
88 return Status::LengthError;
89 }
90 let mut mean = 0.0f64;
91 mean_f64(src, &mut mean);
92 let mut sum_sq = 0.0f64;
93 for &val in src {
94 let diff = val - mean;
95 sum_sq += diff * diff;
96 }
97 *result = sum_sq / ((src.len() - 1) as f64);
98 Status::Success
99}
100
101pub fn var_q31(src: &[q31], result: &mut q31) -> Status {
102 if src.len() <= 1 {
103 return Status::LengthError;
104 }
105 let mut m = 0;
106 mean_q31(src, &mut m);
107 let mut sum_sq: u64 = 0;
108 for &val in src {
109 let diff = (val as i64) - (m as i64);
110 sum_sq += ((diff * diff) >> 31) as u64;
111 }
112 *result = ((sum_sq / (src.len() - 1) as u64) as i64).clamp(0, i32::MAX as i64) as q31;
113 Status::Success
114}
115
116pub fn var_q15(src: &[q15], result: &mut q15) -> Status {
117 if src.len() <= 1 {
118 return Status::LengthError;
119 }
120 let mut m = 0;
121 mean_q15(src, &mut m);
122 let mut sum_sq: u32 = 0;
123 for &val in src {
124 let diff = (val as i32) - (m as i32);
125 sum_sq += ((diff * diff) >> 15) as u32;
126 }
127 *result = ((sum_sq / (src.len() - 1) as u32) as i32).clamp(0, i16::MAX as i32) as q15;
128 Status::Success
129}
130
131pub fn var_q7(src: &[q7], result: &mut q7) -> Status {
132 if src.len() <= 1 {
133 return Status::LengthError;
134 }
135 let mut m = 0;
136 mean_q7(src, &mut m);
137 let mut sum_sq: u32 = 0;
138 for &val in src {
139 let diff = (val as i32) - (m as i32);
140 sum_sq += ((diff * diff) >> 7) as u32;
141 }
142 *result = ((sum_sq / (src.len() - 1) as u32) as i32).clamp(0, i8::MAX as i32) as q7;
143 Status::Success
144}
145
146pub fn std_f32(src: &[f32], result: &mut f32) -> Status {
149 let mut v = 0.0f32;
150 let status = var_f32(src, &mut v);
151 if status == Status::Success {
152 *result = v.sqrt();
153 }
154 status
155}
156
157pub fn std_f64(src: &[f64], result: &mut f64) -> Status {
158 let mut v = 0.0f64;
159 let status = var_f64(src, &mut v);
160 if status == Status::Success {
161 *result = v.sqrt();
162 }
163 status
164}
165
166pub fn std_q31(src: &[q31], result: &mut q31) -> Status {
167 let mut v = 0;
168 let status = var_q31(src, &mut v);
169 if status == Status::Success {
170 let vf = v as f64 / 2147483648.0;
171 let s = vf.sqrt();
172 *result = (s * 2147483647.0).clamp(0.0, 2147483647.0) as q31;
173 }
174 status
175}
176
177pub fn std_q15(src: &[q15], result: &mut q15) -> Status {
178 let mut v = 0;
179 let status = var_q15(src, &mut v);
180 if status == Status::Success {
181 let vf = v as f32 / 32768.0;
182 let s = vf.sqrt();
183 *result = (s * 32767.0).clamp(0.0, 32767.0) as q15;
184 }
185 status
186}
187
188pub fn std_q7(src: &[q7], result: &mut q7) -> Status {
189 let mut v = 0;
190 let status = var_q7(src, &mut v);
191 if status == Status::Success {
192 let vf = v as f32 / 128.0;
193 let s = vf.sqrt();
194 *result = (s * 127.0).clamp(0.0, 127.0) as q7;
195 }
196 status
197}
198
199pub fn rms_f32(src: &[f32], result: &mut f32) -> Status {
202 if src.is_empty() {
203 return Status::LengthError;
204 }
205 let mut sum_sq = 0.0f32;
206 for &val in src {
207 sum_sq += val * val;
208 }
209 *result = (sum_sq / (src.len() as f32)).sqrt();
210 Status::Success
211}
212
213pub fn rms_q31(src: &[q31], result: &mut q31) -> Status {
214 if src.is_empty() {
215 return Status::LengthError;
216 }
217 let mut sum_sq: u64 = 0;
218 for &val in src {
219 let v = val as i64;
220 sum_sq += ((v * v) >> 31) as u64;
221 }
222 let mean_sq = sum_sq / (src.len() as u64);
223 let vf = mean_sq as f64 / 2147483648.0;
224 let r = vf.sqrt();
225 *result = (r * 2147483647.0).clamp(0.0, 2147483647.0) as q31;
226 Status::Success
227}
228
229pub fn rms_q15(src: &[q15], result: &mut q15) -> Status {
230 if src.is_empty() {
231 return Status::LengthError;
232 }
233 let mut sum_sq: u32 = 0;
234 for &val in src {
235 let v = val as i32;
236 sum_sq += ((v * v) >> 15) as u32;
237 }
238 let mean_sq = sum_sq / (src.len() as u32);
239 let vf = mean_sq as f32 / 32768.0;
240 let r = vf.sqrt();
241 *result = (r * 32767.0).clamp(0.0, 32767.0) as q15;
242 Status::Success
243}
244
245pub fn power_f32(src: &[f32], result: &mut f32) -> Status {
248 if src.is_empty() {
249 return Status::LengthError;
250 }
251 let mut sum_sq = 0.0f32;
252 for &val in src {
253 sum_sq += val * val;
254 }
255 *result = sum_sq;
256 Status::Success
257}
258
259pub fn power_q31(src: &[q31], result: &mut q63) -> Status {
260 if src.is_empty() {
261 return Status::LengthError;
262 }
263 let mut sum_sq: q63 = 0;
264 for &val in src {
265 let v = val as i64;
266 sum_sq += (v * v) >> 14;
267 }
268 *result = sum_sq;
269 Status::Success
270}
271
272pub fn power_q15(src: &[q15], result: &mut q63) -> Status {
273 if src.is_empty() {
274 return Status::LengthError;
275 }
276 let mut sum_sq: q63 = 0;
277 for &val in src {
278 let v = val as i32;
279 sum_sq += (v * v) as q63;
280 }
281 *result = sum_sq;
282 Status::Success
283}
284
285pub fn power_q7(src: &[q7], result: &mut q31) -> Status {
286 if src.is_empty() {
287 return Status::LengthError;
288 }
289 let mut sum_sq: q31 = 0;
290 for &val in src {
291 let v = val as i32;
292 sum_sq += v * v;
293 }
294 *result = sum_sq;
295 Status::Success
296}
297
298pub fn min_f32(src: &[f32], result: &mut f32, index: &mut usize) -> Status {
301 if src.is_empty() {
302 return Status::LengthError;
303 }
304 let mut min_val = src[0];
305 let mut min_idx = 0;
306 for (i, &val) in src.iter().enumerate().skip(1) {
307 if val < min_val {
308 min_val = val;
309 min_idx = i;
310 }
311 }
312 *result = min_val;
313 *index = min_idx;
314 Status::Success
315}
316
317pub fn max_f32(src: &[f32], result: &mut f32, index: &mut usize) -> Status {
318 if src.is_empty() {
319 return Status::LengthError;
320 }
321 let mut max_val = src[0];
322 let mut max_idx = 0;
323 for (i, &val) in src.iter().enumerate().skip(1) {
324 if val > max_val {
325 max_val = val;
326 max_idx = i;
327 }
328 }
329 *result = max_val;
330 *index = max_idx;
331 Status::Success
332}
333
334pub fn min_q31(src: &[q31], result: &mut q31, index: &mut usize) -> Status {
335 if src.is_empty() {
336 return Status::LengthError;
337 }
338 let mut min_val = src[0];
339 let mut min_idx = 0;
340 for (i, &val) in src.iter().enumerate().skip(1) {
341 if val < min_val {
342 min_val = val;
343 min_idx = i;
344 }
345 }
346 *result = min_val;
347 *index = min_idx;
348 Status::Success
349}
350
351pub fn max_q31(src: &[q31], result: &mut q31, index: &mut usize) -> Status {
352 if src.is_empty() {
353 return Status::LengthError;
354 }
355 let mut max_val = src[0];
356 let mut max_idx = 0;
357 for (i, &val) in src.iter().enumerate().skip(1) {
358 if val > max_val {
359 max_val = val;
360 max_idx = i;
361 }
362 }
363 *result = max_val;
364 *index = max_idx;
365 Status::Success
366}
367
368pub fn min_q15(src: &[q15], result: &mut q15, index: &mut usize) -> Status {
369 if src.is_empty() {
370 return Status::LengthError;
371 }
372 let mut min_val = src[0];
373 let mut min_idx = 0;
374 for (i, &val) in src.iter().enumerate().skip(1) {
375 if val < min_val {
376 min_val = val;
377 min_idx = i;
378 }
379 }
380 *result = min_val;
381 *index = min_idx;
382 Status::Success
383}
384
385pub fn max_q15(src: &[q15], result: &mut q15, index: &mut usize) -> Status {
386 if src.is_empty() {
387 return Status::LengthError;
388 }
389 let mut max_val = src[0];
390 let mut max_idx = 0;
391 for (i, &val) in src.iter().enumerate().skip(1) {
392 if val > max_val {
393 max_val = val;
394 max_idx = i;
395 }
396 }
397 *result = max_val;
398 *index = max_idx;
399 Status::Success
400}
401
402pub fn min_q7(src: &[q7], result: &mut q7, index: &mut usize) -> Status {
403 if src.is_empty() {
404 return Status::LengthError;
405 }
406 let mut min_val = src[0];
407 let mut min_idx = 0;
408 for (i, &val) in src.iter().enumerate().skip(1) {
409 if val < min_val {
410 min_val = val;
411 min_idx = i;
412 }
413 }
414 *result = min_val;
415 *index = min_idx;
416 Status::Success
417}
418
419pub fn max_q7(src: &[q7], result: &mut q7, index: &mut usize) -> Status {
420 if src.is_empty() {
421 return Status::LengthError;
422 }
423 let mut max_val = src[0];
424 let mut max_idx = 0;
425 for (i, &val) in src.iter().enumerate().skip(1) {
426 if val > max_val {
427 max_val = val;
428 max_idx = i;
429 }
430 }
431 *result = max_val;
432 *index = max_idx;
433 Status::Success
434}
435
436pub fn absmax_f32(src: &[f32], result: &mut f32, index: &mut usize) -> Status {
439 if src.is_empty() {
440 return Status::LengthError;
441 }
442 let mut max_val = src[0].abs();
443 let mut max_idx = 0;
444 for (i, &val) in src.iter().enumerate().skip(1) {
445 let abs_val = val.abs();
446 if abs_val > max_val {
447 max_val = abs_val;
448 max_idx = i;
449 }
450 }
451 *result = max_val;
452 *index = max_idx;
453 Status::Success
454}
455
456pub fn absmin_f32(src: &[f32], result: &mut f32, index: &mut usize) -> Status {
457 if src.is_empty() {
458 return Status::LengthError;
459 }
460 let mut min_val = src[0].abs();
461 let mut min_idx = 0;
462 for (i, &val) in src.iter().enumerate().skip(1) {
463 let abs_val = val.abs();
464 if abs_val < min_val {
465 min_val = abs_val;
466 min_idx = i;
467 }
468 }
469 *result = min_val;
470 *index = min_idx;
471 Status::Success
472}
473
474pub fn entropy_f32(src: &[f32]) -> f32 {
477 let mut ent = 0.0f32;
478 for &p in src {
479 if p > 0.0 {
480 ent -= p * p.ln();
481 }
482 }
483 ent
484}
485
486pub fn kullback_leibler_f32(p: &[f32], q: &[f32]) -> f32 {
487 let len = p.len().min(q.len());
488 let mut kl = 0.0f32;
489 for i in 0..len {
490 if p[i] > 0.0 && q[i] > 0.0 {
491 kl += p[i] * (p[i] / q[i]).ln();
492 }
493 }
494 kl
495}
496
497pub fn logsumexp_f32(src: &[f32]) -> f32 {
498 if src.is_empty() {
499 return 0.0;
500 }
501 let mut max_v = src[0];
502 for &v in src.iter().skip(1) {
503 if v > max_v {
504 max_v = v;
505 }
506 }
507 let mut sum_exp = 0.0f32;
508 for &v in src {
509 sum_exp += (v - max_v).exp();
510 }
511 max_v + sum_exp.ln()
512}