How to resolve the algorithm Apply a digital filter (direct form II transposed) step by step in the Scala programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Apply a digital filter (direct form II transposed) step by step in the Scala programming language

Table of Contents

Problem Statement

Digital filters are used to apply a mathematical operation to a sampled signal. One of the common formulations is the "direct form II transposed" which can represent both infinite impulse response (IIR) and finite impulse response (FIR) filters, as well as being more numerically stable than other forms. [1] Filter a signal using an order 3 low-pass Butterworth filter. The coefficients for the filter are a=[1.00000000, -2.77555756e-16, 3.33333333e-01, -1.85037171e-17] and b = [0.16666667, 0.5, 0.5, 0.16666667] The signal that needs filtering is the following vector: [-0.917843918645, 0.141984778794, 1.20536903482, 0.190286794412, -0.662370894973, -1.00700480494, -0.404707073677 ,0.800482325044, 0.743500089861, 1.01090520172, 0.741527555207, 0.277841675195, 0.400833448236, -0.2085993586, -0.172842103641, -0.134316096293, 0.0259303398477, 0.490105989562, 0.549391221511, 0.9047198589] [Wikipedia on Butterworth filters]

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Apply a digital filter (direct form II transposed) step by step in the Scala programming language

Source code in the scala programming language

object ButterworthFilter extends App {
  private def filter(a: Vector[Double],
                     b: Vector[Double],
                     signal: Vector[Double]): Vector[Double] = {

    @scala.annotation.tailrec
    def outer(i: Int, acc: Vector[Double]): Vector[Double] = {
      if (i >= signal.length) acc
      else {
        @scala.annotation.tailrec
        def inner0(j: Int, tmp: Double): Double = if (j >= b.length) tmp
        else if ((i - j) >= 0) inner0(j + 1, tmp + b(j) * signal(i - j)) else inner0(j + 1, tmp)

        @scala.annotation.tailrec
        def inner1(j: Int, tmp: Double): Double = if (j >= a.length) tmp
        else if (i - j >= 0) inner1(j + 1, tmp - a(j) * acc(i - j)) else inner1(j + 1, tmp)

        outer(i + 1, acc :+ inner1(1, inner0(0, 0D)) / a(0))
      }
    }

    outer(0, Vector())
  }

  filter(Vector[Double](1, -2.77555756e-16, 3.33333333e-01, -1.85037171e-17),
    Vector[Double](0.16666667, 0.5, 0.5, 0.16666667),
    Vector[Double](
      -0.917843918645, 0.141984778794, 1.20536903482, 0.190286794412, -0.662370894973,
      -1.00700480494, -0.404707073677, 0.800482325044, 0.743500089861, 1.01090520172,
      0.741527555207, 0.277841675195, 0.400833448236, -0.2085993586, -0.172842103641,
      -0.134316096293, 0.0259303398477, 0.490105989562, 0.549391221511, 0.9047198589)
  ).grouped(5)
    .map(_.map(x => f"$x% .8f"))
    .foreach(line => println(line.mkString(" ")))

}


  

You may also check:How to resolve the algorithm Primality by trial division step by step in the Lua programming language
You may also check:How to resolve the algorithm Probabilistic choice step by step in the Yabasic programming language
You may also check:How to resolve the algorithm Delete a file step by step in the E programming language
You may also check:How to resolve the algorithm Perfect numbers step by step in the PureBasic programming language
You may also check:How to resolve the algorithm Window creation/X11 step by step in the Wren programming language