#振荡器 #信号 #触发 #波形 #I/Q

iq_osc

无触发函数调用的I/Q振荡器

1 个稳定版本

使用旧的Rust 2015

3.0.0 2018年1月2日

#17 in #振荡器

MIT 许可证

22KB
318

iq_osc.rs – 无触发函数调用的I/Q振荡器

文档

给定 f(t) = cos(θ0 + ωt) = cos Φ(t),在这里定义一个振荡器来按顺序计算 f(0),f(1),f(2),... 以生成正弦信号。此外,一个 正交 振荡器也在每一步计算 g(t) = sin Φ(t) 以生成正交信号。

在高采样率或紧密循环中对这些三角函数进行计算可能会非常昂贵。作为替代方案,这个crate实现了一个正交振荡器,在每个评估中将2个三角函数调用替换为6次算术运算(4次乘法,1次加法和1次减法)。

用法

可以通过在 Cargo.toml 中将其添加为依赖项,通过cargo使用此 crate

[dependencies]
iq_osc = "3.0.0"

并在crate根目录中导入它

extern crate iq_osc;

lib.rs:

无触发函数调用的I/Q振荡器。

给定

f(t) = cos(θ0 + ωt) = cos Φ(t),

在这里定义一个振荡器来按顺序计算 f(0),f(1),f(2),... 以生成正弦信号。此外,一个 正交 振荡器也在每一步计算 g(t) = sin Φ(t) 以生成正交信号。

在高采样率或紧密循环中对这些三角函数进行计算可能会非常昂贵。作为替代方案,这个crate实现了一个正交振荡器,在每个评估中将2个三角函数调用替换为6次算术运算(4次乘法,1次加法和1次减法)。

理论

使用上面定义的 f(t) = cos Φ(t),注意到

Φ(0) = θ0

Φ(1) = θ0 + ω = Φ(0) + ω

Φ(2) = θ0 + 2ω = Φ(1) + ω

一般来说,

Φ(t) = Φ(t - 1) + ω, t > 0

结合这一点和三角恒等式

cos(u + v) = cos(u)cos(v) - sin(u)sin(v)

sin(u + v) = sin(u)cos(v) + cos(u)sin(v)

我们可以将 f(t) 写作

f(t) = cos(Φ(t - 1) + ω) = cos(Φ(t - 1))cos(ω) - sin(Φ(t - 1))sin(ω)

对于正交信号,类似地

g(t) = sin(Φ(t - 1) + ω) = sin(Φ(t - 1))cos(ω) + cos(Φ(t - 1))sin(ω)

如果我们在初始化时计算 sin ω,cos ω,sin θ0 和 cos θ0,那么我们就可以使用上面的方程中的算术来计算 f(t) 和 g(t) 对于 t = 0,1,2,... 的值。

误差累积

由于浮点数舍入误差的累积,返回的正弦/余弦评估的精度会随着相位步长逐渐降低。使用非常小的相位步长或让 IQOsc 进行许多许多周期运行会使这个问题更加明显。作为解决方案,可以使用双精度 IQOsc<f64>,它在相位步长上提供了显著的精度提升,并且对速度的影响相对较小——比较 bench_osc32bench_osc64cargo bench 输出中的结果(以下给出示例输出)。

test bench_osc32  ... bench:      55,043 ns/iter (+/- 4,479)
test bench_osc64  ... bench:      62,170 ns/iter (+/- 30,989)
test bench_trig32 ... bench:     490,407 ns/iter (+/- 90,148)
test bench_trig64 ... bench:   2,365,592 ns/iter (+/- 148,062)

依赖项

~240KB