! FIR Filter design optimization (FIRfilterLin.lng)
In a FIR((Finite Impulse Response) filter, the
output at time t, y(t), is related to the inputs, x(t), by:
y(t) = h(0)*x(t) + h(1)*x(t-1) + ... + h(n)*x(t-n).
We specify two frequency intervals, a pass-band where we want the
frequencies to be preserved/passed, and a stop-band, where we want
the frequencies to be attenuated;
! Ref: M.S. Lobo, L. Vandenberghe, S. Boyd, and H. Lebret, 1998,
"Applications of Second-Order Cone Programming",
Linear Algebra and its Applications, vol. 284, pp. 193-228;
! Keywords: FIR Filter, DSP, Digital Signal Processing,
Finite Impulse Response;
SETS:
LAGSET: h;
ANGLE: Response, Omega;
ENDSETS
DATA:
N2 = 10; ! Number of lags;
NFREQ = 180; ! Frequency sample points;
LAGSET = 1..N2;
ANGLE = 1..NFREQ;
beta = 0.01; ! Attenuation target in stopband interval;
ENDDATA
SUBMODEL FirLinear:
min = t; ! Minimize deviation from target of 1 in Pass band;
@FOR( lagset(k):
@free( h(k)); ! The weights can be < 0;
);
! Compute the response at each frequency i;
@FOR( ANGLE(i):
Omega(i) = (i-1)*pie/180; ! Measure response at these angles;
@FREE( Response(i));
Response(i) = 2*@SUM( LAGSET(k): h(k)*@COS((k-n2-1/2)*omega(i)));
);
! In the Pass band we want 2*Response to be close to 1;
@FOR( ANGLE(i) | omega(i) #LE# omega_pass:
1-t <= Response(i);
Response(i) <= 1+t;
);
! In the Stop band we want Response to be close to 0;
@FOR( ANGLE(i) | omega(i) #GE# omega_stop:
-2*beta <= Response(i);
Response(i) <= 2*beta;
);
ENDSUBMODEL
CALC:
@SET( 'TERSEO',2); ! Output level (0:verb, 1:terse, 2:only errors, 3:none);
@SET( 'SCALEW',0); ! Suppress scaling warning;
pie = @PI();
omega_pass = pie/2; ! The end of the pass band;
omega_stop = 2*pie/3; ! The start of the stop band;
@SOLVE( FirLinear);
@WRITE(@NEWLINE(1),
'Design of FIR Filter with Pass band= 0 to ',@FORMAT(omega_pass,'6.4f'),', Stop band = ',
@FORMAT( omega_stop, '6.4f'),' to PI()',@NEWLINE(1));
@WRITE(' Lag Weight', @NEWLINE(1));
@FOR( LAGSET(k):
@WRITE( @FORMAT( k-1, '7.0f'),' ', @FORMAT(h(k), '8.4f'),@NEWLINE(1));
);
@CHARTCURVE(
'Response Curve for FIR Filter: Pass band=(0,'
+ @FORMAT(omega_pass,'4.2f')
+ '), Stop band=('
+ @FORMAT(omega_stop,'4.2f')
+ ', 3.1416)',
'Angle/Frequency', 'Response', ' ', omega, response);
ENDCALC
|