Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve online filter functions #605

Open
ufechner7 opened this issue Dec 4, 2024 · 1 comment
Open

Improve online filter functions #605

ufechner7 opened this issue Dec 4, 2024 · 1 comment

Comments

@ufechner7
Copy link

ufechner7 commented Dec 4, 2024

If you want to filter online data, you can use the following function:

"""
    apply_filter(tfilter::DF2TFilter, measurement)

Apply the filter to the measurement.

# Arguments
- `tfilter`: The filter, created with `create_filter` and converted to a DF2TFilter
- `measurement`: The measurement value
"""
function apply_filter(tfilter::DF2TFilter, measurement)
    results = zeros(1)
    measurements = ones(1) * measurement
    @views filt!(results[1:1], tfilter, measurements)
    return results[1]
end

This is an ugly workaround. We need a function that does the same, but:

  • does not require the allocation of one element arrays
  • does not allocate at all (important for real-time control systems)

In addition, the fact that this function does not accept a filter of type ZeroPoleGain is annoying.

@martinholters
Copy link
Member

  • does not require the allocation of one element arrays

Yes, this is quite unfortunate. Would be nice if we could tack this on filt as accepting a single number as the input "signal". However, we could not do that too broadly as we have
filt(h::Vector, x::AbstractVector, rate::AbstractFloat) (FIR resampling) and filt(b::Union{Number, AbstractVector}, a::Union{Number, AbstractVector}, x::AbstractArray{T}). Now if we allowed x to be a number in the latter, that would cause ambiguities. Arguably, this single-sample processing only makes sense if state is preserved, i.e. when using DF2TFilter. So adding a method filt(f::DF2TFilter, x::Number) returning a single number seems reasonable to me and the inconsistency of not doing this for the other filt variants can be justified. (Oh, just noticed that filt(self::FIRFilter{<:FIRStandard}, x) would be another candidate; but that also is unambiguous when a x::Number method is added.)

  • does not allocate at all (important for real-time control systems)

You get that if you base the DF2TFilter on SecondOrderSections:

julia> typeof(H)
DF2TFilter{SecondOrderSections{:z, Float64, Float64}, Matrix{Float64}}

julia> @ballocated filt!(y, H, x)
0

It surely would be nice for PolynomialRatio to also allow this, but that is not so easily solved.
(This is for filt!, of course, but should translate to a potential future single-sample filt.)

In addition, the fact that this function does not accept a filter of type ZeroPoleGain is annoying.

It does accept it, but converts it to SecondOrderSections. I'm not completely sure working with the (complex-valued!) poles/zeros would be better in any way. What's the benefit?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants