! 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