cmProc5.h/c : Fixed bug in cmNlmsEcExec() where weight vector was not updated correctly.
This commit is contained in:
parent
afc70eae74
commit
62f708f04b
47
cmProc5.c
47
cmProc5.c
@ -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 )
|
||||||
|
17
cmProc5.h
17
cmProc5.h
@ -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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user