Help on mathematics of filters

Dear AI2 specialists,

I am working on processing of ECG signals.
In order to process the received data, we need to filter it.
Several papers suggest filtering foemulas for high-pass and low-pass filters.
But I don't know how to write those formulas in AI2 blocks.
For example I quote part of one paper:

filters

Could anyone please help me writing the required blocks?

Thanks in advance,
Sirous

What have you tried? You have a mathematics issue; the equations you supplied (in isolation) are simultaneous equations, Whether you can use either

to solve the equation is problematical. What value are you solving for? Do you know the value of all the variables?

Someone would need to know what you are filtering and where the data originates. Those equations in themselves are useless out of context.

Another possibility is to use javascript. This article Signal.js shows how to produce a lowpass filter using javascript. App Inventor can use javascript modules. The article does not explain how to use the javascript with AI.

An online reference would be helpful for interpreting the formula.

I can't tell if (nT - T) is the difference of two variables, or (n*T - T), equivalent to (n-1)T.

Here's a low pass filter in blocks, courtesy of Wikipedia

// Return RC low-pass filter output samples, given input samples,
// time interval dt, and time constant RC
function lowpass(real[0..n] x, real dt, real RC)
    var real[0..n] y
    var real α := dt / (RC + dt)
    y[0] := α * x[0]
    for i from 1 to n
        y[i] := α * x[i] + (1-α) * y[i-1]
    return y
The loop that calculates each of the n outputs can be refactored into the equivalent:

    for i from 1 to n
        y[i] := y[i-1] + α * (x[i] - y[i-1])

and here are the blocks, assuming a non-empty list of x values, and dt and RC as described at that article.

Here is the high pass filter from

// Return RC high-pass filter output samples, given input samples,
// time interval dt, and time constant RC
function highpass(real[0..n] x, real dt, real RC)
    var real[0..n] y
    var real α := RC / (RC + dt)
    y[0] := x[0]
    for i from 1 to n
        y[i] := α × y[i−1] + α × (x[i] − x[i−1])
    return y
The loop which calculates each of the {\displaystyle n}n outputs can be refactored into the equivalent:

    for i from 1 to n
        y[i] := α × (y[i−1] + x[i] − x[i−1])

and the blocks would be

The blocks are draggable.

It would be wise to double check my blocks against the formula, just in case.

1 Like

https://www.researchgate.net/publication/323807706_QRS_Detection_Based_on_Improved_Adaptive_Threshold

Unfortunately, that article does not define nT or T.
It might be Chinese subscript notation, for all I know.

It works!
Really works.
However, I changed the variables to global, anyway.

Thank you

Keep them on a leash, so they don't get loose.

Was that a proverb? I didn't understand what you mean.

Global variables are like medical catheters.
Local variables are like internal organs, you don't want them exposed to the elements, otherwise you are living a horror movie.
Sometimes you really need a global variable, for example when a Clock Timer has to pass data to another part of your code.
But there is a cost to them, if a later you or someone else goes to change the program and forgets all the connections between program parts that pass through the global variable's contents.
I try to avoid them, or to replace them with getter/setter functions if I can.
The programming terms for these ideas are

  • locality of reference
  • cohesion vs coupling
2 Likes

Good explanation, thank you.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.