Lindo Systems

! 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