Skip to content

james34602/Open-DSP-Toolbox

Repository files navigation

Open Signal Processing Toolbox

Least square IIR filter design

Design IIR filter & system identification with least square based method in C

Compute L2 solution by iteratively solving overdetermined linear equations.

User must specify desired complex frequency response and initial weights to weight the error on frequency grid.

IIR filter design algorithm with equation error minimization method is written by Mathias C. Lang

Examples:

Passband linear phase low pass IIR filter

Diagram1

Passband linear phase band pass IIR filter

Diagram2

Passband linear phase arbitrary bands IIR filter

Diagram3

Group delay only IIR filter (Allpass filter)

Diagram4

Discussion

Frequency Domain Least Square vs Eqnerror

Both FDLS and eqnerror design digital filter take arbitrary frequency grid and gain vector as input.

From the filter designer's perspective, this property is very desirable.

Designers once had to craft frequency response equations on the s-plane and convert them to the z-plane using bilinear transform.

With FDLS or eqnerror, designers can convert their analogue frequency requirements to digital IIR filter directly without making their own equation.

FDLS method does a pretty good job at preserving the frequency response at high frequency of the analogue filter.

In my opinion, FDLS is an easy version of the Matched Z-transform, they both have potentials on designing filters that need to preserve frequency response around Nyquist, although they work in a completely different ways.

However, FDLS shouldn't be used if you have linear phase passband requirement, FDLS cannot handle abrupt changes in the desired response.

License and alternative

mldivide and matrix inversion related algorithm are the only part of the code that is generated by Matlab coder, however, I still decide to put GNU license on it, because the internal algorithm of generated mldivide do not work like Mathworks's implemented mldivide, the Matlab one is more complicated and numerically stable, Since a completely different algorithm is used to solve linear equations, I don't think there are any license violations.

Thanks to the fixed matrix dimension code generation, the generated mldivide function in C is pretty clean and readable.

However we need to add support for arbitrary matrix dimension, so the C version of mldivide has been heavily modified, many redundant memory allocation steps have been removed manually.

DO NOT RELY on Matlab generated code if you need computational efficiency!!! Matlab is a column-major order language, while we don't do that in most other programming languages.

If you don't like the mldivide, you can simply replace mldivide with following logic:

if is_square_matrix(A)
   return inv(A) * vector;
else
   return pinv(A) * vector;

However, I still encourage users to implement their mldivide using LAPACK. Matrix preconditioner may be available in some of their algorithms, making the solver more robust.

inv() can be implemented using LU decomposition or can be calculated using determinant.

pinv() is implemented using Singular value decomposition (SVD).

Neither mldivde or above method provides good numerical stability.

Mathworks documentation provides a good way to achieve good numerical stability in matrix inversion, but that is out-of-scope of this document.

General transfer function

Implemented function

cplxpair

Description

Sort the elements of a vector into complex conjugate pairs. The pairs are ordered by increasing real part. Real elements are placed after all complex pairs.

Use

What we know is that the correct algorithm will generate the correct answer, but roots computed by polynomial root finding algorithm is not guaranteed to be sorted. To make sure second-order section is grouped correctly, it is required for complex conjugate pairs to be grouped.

zp2sos

Description

Convert filter poles and zeros to second-order sections.

Use

Converts the zero-pole form into cascade form(SOS), result SOS will be ordered so the first row of SOS contains the poles farthest from the unit circle.

tf2sos

Description

Convert digital filter transfer function data into second-order sections form.

Algorithm:

  1. Calculate the z-plane of the transfer function
  2. Uses the function zp2sos, which first groups the zeros and poles into complex conjugate pairs using the cplxpair function. zp2sos then forms the second-order sections by matching the pole and zero pairs

Use

Convert high order transfer function into second-order biquads.

General maths function

cpoly

Description

Known as roots() in Matlab / Octave.

General-purpose complex root finder, the complex polynomial calculation is permitted.

Use

Wide range of polynomial root finding applications, for instance, digital filter stability check.

About

A special purpose signal processing toolbox for special IIR filter design and transfer function form conversion, written in C.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published