Overload List
| # | Signature | Description |
|---|---|---|
| 1 | void Bilinear(TVec *z, TVec *p, double &k, double FS = 2, bool AddZeros = true); | Compute bilinear transformation. |
| 2 | void Bilinear(TMtx *A, TVec *B, TVec *C, double &D, double FS = 2); | Apply bilinear transform to a linear system represented in state-space form. |
Overload 1: void Bilinear(TVec *z, TVec *p, double &k, double FS = 2, bool AddZeros = true);
Compute bilinear transformation.
Apply bilinear transform to transfer function represented in zero-pole form. FS defines the sampling frequency. If z.Length < p.Length the routine will not add zeroes at -1 to match the number of poles unless AddZeros is True.
Bilinear transformation is defined with the mapping: s -> 2/T (1 - z^(-1))/(1 + z^(-1)), T = 1/FS Bilinear transform requires that the amplitude response of a continuous system is piecewise constant and can not be used to transform an analog differentiator to a digital filter (for example). Bilinear transform also does not preserve the impulse or the phase response [1].
References:
[1] Theory and application of digital signal processing, Lawrence R. Rabiner and Bernard Gold. Prentice-Hall, 1975
#include "MtxExpr.h"
#include "Units.IIrFilters.h"
#include "Units.LinearSystems.h"
#include "Units.SignalUtils.h"
using namespace Dew;
using namespace Dew::Math;
using namespace Dew::Signal;
using namespace Dew::Signal::Units::IIRFilters;
using namespace Dew::Signal::Units::LinearSystems;
using namespace Dew::Signal::Units::SignalUtils;
void Example()
{
Vector z, p, num, den, Response, b, c;
int Order;
double k, Wc, d;
Matrix A;
Order = 5; //design a fifth order filter.
EllipticAnalog(Order, 0.2, 40, z, p, k); //design analog protype
//passband ripple 0.2dB, stopband attenuation 40dB
Bilinear(z, p, k, 2); //Sampling frequency = 2
Wc = 0.6; //request a cutoff at 0.6 Hz
LowpassToLowpassZ(z, p, k, Wc, BilinearUnwarp(1)); //frequency transformation in z-domain
ZeroPoleToTransferFun(num, den, z, p, k);
//Alternative 1:
// EllipticAnalog(Order, 0.2, 40, z, p, k); //design analog protype
// Bilinear(z, p, k, 2); //Sampling frequency = 2
// ZeroPoleToTransferFun(num, den, z, p, k);
// Wc = 0.6; //request a cutoff at 0.6 Hz
// LowpassToLowpassZ(num, den, Wc, BilinearUnwarp(1)); //frequency transformation in z-domain
//Alternative 2:
// EllipticAnalog(Order, 0.2, 40, z, p, k); //design analog protype
// Wc = BilinearPrewarp(0.6); //request a cutoff at 0.6 Hz
// LowpassToLowpass(z, p, k, Wc); //frequency transformation in s-domain
// Bilinear(z, p, k, 2); //Sampling frequency = 2
// ZeroPoleToTransferFun(num, den, z, p, k);
//Alternative 3:
// EllipticAnalog(Order, 0.2, 40, z, p, k); //design analog protype
// ZeroPoleToStateSpace(A, b, c, d, z, p, k);
// Wc = BilinearPrewarp(0.6); //request a cutoff at 0.6 Hz
// LowpassToLowpass(A, b, c, d, Wc); //frequency transformation in s-domain
// Bilinear(A, b, c, d, 2);
// StateSpaceToZeroPole(z, p, k, A, b, c, d);
// ZeroPoleToTransferFun(num, den, z, p, k);
FrequencyResponse(num, den, Response, 64); //zero padding set to 64
}
Overload 2: void Bilinear(TMtx *A, TVec *B, TVec *C, double &D, double FS = 2);
Apply bilinear transform to a linear system represented in state-space form.
#include "MtxExpr.h"
#include "Units.IIrFilters.h"
#include "Units.LinearSystems.h"
#include "Units.SignalUtils.h"
using namespace Dew;
using namespace Dew::Math;
using namespace Dew::Signal;
using namespace Dew::Signal::Units::IIRFilters;
using namespace Dew::Signal::Units::LinearSystems;
using namespace Dew::Signal::Units::SignalUtils;
void Example()
{
Vector z(0);
Vector p(0);
Vector num(0);
Vector den(0);
Vector Response(0);
Vector b(0);
Vector c(0);
double k, Wc, d;
Matrix A(0, 0);
double FS = 2;
int Order = 5; //design a fifth order filter.
EllipticAnalog(Order, 0.2, 40, z, p, k); //design analog protype
//passband ripple 0.2dB, stopband attenuation 40dB
Bilinear(z, p, k, FS, true); //Sampling frequency = 2
Wc = 0.6; //request a cutoff at 0.6 Hz
LowpassToLowpassZ(z, p, k, Wc, BilinearUnwarp(1, FS)); //frequency transformation in z-domain
ZeroPoleToTransferFun(num, den, z, p, k);
FrequencyResponse(num, den, Response, 64, false, TSignalWindowType::wtRectangular, 0); //zero padding set to 64
//Alternative 1:
EllipticAnalog(Order, 0.2, 40, z, p, k); //design analog protype
Bilinear(z, p, k, FS, true); //Sampling frequency = 2
ZeroPoleToTransferFun(num, den, z, p, k);
Wc = 0.6; //request a cutoff at 0.6 Hz
LowpassToLowpassZ(num, den, Wc, BilinearUnwarp(1, FS)); //frequency transformation in z-domain
FrequencyResponse(num, den, Response, 64, false, TSignalWindowType::wtRectangular, 0); //zero padding set to 64
//Alternative 2:
EllipticAnalog(Order, 0.2, 40, z, p, k); //design analog protype
Wc = BilinearPrewarp(0.6, FS); //request a cutoff at 0.6 Hz
LowpassToLowpass(z, p, k, Wc); //frequency transformation in s-domain
Bilinear(z, p, k, FS, true); //Sampling frequency = 2
ZeroPoleToTransferFun(num, den, z, p, k);
FrequencyResponse(num, den, Response, 64, false, TSignalWindowType::wtRectangular, 0); //zero padding set to 64
//Alternative 3:
EllipticAnalog(Order, 0.2, 40, z, p, k); //design analog protype
ZeroPoleToStateSpace(A, b, c, d, z, p, k);
Wc = BilinearPrewarp(0.6, FS); //request a cutoff at 0.6 Hz
LowpassToLowpass(A, b, c, d, Wc); //frequency transformation in s-domain
Bilinear(A, b, c, d, 2);
StateSpaceToZeroPole(z, p, k, A, b, c, d);
ZeroPoleToTransferFun(num, den, z, p, k);
FrequencyResponse(num, den, Response, 64, false, TSignalWindowType::wtRectangular, 0); //zero padding set to 64
}