cmProc5.h/c : Fixed bug in cmNlmsEcExec() where weight vector was not updated correctly.

This commit is contained in:
kevin 2015-08-26 19:37:52 -04:00
parent afc70eae74
commit 62f708f04b
2 changed files with 39 additions and 25 deletions

View File

@ -959,9 +959,8 @@ cmRC_t cmNlmsEcInit( cmNlmsEc_t* p, float mu, unsigned hN, unsigned delayN
p->mu = mu; p->mu = mu;
p->hN = hN; p->hN = hN;
p->delayN = delayN; p->delayN = delayN;
p->wV = cmMemResizeZ(cmSample_t,p->wV,hN); p->wV = cmMemResizeZ(double,p->wV,hN);
p->hV = cmMemResizeZ(cmSample_t,p->hV,hN); p->hV = cmMemResizeZ(double,p->hV,hN);
p->dV = cmMemResizeZ(cmSample_t,p->dV,delayN);
p->w0i = 0; p->w0i = 0;
return rc; return rc;
@ -982,37 +981,53 @@ cmRC_t cmNlmsEcFinal( cmNlmsEc_t* p )
cmRC_t cmNlmsEcExec( cmNlmsEc_t* p, const cmSample_t* xV, const cmSample_t* fV, cmSample_t* yV, unsigned xyN ) cmRC_t cmNlmsEcExec( cmNlmsEc_t* p, const cmSample_t* xV, const cmSample_t* fV, cmSample_t* yV, unsigned xyN )
{ {
// See: http://www.eit.lth.se/fileadmin/eit/courses/ett042/CE/CE2e.pdf
// and http://www.eit.lth.se/fileadmin/eit/courses/ett042/CE/CE3e.pdf
unsigned i; unsigned i;
for(i=0; i<xyN; ++i) for(i=0; i<xyN; ++i)
{ {
cmSample_t y = 0; double y = 0;
unsigned j; unsigned k = 0;
unsigned k = 0; double a = 0.001;
float a = 0.00001; unsigned j;
p->hV[p->w0i] = xV[i]; // insert the next sample into the filter delay line
p->hV[p->w0i] = xV[i];
// calculate the output of the delay w0i:hN
for(j=p->w0i,k=0; j<p->hN; ++j,++k) for(j=p->w0i,k=0; j<p->hN; ++j,++k)
y += p->hV[j] * p->wV[k]; y += p->hV[j] * p->wV[k];
// calcuate the output of the delay 0:w0i
for(j=0; j<p->w0i; ++j,++k) for(j=0; j<p->w0i; ++j,++k)
y += p->hV[j] * p->wV[k]; y += p->hV[j] * p->wV[k];
p->w0i = (p->w0i+1) % p->hN; // calculate the error
double e = fV[i] - y;
float e = fV[i] - y; yV[i] = e;
cmSample_t z = 0; //
double z = 0;
for(j=0; j<p->hN; ++j) for(j=0; j<p->hN; ++j)
z += p->hV[j] * p->hV[j]; z += p->hV[j] * p->hV[j];
for(j=0; j<p->hN; ++j) // update weights 0 through w0i
p->wV[j] += p->mu/(a + z) * p->hV[j] * e; for(j=p->w0i,k=0; j<p->hN; ++j,++k)
p->wV[k] += (p->mu/(a + z)) * p->hV[j] * e;
// update weights w0i through hN
for(j=0; j<p->w0i; ++j,++k)
p->wV[k] += (p->mu/(a + z)) * p->hV[j] * e;
// advance the delay
p->w0i = (p->w0i+1) % p->hN;
} }
return cmOkRC; return cmOkRC;
} }
cmRC_t cmNlmsEcWrite( cmNlmsEc_t* p, const cmChar_t* dirStr ) cmRC_t cmNlmsEcWrite( cmNlmsEc_t* p, const cmChar_t* dirStr )
{ {
if( p->eVa != NULL ) if( p->eVa != NULL )

View File

@ -230,16 +230,15 @@ extern "C" {
// //
typedef struct typedef struct
{ {
cmObj obj; cmObj obj;
float mu; // LMS step rate float mu; // LMS step rate
unsigned hN; // filter length unsigned hN; // filter length
unsigned delayN; // fixed delay to apply to align xV with fV. unsigned delayN; // fixed delay to apply to align xV with fV.
cmSample_t* dV; // delay line double* wV; // wV[hN] filter weights
cmSample_t* wV; // wV[hN] filter weights double* hV; // hV[hN] filter delay line
cmSample_t* hV; // hV[hN] filter delay line
unsigned w0i;
unsigned w0i;
cmVectArray_t* eVa; cmVectArray_t* eVa;
} cmNlmsEc_t; } cmNlmsEc_t;