Engee documentation

invfreqz

Determination of discrete filter parameters based on frequency response data.

Library

EngeeDSP

Syntax

Function call

  • b,a = invfreqz(h,w,n,m) — returns vectors of the real coefficients of the numerator and denominator b and a the transfer function h.

  • b,a = invfreqz(h,w,n,m,wt) — weights the approximation errors depending on the frequency using the argument wt.

  • b,a = invfreqz(___,iter) — provides an algorithm that guarantees the stability of the resulting linear system by searching for the best approximation using a numerical iterative scheme. This syntax can include any combination of input arguments from previous syntax options.

  • b,a = invfreqz(___,tol) — uses an argument tol to determine the convergence of an iterative algorithm.

  • b,a = invfreqz(___,"trace") — displays a text report on the progress of the iteration.

  • b,a = invfreqz(h,w,"complex",n,m,___) — creates a comprehensive filter. In this case, the symmetry is not respected, and the frequency is set in radians in the range from before .

Arguments

Input arguments

# h — frequency response

+ vector

Details

Frequency response, defined as a vector.

# w — angular frequencies

+ vector

Details

The angular frequencies at which the argument is calculated h, set as a vector.

# n,m — desired order

+ scalars

Details

The desired orders of the polynomials in the numerator and denominator, given as positive integers.

# wt — weight coefficients

+ vector

Details

The weight coefficients specified as a vector. Vector of weight coefficients wt has the same length as the vector w.

# iter — the number of iterations in the search algorithm

+ scalar

Details

The number of iterations in the search algorithm, given as a positive real scalar. Argument iter specifies functions invfreqz finish the iteration when the solution comes together, or after iter iterations, depending on what happens first.

# tol — tolerance

+ 0.01 (by default) | scalar

Details

The tolerance is set as a scalar. Function invfreqz defines convergence as the occurrence of the moment when the norm of the (modified) gradient vector is less than the value of the argument tol.

To get a vector of weighting coefficients consisting of one unit, use

invfreqz(h, w, n, m, [], iter, tol)

Output arguments

# b,a are the coefficients of the transfer function

+ vectors

Details

The coefficients of the transfer function returned as vectors. The transfer function is expressed in terms of b and a as follows:

Типы данных

Float64, Float32

Support for complex numbers

Yes

Examples

Stable approximate transfer function

Details

We convert a simple transfer function into frequency response data, and then back to the original filter coefficients.

import EngeeDSP.Functions: freqz, invfreqz

a = [1 2 3 2 1 4]
b = [1 2 3 2 3]

h, w = freqz(b, a, 64)
bb, aa = invfreqz(h, w, 4, 5)
println("bb = ", bb, "\naa = ", aa)
bb = [1.000000000000525 1.9999999999978302 2.9999999999980442 1.999999999998664 2.9999999999957274]
aa = [1.0 1.9999999999999936 2.999999999994893 1.9999999999994074 1.0000000000005878 3.9999999999943077]

Let’s draw the zeros and poles of the function, and add a unit circle for clarity.

import Pkg
Pkg.add("ControlSystems")
using ControlSystems

H = tf(vec(bb), vec(aa))
z, p = tzeros(H), poles(H)

pzmap(H)
annotate!([(real(zi)+0.1, imag(zi), text("Zero", 8)) for zi in z])
annotate!([(real(pi)+0.1, imag(pi), text("Pole", 8)) for pi in p])

θ = range(0, 2π, length=200)
plot!(cos.(θ), sin.(θ),
      ls=:dash, color=:black,
      label="Unit Circle", aspect_ratio=:equal,
      xlabel="Real Part", ylabel="Imaginary Part")

display(plot!())

invfreqz 1

Variables bb and aa are equivalent to b and a accordingly. However, the system is unstable because it has poles outside the unit circle. We use the iterative algorithm of the function invfreqz to find a stable approximation to the system.

bbb, aaa = invfreqz(h, w, 4, 5, [], 30)
println("bbb = ", bbb, "\naaa = ", aaa)
bbb = [0.24268035528110668 0.27880314196742667 0.006865008205357481 0.09712543692553093 0.19804400564173713]
aaa = [1.0 -0.8943888916069611 0.6953713986167904 0.9997072238456083 -0.8932896310322123 0.6949656991019518]

Let’s make sure that the poles are inside the unit circle.

H = tf(vec(bbb), vec(aaa))
z, p = tzeros(H), poles(H)

pzmap(H)

θ = range(0, 2π, length=200)
plot!(cos.(θ), sin.(θ),
      ls=:dash, color=:black,
      label="Unit Circle", aspect_ratio=:equal,
      xlabel="Real Part", ylabel="Imaginary Part")

display(plot!())

invfreqz 2

Algorithms

The default function is invfreqz uses the error equation method to determine the best model based on the data. This method finds b and a in

by creating a system of linear equations and solving them using the left division operator \. Here and — Fourier transforms of polynomials a and b accordingly, on the frequency , and — number of frequency points (length of vectors h and w). This algorithm is based on the work of Levi [1].

A more efficient (based on the "exit error") algorithm uses the Gauss method. — Newton with attenuation for iterative search [2], while the output of the first algorithm is used as an initial estimate. This solves the direct problem of minimizing the weighted sum of squared errors between the actual and desired frequency response points.

Literature

  1. Levi, E. C. «Complex-Curve Fitting.» IRE Transactions on Automatic Control. Vol. AC-4, 1959, pp. 37–44.

  2. Dennis, J. E., Jr., and R. B. Schnabel. Numerical Methods for Unconstrained Optimization and Nonlinear Equations. Englewood Cliffs, NJ: Prentice-Hall, 1983.