# Crate iq_osc [−] [src]

I/Q oscillator without trig function calls.

Given

f(t) = cos(θ

_{0}+ ωt) = cos Φ(t),

an oscillator is defined here to evaluate f(0), f(1), f(2), ... in sequence to
generate a sinusoidal signal. Further, a *quadrature* oscillator also evaluates
g(t) = sin Φ(t) at each step for the quadrature signal.

Calling out to these trig functions at each evaluation of f(t) and g(t) can be costly with a high sample rate or within a tight loop. As an alternative, this crate implements a quadrature oscillator that replaces the 2 trig function calls at each evaluation with 6 arithmetic operations (4 multiplies, 1 addition, and 1 subtraction.)

## Theory

Using the definition of f(t) = cos Φ(t) from above, notice that

Φ(0) = θ

_{0}Φ(1) = θ

_{0}+ ω = Φ(0) + ωΦ(2) = θ

_{0}+ 2ω = Φ(1) + ω

And in general,

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

With this and the trig identities

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

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

we can then write f(t) as

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

and similarly for the quadrature signal,

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

If we compute sin ω, cos ω, sin θ_{0}, and cos θ_{0} at
initialization, then we can compute f(t) and g(t) for t = 0, 1, 2, ... using just the
arithmetic in the above equations.

## Error Accumulation

Due to the accumulation of floating-point roundoff errors, the accuracy of returned
sine/cosine evaluations will slowly degrade over phase steps. Using a very small phase
step or running an `IQOsc`

through many, many cycles will make this problem more
pronounced. As a workaround, the double-precision `IQOsc<f64>`

can be used, which
provides a significant increase in accuracy across phase steps and has relatively
little impact on speed – compare `bench_osc32`

and `bench_osc64`

in the output of
`cargo bench`

(example output is given below.)

```
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)
```

## Structs

IQOsc |
Quadrature oscillator with current phase Φ(t) and phase step ω. |