% function alpha_M = eflslbr_tv1(lambda,M,delta)

%%% Felix Albu

%%% Valahia University of Targoviste, Romania

%%% Email: felix.albu@valahia.ro

%%% http://falbu.50webs.com

% function alpha_M = eflslbr_tv1(lambda,M,delta) 

% 

% Implementation of the Recursive Least Squares Lattice (Recursive LSL)  

% adaption algorithm using a priori estimation errors and error 

% feedback. (Carezia version using a modified EF-LSL algorithm) 

% 

% use int2log and log2int routines 

% 

% lambda- Forgetting factor  

% delta- Small positive initialization constant 

% 

% alpha_M- A priori estimation error 

% 

% Felix Albu ---- Dublin ---- 10 October 2001 

F. Albu, J. Kadlec, N. Coleman, A. Fagan, "Pipelined Implementations of the A Priori Error-Feedback LSL Algorithm Using Logarithmic Number System", 

% Proceedings of ICASSP 2002, pp.2681-2684, Orlando, Florida, U.S.A

% felix_albu@ieee.org

%

% ------------------------------------------------------------------------------ 

% Set default values 

  

clear 

load ca2 

  

%load datagen 

%d=yy4; 

%u=yy6; 

%L = length(d); 

  

prec=23; 

  

L= 10; 

M = 5; 

  

d=mtlb_c(1:L); 

u=mtlb_d(1:L);

 

ufpga= (2^(23-prec))*fix((2^prec)* u);

u=fix((2^prec)* u)/((2^prec));

for k=1:L

lu(k)=int2log2(ufpga(k));

end

 

dfpga= (2^(23-prec))*fix((2^prec)* d);

d=fix((2^prec)* d)/((2^prec));

for k=1:L

ld(k)=int2log2(dfpga(k));

end

 

 

fd=d2sp(d);fu=d2sp(u);

 

lambda = 0.999;

flambda=d2sp(lambda);

llambda=d2logs(lambda);

 

teta=2^(-7);

fteta=d2sp(teta);

lteta=d2logs(teta);

 

delta = lambda*teta*(1-lambda);

fdelta=d2sp(delta);

ldelta=d2logs(delta);

 

sirm=d2logs(zeros(M,1));

 

% ------------------------------------------------------------------------------

% The initialisation. (variables at time n=0)

 

gamma_old = ones(M,1);

psi_old = zeros(M,1);

F_old = ones(M,1) .* delta;

B_old = ones(M,1) .* delta;

Gamma_f_old = zeros(M,1);

Gamma_b_old = zeros(M,1);

kappa_old = zeros(M,1);

bn_old = zeros(M,1);

bn = zeros(M,1);

 

fgamma_old = ones(M,1);

fpsi_old = zeros(M,1);

fF_old = d2sp(F_old); % fF for m=M-1 is not calculated

fB_old = d2sp(B_old);

fGamma_f_old = zeros(M,1);

fGamma_b_old = zeros(M,1);

fkappa_old = zeros(M,1);

fbn_old = zeros(M,1);

fbn = zeros(M,1);

 

lgamma_old = d2logs(gamma_old);

lpsi_old = sirm;

lF_old = d2logs(F_old);

lB_old = d2logs(B_old);

lGamma_f_old = sirm;

lGamma_b_old = sirm;

lkappa_old = sirm;

lbn_old = sirm;

lbn = sirm;

 

% ------------------------------------------------------------------------------

% Declare variables

 

gamma= ones(M,1);

psi= zeros(M,1);

F= F_old;

B= B_old;

Gamma_b= zeros(M,1);

Gamma_b= zeros(M,1);

kappa= zeros(M,1);

eta= zeros(M,1);

 

fgamma= ones(M,1);

fpsi= zeros(M,1);

fF= fF_old;

fB= fB_old;

fGamma_b= zeros(M,1);

fGamma_b= zeros(M,1);

fkappa= zeros(M,1);

feta= zeros(M,1);

 

lgamma= d2logs(gamma);

lpsi= sirm;

lF= lF_old;

lB= lB_old;

lGamma_b= sirm;

lGamma_b= sirm;

lkappa= sirm;

leta= sirm;

 

alpha_M = zeros(1,L);

falpha_M = zeros(1,L);

lalpha_M = d2logs(zeros(1,L));

 

% ------------------------------------------------------------------------------

% After the initialisation (for n>=1)

%

 

for n = 1:L

 

% Order initialization for each n>=1

 

gamma(1)= 1;fgamma(1) = 1;lgamma(1)= d2log(1);

 

eta (1)= u(n);psi(1) = u(n);

feta(1)= fu(n);fpsi(1) = fu(n);

leta (1)= lu(n);lpsi(1) = lu(n);

alpha= d(n);falpha = fd(n);lalpha= ld(n);

 

% Order update of the lattice filter

for mm=2:M

 

% Line (1)

eta(mm)= eta(mm-1) - Gamma_f_old(mm) * psi_old(mm-1);

feta (mm)= fsub(feta(mm-1) , fmul(fGamma_f_old(mm) , fpsi_old(mm-1)));

leta(mm)= lsub(leta(mm-1) , lmul(lGamma_f_old(mm) , lpsi_old(mm-1)));

 

 

% Line (2)

f = gamma_old(mm-1) * eta(mm-1);

ff = fmul(fgamma_old(mm-1), feta(mm-1));

lf = lmul(lgamma_old(mm-1), leta(mm-1));

 

 

% Line (3)

psi(mm)= psi_old(mm-1) - Gamma_b_old(mm) * eta(mm-1);

fpsi(mm)= fsub(fpsi_old(mm-1) , fmul(fGamma_b_old(mm) , feta(mm-1)));

lpsi(mm)= lsub(lpsi_old(mm-1) , lmul(lGamma_b_old(mm) , leta(mm-1)));

 

 

% Line (4)

b = gamma(mm-1) * psi(mm-1);

fb = fmul(fgamma(mm-1), fpsi(mm-1));

lb = lmul(lgamma(mm-1), lpsi(mm-1));

 

 

% Line (5)

alpha = alpha - kappa_old(mm) * psi(mm-1);

falpha = fsub(falpha , fmul(fkappa_old(mm) , fpsi(mm-1)));

lalpha = lsub(lalpha , lmul(lkappa_old(mm) , lpsi(mm-1)));

 

 

% Line (6)

Gamma_f(mm) = Gamma_f_old(mm) + bn_old(mm-1)*eta(mm);

fGamma_f(mm) = fadd(fGamma_f_old(mm) , fmul(fbn_old(mm-1), feta(mm)));

lGamma_f(mm) = ladd(lGamma_f_old(mm) , lmul(lbn_old(mm-1), leta(mm)));

 

 

% Line (7)

F(mm-1)= lambda * F_old(mm-1) + f*eta(mm-1) + teta;

fF(mm-1)= fadd(fadd(fmul(flambda , fF_old(mm-1)) , fmul(ff, feta(mm-1))), fteta);

lF(mm-1)= ladd(ladd(lmul(llambda , lF_old(mm-1)) , lmul(lf, leta(mm-1))), lteta);

 

% Line (8)

B(mm-1)= lambda * B_old(mm-1) + b*psi(mm-1) + teta;

fB(mm-1)= fadd(fadd(fmul(flambda , fB_old(mm-1)) , fmul(fb, fpsi(mm-1))), fteta);

lB(mm-1)= ladd(ladd(lmul(llambda , lB_old(mm-1)) , lmul(lb, lpsi(mm-1))), lteta);

 

 % Line (9)

fn = f/F(mm-1);

ffn = fdiv(ff, fF(mm-1));

lfn = ldiv(lf, lF(mm-1));

 

 

% Line (10)

bn(mm-1) = b/B(mm-1);

fbn(mm-1) = fdiv(fb, fB(mm-1));

lbn(mm-1) = ldiv(lb, lB(mm-1));

 

 

% Line (11)

Gamma_b(mm) = Gamma_b_old(mm) + fn*psi(mm);

fGamma_b(mm) = fadd(fGamma_b_old(mm) , fmul(ffn, fpsi(mm)));

lGamma_b(mm) = ladd(lGamma_b_old(mm) , lmul(lfn, lpsi(mm)));

 

 

% Line (12)

kappa(mm)= kappa_old(mm) + bn(mm-1)*alpha;

fkappa(mm)= fadd(fkappa_old(mm) , fmul(fbn(mm-1), falpha));

lkappa(mm)= ladd(lkappa_old(mm) , lmul(lbn(mm-1), lalpha));

 

 

% Line (13)

gamma(mm) = gamma(mm-1) - bn(mm-1)*b;

fgamma(mm)= fsub(fgamma(mm-1), fmul(fbn(mm-1), fb));

lgamma(mm)= lsub(lgamma(mm-1), lmul(lbn(mm-1), lb));

 

end

 

 

% Update output

 

alpha_M(n) = alpha;

falpha_M(n) = falpha;

lalpha_M(n)=log2int2(lalpha)/2^prec;

 

erlns(n)=alpha_M(n)-lalpha_M(n);

ersp(n)=alpha_M(n)-falpha_M(n);

 

% Update old values

gamma_old= gamma;

psi_old= psi;

F_old= F;

B_old= B;

Gamma_f_old = Gamma_f;

Gamma_b_old = Gamma_b;

kappa_old= kappa;

bn_old= bn;

 

fgamma_old= fgamma;

fpsi_old= fpsi;

fF_old= fF;

fB_old= fB;

fGamma_f_old = fGamma_f;

fGamma_b_old = fGamma_b;

fkappa_old= fkappa;

fbn_old= fbn;

 

lgamma_old= lgamma;

lpsi_old= lpsi;

lF_old= lF;

lB_old= lB;

lGamma_f_old = lGamma_f;

lGamma_b_old = lGamma_b;

lkappa_old= lkappa;

lbn_old= lbn;

 

end

 

ssl=0;ssf=0;

sl=zeros(L,1);sf=zeros(L,1);

 

for i=1:L,

ssl=ssl+abs(erlns(i)); sl(i)=ssl;

ssf=ssf+abs(ersp(i)); sf(i)=ssf;

end;

 

 

fid=fopen('.\Debug\input.dat','w'); % The Handel C input file

fprintf(fid, '%d\n', L);

fprintf(fid, '%d\n', M);

fprintf(fid, '%d\n', ldelta);

fprintf(fid, '%d\n', llambda);

fprintf(fid, '%d\n', lteta);

for i=1:L

fprintf(fid,'%d\n', ufpga(i));

fprintf(fid,'%d\n', dfpga(i));

end

fclose(fid);

 

%

% ======================== end of file writing ====================

HC_JOB='handelc -s -ss 1000 eflslbr_tv1.c';

!del outfpga.dat

dos('del input.dat');

dos('copy .\Debug\input.dat input.dat');

 

dos(HC_JOB);

 

load outfpga.dat

 

r=outfpga-lalpha_M'*2^23;

if sum(r)==0

disp(['test is OK']);

end;

 

 

 

 

 

/*------------------------------------------------------
eflslbr01.c: 10.10.2001(on chip RAM) 
 
LOG LATTICE RECURSIVE LEAST-SQUARES 
 A PRIORI ERROR FEEDBACK ALGORITHM (CAREZIA's version) 
 
it takes the initial varibles values from the file input.dat
returns the output errors (LOG) in outfpga.dat
 
 Contact information: 
 
 felix_albu@ieee.org 
*/
 
#define PP1000_32BIT_RAMS
#define PP1000_DIVIDE1
#define PP1000_CLOCK PP1000_MCLK
#include "Pp1000.h"
#include <stdlib.h>
#include "stdlib.c"
 
set part = "V2000BG560-6";
 
#include "lalu.h"
 
int 32 idk, iuk, ialpha, luk, ldk, ldelta, llambda, lf, lb, lfn, leta, lalpha;
int 32ltemp3, ltemp1, ltemp2, ltemp4, ltemp5, ltemp6, ltemp7, ltemp8, ltemp9, ltemp10, ltemp11;
ram int 32 lgamma_old[16], lpsi_old[16], lF_old[16], lB_old[16], lGamma_f_old[16], lGamma_b_old[16], lkappa_old[16];
ram int 32 lgamma[16], lbn[16], lpsi[16], lF[16], lB[16], lGamma_b[16], lGamma_f[16], lkappa[16], lbn_old[16];
unsigned 4 lM1, lj;
unsigned 16 lindex;
unsigned 16 lL1;
int 32 lM, lL;
 
 
macro proc eflatice()
{
 
 par
 {
 ltemp1=lm(lGamma_f_old[lj], lpsi_old[lj-1]); // ltemp1=Gamma_f_old(mm) * psi_old(mm-1);
 lf = lm(lgamma_old[lj-1], leta[lj-1]); // (2) !!!!! f = gamma_old(mm-1) * eta(mm-1);
 ltemp2= lm(lGamma_b_old[lj],leta[lj-1]);// ltemp2=Gamma_b_old(mm) * eta(mm-1);
 lb = lm(lgamma[lj-1], lpsi[lj-1]); // (4) !!!!! lb=gamma(mm-1) * psi(mm-1)
 ltemp3= lm(lkappa_old[lj],lpsi[lj-1]);// ltemp3=kappa_old(mm) *psi(mm-1);
 }
 
 par
 {
 lsub(leta[lj-1], ltemp1, leta[lj]); // (1)!!! eta(mm)= eta(mm-1) + Gamma_f_old(mm) * psi_old(mm-1);
 {
 ltemp7= lm(lb, lpsi[lj-1]); // ltemp7= b*psi(mm-1)
 }
 }
 
 par
 {
 lsub(lpsi_old[lj-1], ltemp2, lpsi[lj]);// (3) !!!!!!! psi(mm) = psi_old(mm-1) - Gamma_b_old(mm) * eta(mm-1);
 {
 ltemp6= lm(lf, leta[lj-1]); // ltemp6= f*eta(mm-1)
 ltemp8= lm(lbn_old[lj-1], leta[lj]);// ltemp8= bn_old(mm-1)*eta(mm);
 ltemp4= lm(llambda, lF_old[lj-1]); // ltemp4=lambda * F_old(mm-1); 
 ltemp5= lm(llambda, lB_old[lj-1]); // ltemp5=lambda * B_old(mm-1);
 }
 }
 
 lsub(lalpha, ltemp3, lalpha); //(5) !!!! alpha = alpha - kappa_old(mm) *psi(mm-1);
 ladd(lGamma_f_old[lj], ltemp8, lGamma_f[lj]); // (6) !!! Gamma_f(mm) = Gamma_f_old(mm) + bn_old(mm-1)*eta(mm);
 
 ladd(ltemp4, ltemp6, ltemp10); 
  ladd(ltemp10, lteta, lF[lj-1]); // (7) !!F(mm-1)= lambda * F_old(mm-1) + f*eta(mm-1) + teta;
 ladd(ltemp5, ltemp7, ltemp11); 
 ladd(ltemp11, lteta, lB[lj-1]); // (8) !!B(mm-1)= lambda * B_old(mm-1) + b*psi(mm-1) + teta;
 
 par
 {
 lfn= ld(lf, lF[lj-1]); // (9) !!!! fn = f/F(mm-1);
 lbn[lj-1]= ld(lb, lB[lj-1]); // bn(mm-1) = b/B(mm-1);
 }
 
 ltemp9= lm(lbn[lj-1], lb); // ltemp9=bn(mm-1)*b;
 
 par
 {
 lsub(lgamma[lj-1], ltemp9, lgamma[lj]); // (13) !! gamma(mm) = gamma(mm-1) - bn(mm-1)*b;
 {
 ltemp12= lm(lfn, lpsi[lj]); // ltemp4= fn(mm-1)*psi(mm);
 ltemp13= lm(lbn[lj-1], lalpha); // ltemp5= bn(mm-1)*alpha;
 }
 }
 
 ladd(lGamma_b_old[lj], ltemp12, lGamma_b[lj]);// (11) !! Gamma_b(mm) = Gamma_b_old(mm) + fn*psi(mm);
 ladd(lkappa_old[lj], ltemp13, lkappa[lj]); // (12) !!kappa(mm)= kappa_old(mm) + bn(mm-1)*alpha;
 
}
 
 
 
void main(void)
{  
 lL=pc2alg();
 lM=pc2alg();
 ldelta=pc2alg();
 llambda=pc2alg();
 lteta=pc2alg();
 
 par
 {
 lM1=(unsigned 4)lM[3:0];
 lL1=(unsigned 16)lL[15:0];
 }
 
 for (lj=0; lj<lM1; lj=lj+1)
 {
 par
 {
 lgamma_old[lj]=(int 32)0;
 lpsi_old[lj]=ZERO_LNSALU;
 lB_old[lj]=ldelta;
 lF_old[lj]=ldelta;
 lGamma_b_old[lj]=ZERO_LNSALU;
 lGamma_f_old[lj]=ZERO_LNSALU;
 lkappa_old[lj]=ZERO_LNSALU;
 lgamma[lj]=(int 32)0;
 lbn[lj]=ZERO_LNSALU;
 lpsi[lj]=ZERO_LNSALU;
 lB[lj]=ldelta;
 lF[lj]=ldelta;
 lGamma_b[lj]=ZERO_LNSALU;
 lGamma_f[lj]=ZERO_LNSALU;
 lkappa[lj]=ZERO_LNSALU;
 lbn_old[lj]=ZERO_LNSALU;
 }
 }
 
 
 for (lindex=0; lindex<lL1; lindex=lindex+1)
 {
 
iuk=pc2alg();
 luk=int2log(iuk);
idk=pc2alg();
 ldk=int2log(idk);
 
 par
 {
 lgamma[0]=(int 32)0;
 leta=luk;
 lpsi[0]=luk; 
 lalpha=ldk;
 }
 
 for (lj=1; lj<lM1; lj=lj+1)// ciclu lj 
 eflatice();
 
 par
 {
 ialpha=log2int(lalpha);
 {
 for (lj=0; lj<lM1; lj=lj+1)
 {
 par
 {
 lgamma_old[lj]=lgamma[lj];
 lpsi_old[lj]=lpsi[lj];
 lF_old[lj]=lF[lj];
 lB_old[lj]=lB[lj];
 lGamma_f_old[lj]=lGamma_f[lj];
 lGamma_b_old[lj]=lGamma_b[lj];
 lkappa_old[lj]=lkappa[lj];
 lbn_old[lj]=lbn[lj];
 }
 }
 }
 
 }
 
 alg2pc(ialpha);
 
 } // end program EFLSL (simplified version)