/*************************************/
/**
Introduction
**/
/*************************************/
This explains how to
use digital filters in FUNC_X codes.
Updated on January 10, 2006,
e2e-3.1.1
/*************************************/
/**
HOW TO USE
**/
/*************************************/
/**
likes with >> is
the code to be added in FUNC_X
(1) in MemberCecl
>> DF
aFilter;
(2) in Constructor
>>
aFilter.addKZPHz( xxx );
or using any other
functions defining gain, zeros and ppoles
To set the initial
condition or to force quad, use
>>
aFilter.initCondition( x0, v0 ); aFilter.forcceQuad();
To printout various
information, use
>>
printAandB or printKZP
(3) in equation
to apply filter
>>
aFilter.filterApply( input );
to reset the filter,
>>
aFilter.filterReset();
**/
/*************************************/
/**
MAIN FUNCTIONS **/
/*************************************/
/** returns the current
output using cascaded direct form II second order sections **/
adlib_real filterApply( const
adlib_real inputNow );
/** force to reset the
filter to the initial state **/
void filterReset( void );
/* conditional reset */
bool filterReset( const adlib_real
resetSig_arg, adlib_real *outputVal = 0 );
/** set the initial
condition and velocity.
filterApply(0)
= y0
filterApply(1)
= y0 + velocity * delT
**/
void initCondition( adlib_real y0,
adlib_real velocity );
/** force to use quad
**/
void forceQuad( void );
/** print A and B of
SOS sections to output stream */
void printAandB( ostream *strm, const
string &msg = "" );
/** print s domain
zeros and poles. If forMatlab is true, it generates an expression which can be
pasted in matlab directly. */
void printKZP( ostream *strm, const
string &msg = "", const bool forMatlab = false );
/** calculate the
complex transfer function */
adlib_complex transferFunc( const
adlib_real freq, const bool digital = true ) const;
/** set the name of the
filter. Useful for debugging */
void setName( const string name_arg ) {
name = name_arg; };
/** dynamic safety
limit. range 0 is off */
void
setDynamicRange( const adlib_real range_arg = 1e12 );
/*************************************/
/**
SETTING GAINS, ZEROS AND POLES **/
/*************************************/
/** multiply gain by
gain and add zeros and poles to the existing filter */
bool addKZP
( const adlib_real gain =
1,
const size_t
numZeros = 0, const adlib_real *zeros = NULL,
const size_t
numPoles = 0, const adlib_real *poles = NULL,
const size_t
numZeroPairs = 0, const adlib_complex *zeroPairs = NULL,
const size_t
numPolePairs = 0, const adlib_complex *polePairs = NULL );
/** multiply gain by
gain and add zeros and poles to the existing filter */
/** zeros and poles are
specified in degree / Hz
*/
/** addKZPHz( pole,
zero) = addKZP( -2 Pi pole, -2 Pi zero )
*/
bool addKZPHz
( const adlib_real gain =
1,
const size_t
numZeros = 0, const adlib_real *zeros = NULL,
const size_t
numPoles = 0, const adlib_real *poles = NULL,
const size_t
numZeroPairs = 0, const adlib_complex *zeroPairs = NULL,
const size_t numPolePairs
= 0, const adlib_complex *polePairs = NULL );
/** multiply gain by
gain and add zeros and poles to the existing filter */
/** zeros and poles are
specified in degree / Hz
*/
/** complex pairs are
specified by Q, instead of using a complex number */
/** (re, im) = -2 Pi
freq / ( 2 Q ) { 1, sqrt( 4 Q^2 - 1 ) }
*/
/** When Q <
0.5, pole (zero) pair becomes a simple pile (not pair) */
/** This is to use
one expression for both a complex pole and a pole */
bool addKZPHzQ
( const adlib_real gain =
1,
const size_t
numZeros = 0,
const
adlib_real *zeros = NULL, const adlib_real *zeroQs = NULL,
const size_t
numPoles = 0,
const
adlib_real *poles = NULL, const adlib_real *poleQs = NULL );
/** Set the gain factor
*/
void setGain( adlib_real gain) {
dfRec.coef[0] = gain; gainS = gain; calcAB();};
/** Set the gain at a
given frequency */
void setGainHz( adlib_real gain,
adlib_real freq );
/** Add to the zero vector */
bool addZero( const adlib_real zero );
bool addZeroHzQ( const adlib_real zero,
const adlib_real zeroQ );
/** Add to the pole vector */
bool addPole( adlib_real pole);
bool addPoleHzQ( const adlib_real pole,
const adlib_real poleQ );
/** Add to the zero pair vector */
bool addZeroPair( adlib_complex
zeroPair );
bool addZeroPair( adlib_real zero_real,
adlib_real zero_imag );
/** Add to the pole pair vector */
bool addPolePair( adlib_complex
polePair );
bool addPolePair( adlib_real pole_real,
adlib_real pole_imag );
/**********************************************/
/**
VARIOUS SPECIAL FILTERS
**/
/**
to setup the filter
**/
/**
DF aFilter;
**/
/**
aFilter.calcAB_xxx( TIME_STEP, params ); **/
/**********************************************/
bool calcAB_buttap( const adlib_real
delT_arg,
const size_t
order,
const
adlib_real cutoffFreq,
const
adlib_real gain_arg,
const bool
isLowPass = true );
bool calcAB_cheb1ap( const adlib_real
delT_arg,
const
size_t order,
const
adlib_real cutoffFreq,
const
adlib_real ripple,
const
adlib_real gain_arg,
const
bool isLowPass = true );
bool calcAB_cheb2ap( const adlib_real
delT_arg,
const
size_t order,
const
adlib_real cutoffFreq,
const
adlib_real ripple,
const
adlib_real gain_arg,
const
bool isLowPass = true );
bool calcAB_elliptic( const adlib_real
delT_arg,
const
size_t order,
const
adlib_real cutoffFreq,
const
adlib_real passbandRipple,
const
adlib_real stopbandRipple,
const
adlib_real gain_arg,
const
bool DCUnitGain = true,
const
bool isLowPass = true );
bool calcAB_AntFilter( const adlib_real
delT_arg,
const adlib_real nyquestLow,
const adlib_real nyquestHigh );
/*** How to use calcAB_XXX in FUNC_X ***/
in MemberDecl
DF cheby;
DF
butter;
DF elliptic;
in Constructor
adlib_real
gain = 100;
adlib_real cutHz = 10;
adlib_real pR = 0.5;
adlib_real
sR = 20;
cheby.calcAB_cheb1ap(
TIME_STEP, 4, cutHz, pR, gain );
butter.calcAB_buttap(TIME_STEP, 4, cutHz,
gain );
elliptic.calcAB_elliptic(TIME_STEP, 6, cutHz, pR, sR, gain );
in Equation
out0 =
cheby.filterApply(in0);
out1 = butter.filterApply(in0);
out2 =
elliptic6.filterApply(in0);