A radio's tone control is a digital filter with transfer function H(z) = B(z) / A(z) (coefficient lists b and a in powers of z^-1, as in the previous problems). Before listening, the engineer checks the two extremes of its frequency range:
- DC (0 Hz, a constant input, the deepest "bass"): a constant signal is unchanged by a delay, so every
z^-1acts like1. The gain isH(1) = (b[0] + b[1] + b[2] + ...) / (a[0] + a[1] + a[2] + ...). This is the steady-state gain of Level 2, for a filter of any length. - Nyquist (
fs / 2, the fastest signal there is,+1, -1, +1, -1, ..., the highest "treble"): a delay of one sample flips its sign, soz^-1acts like-1andH(-1) = (b[0] - b[1] + b[2] - ...) / (a[0] - a[1] + a[2] - ...).
A gain of 2 doubles the signal's amplitude; a negative gain also turns it upside down. If the denominator is 0, the filter has a pole exactly there and the gain is not finite: an integrator (a = [1, -1]) keeps adding up a constant input for ever.
Write bass_treble(b, a) that returns the pair (H(1), H(-1)), with None in place of a gain whose denominator has abs(...) < 1e-9.
Examples
Input: b = [0.5, 0.5], a = [1]
Output: (1.0, 0.0)
Explanation: averaging two neighbours keeps a constant and removes +1, -1, +1, ... completely.
Input: b = [1, -0.5], a = [1, 0.5]
Output: (0.3333333333333333, 3.0)
Explanation: 0.5 / 1.5 for the bass, 1.5 / 0.5 for the treble: a treble boost.
Input: b = [1], a = [1, -1]
Output: (None, 0.5)
Explanation: an integrator: a constant input grows without limit.
Constraints
- answers are compared with a tolerance of
1e-6; a list is accepted in place of the tuple - the tests never have a denominator close to
1e-9unless it is really 0
Goals
- Find the gain for a constant input as H(1) = sum(b) / sum(a)
- Find the gain at the Nyquist frequency as H(-1), with alternating signs
- Recognise a pole at z = 1 or z = -1, where the gain is not finite