Problem 455079 · easy · Level 04 Non-Linear Data Structures

Probing a Hearing-Aid Filter at Any z

transfer function · complex numbers · polynomial evaluation · Horner's rule · poles

A hearing aid shapes sound with a recursive digital filter. Its designer describes it by two coefficient lists, b (the numerator) and a (the denominator), and its transfer function

         B(z)     b[0] + b[1] * z^-1 + b[2] * z^-2 + ...
H(z) = ------ = ----------------------------------------
         A(z)     a[0] + a[1] * z^-1 + a[2] * z^-2 + ...

Until now z^-1 was a symbol for a delay. The power of the transfer function is that you can also put a number in for z, any complex number except 0, and get a complex number H(z) back. Special values of z answer physical questions: z = 1 gives the gain for a constant input, and points on the circle |z| = 1 give the response to sine waves (both come later in this level). Values of z where A(z) = 0 are the filter's poles: there H(z) is not defined, and near them it is huge.

Python's complex numbers do the arithmetic: z ** -k is z^-k, and 1j is the imaginary unit.

Write tf_value(b, a, z) that returns the pair (H.real, H.imag), or None if abs(A(z)) < 1e-12 (z is a pole).

Examples

Input:  b = [1, 1], a = [1, -0.5], z = 1
Output: (4.0, 0.0)
Explanation: B(1) = 1 + 1 = 2, A(1) = 1 - 0.5 = 0.5, so H(1) = 4.

Input:  b = [1, 1], a = [1, -0.5], z = 1j
Output: (0.4, -1.2)
Explanation: z^-1 = 1 / 1j = -1j, so B = 1 - 1j and A = 1 + 0.5j; (1 - 1j) / (1 + 0.5j) = 0.4 - 1.2j.

Input:  b = [1, 1], a = [1, -0.5], z = 0.5
Output: None
Explanation: A(0.5) = 1 - 0.5 * 2 = 0: z = 0.5 is a pole.

Constraints

  • z may be given as an int, a float or a complex number, never 0
  • answers are compared with a tolerance of 1e-6; a list [re, im] is accepted in place of the tuple
  • the tests never have abs(A(z)) close to 1e-12 unless it is really 0

Goals

  • Evaluate a transfer function H(z) = B(z) / A(z) at a complex number z
  • Evaluate a polynomial in z^-1 term by term or with Horner's rule
  • Recognise a value of z where the denominator is zero (a pole)
Starting Python…