androidsignal-processinglowpass-filtertransfer-function

creating a digital filter in android


I'm trying to deal with ECG signal processing in android. I want to implement simple digital filters (lowpass, highpass)

I've got a transfer function:

click to see transfer function

here is what i've found:

wikipedia - lowpass filter - it looks quite easy here.

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

but there is nothing about transfer function which I want to use.

I also found the following matlab code

%% Low Pass Filter  H(z) = (1 - 2z^(-6) + z^(-12)) / (1 - 2z^(-1) + z^(-2))
b = [1 0 0 0 0 0 -2 0 0 0 0 0 1];
a = [1 -2 1];
h_l = filter(b,a,[1 zeros(1,12)]); 
ecg_l = conv (ecg ,h_l);

but there is no function like filter and conv in java (or I missed something).

Also I was looking on stackoverflow for an answer. But I didn't found anything about transfer function.

so can someone help me? I just want to move on with my project.


Solution

  • Given a time-domain recurrence equation (such as the one you quoted from wikipedia), the corresponding transfer function in the z-domain can relatively easily be obtained by using the following properties:

    $$\begin{align} \mathcal Z\left{x[n-k]\right} &= z^{-k} X(z) \tag{1}\    H(z) &= \frac{Y(z)}{X(z)} \tag{2}\end{align}$$

    Where X(z) and Y(z) are the z-transforms of the time-domain input sequence x and output sequence y respectively. Going the other way around, given a transfer function which can be expressed as a ratio of polynomials in z, such as:

    H(z) = \frac{\sum_{i=0}^N b_i z^{-i}}{1 + \sum_{i=1}^M a_i z^{-i}}

    the recurrence equation of the transfer function can be written as:

    y[n] = -\sum_{i=1}^M a_i y[n-i] + \sum_{i=0}^N b_i x[n-i]

    There are of course many different ways to implement such a recurrence equation, but a simple filter implementation following the Direct Form II would be along the line of:

    // Implementation of an Infinite Impulse Response (IIR) filter
    // with recurrence equation:
    //   y[n] = -\sum_{i=1}^M a_i y[n-i] + \sum_{i=0}^N b_i x[n-i]
    public class IIRFilter {
    
      public IIRFilter(float a_[], float b_[]) {
        // initialize memory elements
        int N = Math.max(a_.length, b_.length);
        memory = new float[N-1];
        for (int i = 0; i < memory.length; i++) {
          memory[i] = 0.0f;
        }
        // copy filter coefficients
        a = new float[N];
        int i = 0;
        for (; i < a_.length; i++) {
          a[i] = a_[i];
        }
        for (; i < N; i++) {
          a[i] = 0.0f;
        }
        b = new float[N];
        i = 0;
        for (; i < b_.length; i++) {
          b[i] = b_[i];
        }
        for (; i < N; i++) {
          b[i] = 0.0f;
        }
      }
    
      // Filter samples from input buffer, and store result in output buffer.
      // Implementation based on Direct Form II.
      // Works similar to matlab's "output = filter(b,a,input)" command
      public void process(float input[], float output[]) {
        for (int i = 0; i < input.length; i++) {
          float in  = input[i];
          float out = 0.0f;
          for (int j = memory.length-1; j >= 0; j--) {
            in  -= a[j+1] * memory[j];
            out += b[j+1] * memory[j];
          }
          out += b[0] * in;
          output[i] = out;
          // shift memory
          for (int j = memory.length-1; j > 0; j--) {
            memory[j] = memory[j - 1];
          }
          memory[0] = in;
        }
      }
    
      private float[] a;
      private float[] b;
      private float[] memory;
    }
    

    which you could use to implement your specific transfer function like so:

    float   g = 1.0f/32.0f; // overall filter gain
    float[] a = {1, -2, 1};
    float[] b = {g, 0, 0, 0, 0, 0, -2*g, 0, 0, 0, 0, 0, g};
    IIRFilter filter = new IIRFilter(a, b);
    
    filter.process(input, output);
    

    Note that you can alternatively also factorize the numerator and denominator into 2nd order polynomials and obtain a cascade of 2nd order filters (known as biquad filters).