Skip to content

Instantly share code, notes, and snippets.

@kristopherjohnson
Last active April 2, 2023 00:54
Show Gist options
  • Save kristopherjohnson/0b0442c9b261f44cf19a to your computer and use it in GitHub Desktop.
Save kristopherjohnson/0b0442c9b261f44cf19a to your computer and use it in GitHub Desktop.
Simple implementation of low-pass filter
struct LowPassFilterSignal {
/// Current signal value
var value: Double
/// A scaling factor in the range 0.0..<1.0 that determines
/// how resistant the value is to change
let filterFactor: Double
/// Update the value, using filterFactor to attenuate changes
mutating func update(newValue: Double) {
value = filterFactor * value + (1.0 - filterFactor) * newValue
}
}
@uros-gardasevic
Copy link

It's probably the naming that has made you confused. The previous computed value plays the significant role in creation of a new one, hence should be multiplied by higher factor (in our case, where α is picked as a very small number closer to 0, that factor is (1-α)).
Thats the whole point of this filter, to not let new value significantly peak over the current one.

So next to (1-α), where α should number between 0 and 1 but closer to 0, you should have previously computed value.
(1-α) * smoothedValueFromPreviousStep + α * newRawValue

If you look at the equation bellow, you might get better understand where s the motivation coming from.
value * (1-α) + value * α = (1 - α + α) * value = 1 * value = value

Finally, if you take an opposite approach in defining α, where it still resides in [0,1] but closer to 1, then you can revert the naming.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment