iir: more generic math helpers, use core::intrinsics
This commit is contained in:
parent
ea3e343c39
commit
74349e5d68
|
@ -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.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#![no_std]
|
||||
#![cfg_attr(feature = "nightly", feature(asm))]
|
||||
#![cfg_attr(feature = "nightly", feature(asm, core_intrinsics))]
|
||||
|
||||
pub mod iir;
|
||||
|
|
Loading…
Reference in New Issue