iir: more generic math helpers, use core::intrinsics

This commit is contained in:
Robert Jördens 2020-11-27 10:36:30 +01:00
parent ea3e343c39
commit 74349e5d68
2 changed files with 28 additions and 28 deletions

View File

@ -1,4 +1,4 @@
use core::ops::{Add, Mul};
use core::ops::{Add, Mul, Neg};
use serde::{Deserialize, Serialize};
use core::f32;
@ -8,16 +8,24 @@ use core::f32;
// `compiler-intrinsics`/llvm should have better (robust, universal, and
// faster) implementations.
fn abs(x: f32) -> f32 {
if x >= 0. {
fn abs<T>(x: T) -> T
where
T: PartialOrd + Default + Neg<Output = T>,
{
if x >= T::default() {
x
} else {
-x
}
}
fn copysign(x: f32, y: f32) -> f32 {
if (x >= 0. && y >= 0.) || (x <= 0. && y <= 0.) {
fn copysign<T>(x: T, y: T) -> T
where
T: PartialOrd + Default + Neg<Output = T>,
{
if (x >= T::default() && y >= T::default())
|| (x <= T::default() && y <= T::default())
{
x
} else {
-x
@ -25,7 +33,10 @@ fn copysign(x: f32, y: f32) -> f32 {
}
#[cfg(not(feature = "nightly"))]
fn max(x: f32, y: f32) -> f32 {
fn max<T>(x: T, y: T) -> T
where
T: PartialOrd,
{
if x > y {
x
} else {
@ -34,7 +45,10 @@ fn max(x: f32, y: f32) -> f32 {
}
#[cfg(not(feature = "nightly"))]
fn min(x: f32, y: f32) -> f32 {
fn min<T>(x: T, y: T) -> T
where
T: PartialOrd,
{
if x < y {
x
} else {
@ -44,26 +58,12 @@ fn min(x: f32, y: f32) -> f32 {
#[cfg(feature = "nightly")]
fn max(x: f32, y: f32) -> f32 {
let o: f32;
unsafe {
asm!("vmaxnm.f32 {}, {}, {}",
lateout(sreg) o, in(sreg) x, in(sreg) y,
options(pure, nomem, nostack, preserves_flags)
);
}
o
core::intrinsics::maxnumf32(x, y)
}
#[cfg(feature = "nightly")]
fn min(x: f32, y: f32) -> f32 {
let o: f32;
unsafe {
asm!("vminnm.f32 {}, {}, {}",
lateout(sreg) o, in(sreg) x, in(sreg) y,
options(pure, nomem, nostack, preserves_flags)
);
}
o
core::intrinsics::minnumf32(x, y)
}
// Multiply-accumulate vectors `x` and `a`.
@ -76,7 +76,7 @@ where
{
x.iter()
.zip(a)
.map(|(&x, &a)| x * a)
.map(|(x, a)| *x * *a)
.fold(y0, |y, xa| y + xa)
}
@ -84,10 +84,10 @@ where
///
/// To represent the IIR state (input and output memory) during the filter update
/// this contains the three inputs (x0, x1, x2) and the two outputs (y1, y2)
/// concatenated.
/// concatenated. Lower indices correspond to more recent samples.
/// To represent the IIR coefficients, this contains the feed-forward
/// coefficients (b0, b1, b2) followd by the feed-back coefficients (a1, a2),
/// all normalized such that a0 = 1.
/// coefficients (b0, b1, b2) followd by the negated feed-back coefficients
/// (-a1, -a2), all five normalized such that a0 = 1.
pub type IIRState = [f32; 5];
/// IIR configuration.

View File

@ -1,4 +1,4 @@
#![no_std]
#![cfg_attr(feature = "nightly", feature(asm))]
#![cfg_attr(feature = "nightly", feature(asm, core_intrinsics))]
pub mod iir;