// adaptive filter : predictor
//
//       +-------------------------+ d
//       |                         |
//       |                         v +
//  x ---+                   ^    (+)---+---> e
//       |                   |     ^ -  |
//       |    +-------+    +---+   |    |
//       +--->| delay +--->| w +---+    |
//            +-------+ zx +---+ y      |
//                           |          |
//                           +----------+

clear;
stacksize('max');

DATLEN=10000;                                    // simulation data length
FLTLEN=100;                                      // filter length
DLYLEN=5;                                        // delay length
MU=0.0001;                                       // step size parameter

rand('normal');                                  // Gaussian noise mode
indata=0.5*rand(1:DATLEN);                       // generate noise
indata=indata+sin(2*%pi/45.6*(1:DATLEN));        // add sinusoidal signal
indata=indata+cos(2*%pi/67.8*(1:DATLEN));        // add sinusoidal signal

out_e=zeros(1:DATLEN);
out_y=zeros(1:DATLEN);

delay=zeros(1:DLYLEN);
xbuf=zeros(1:FLTLEN);
w=zeros(1:FLTLEN);

for i=1:DATLEN
    
  x=indata(i);
  d=x;
    
  zx=delay(DLYLEN);
  delay=[x, delay(1:DLYLEN-1)];

  xbuf=[zx, xbuf(1:FLTLEN-1)];
  y=xbuf*w';
  e=d-y;
  w=w+2*MU*e*xbuf;
  
  out_e(i)=e;
  out_y(i)=y;
    
end

scf(0); clf; plot2d(w);
scf(1); clf; plot2d(indata);
scf(2); clf; plot2d(out_e);
scf(3); clf; plot2d(out_y);

scf(4);
clf;
plot2d(indata(floor(0.95*DATLEN):DATLEN), style=3);
plot2d(out_y(floor(0.95*DATLEN):DATLEN), style=5);


