Переглянути джерело

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

master
kevin 8 роки тому
джерело
коміт
62f708f04b
2 змінених файлів з 39 додано та 25 видалено
  1. 31
    16
      cmProc5.c
  2. 8
    9
      cmProc5.h

+ 31
- 16
cmProc5.c Переглянути файл

@@ -959,9 +959,8 @@ cmRC_t      cmNlmsEcInit( cmNlmsEc_t* p, float mu, unsigned hN, unsigned delayN
959 959
   p->mu     = mu;
960 960
   p->hN     = hN;
961 961
   p->delayN = delayN;
962
-  p->wV     = cmMemResizeZ(cmSample_t,p->wV,hN);
963
-  p->hV     = cmMemResizeZ(cmSample_t,p->hV,hN);
964
-  p->dV     = cmMemResizeZ(cmSample_t,p->dV,delayN);
962
+  p->wV     = cmMemResizeZ(double,p->wV,hN);
963
+  p->hV     = cmMemResizeZ(double,p->hV,hN);
965 964
   p->w0i    = 0;
966 965
   
967 966
   return rc;
@@ -982,37 +981,53 @@ cmRC_t      cmNlmsEcFinal( cmNlmsEc_t* p )
982 981
 
983 982
 cmRC_t      cmNlmsEcExec( cmNlmsEc_t* p, const cmSample_t* xV, const cmSample_t* fV, cmSample_t* yV, unsigned xyN )
984 983
 {
984
+  // See: http://www.eit.lth.se/fileadmin/eit/courses/ett042/CE/CE2e.pdf
985
+  // and  http://www.eit.lth.se/fileadmin/eit/courses/ett042/CE/CE3e.pdf
985 986
   unsigned i;
986 987
   for(i=0; i<xyN; ++i)
987 988
   {
988
-    cmSample_t y = 0;
989
-    unsigned j;
990
-    unsigned k = 0;
991
-    float a = 0.00001;
992
-    
993
-    p->hV[p->w0i] = xV[i];
994
-    
989
+    double     y = 0;
990
+    unsigned   k = 0;
991
+    double     a = 0.001;
992
+    unsigned   j;
993
+
994
+    // insert the next sample into the filter delay line
995
+    p->hV[p->w0i] = xV[i]; 
996
+
997
+    // calculate the output of the delay w0i:hN
995 998
     for(j=p->w0i,k=0; j<p->hN; ++j,++k)
996 999
       y += p->hV[j] * p->wV[k];
997 1000
 
1001
+    // calcuate the output of the delay 0:w0i
998 1002
     for(j=0; j<p->w0i; ++j,++k)
999 1003
       y += p->hV[j] * p->wV[k];
1000 1004
 
1001
-    p->w0i = (p->w0i+1) % p->hN;
1002
-    
1003
-    float e = fV[i] - y;
1005
+    // calculate the error
1006
+    double e = fV[i] - y;
1007
+    yV[i] = e;
1004 1008
 
1005
-    cmSample_t z = 0;
1009
+    // 
1010
+    double z = 0;
1006 1011
     for(j=0; j<p->hN; ++j)
1007 1012
       z += p->hV[j] * p->hV[j];
1008 1013
 
1009
-    for(j=0; j<p->hN; ++j)
1010
-      p->wV[j] += p->mu/(a + z) * p->hV[j] * e;
1014
+    // update weights 0 through w0i
1015
+    for(j=p->w0i,k=0; j<p->hN; ++j,++k)
1016
+      p->wV[k] += (p->mu/(a + z)) * p->hV[j] * e;
1017
+
1018
+    // update weights w0i through hN
1019
+    for(j=0; j<p->w0i; ++j,++k)
1020
+      p->wV[k] += (p->mu/(a + z)) * p->hV[j] * e;
1021
+
1022
+    // advance the delay
1023
+    p->w0i = (p->w0i+1) % p->hN;
1024
+
1011 1025
   }
1012 1026
 
1013 1027
   return cmOkRC;
1014 1028
 }
1015 1029
 
1030
+
1016 1031
 cmRC_t      cmNlmsEcWrite( cmNlmsEc_t* p, const cmChar_t* dirStr )
1017 1032
 {
1018 1033
   if( p->eVa != NULL )

+ 8
- 9
cmProc5.h Переглянути файл

@@ -230,16 +230,15 @@ extern "C" {
230 230
   //
231 231
   typedef struct
232 232
   {
233
-    cmObj obj;
234
-    float           mu;        // LMS step rate
235
-    unsigned        hN;        // filter length
236
-    unsigned        delayN;    // fixed delay to apply to align xV with fV.
237
-    cmSample_t*     dV;        // delay line
238
-    cmSample_t*     wV;        // wV[hN] filter weights
239
-    cmSample_t*     hV;        // hV[hN] filter delay line
233
+    cmObj          obj;
234
+    float          mu;          // LMS step rate
235
+    unsigned       hN;          // filter length
236
+    unsigned       delayN;      // fixed delay to apply to align xV with fV.
237
+    double*        wV;          // wV[hN] filter weights
238
+    double*        hV;          // hV[hN] filter delay line
239
+    
240
+    unsigned       w0i;
240 241
     
241
-    unsigned        w0i;
242
-      
243 242
     cmVectArray_t* eVa;
244 243
   } cmNlmsEc_t;
245 244
 

Завантаження…
Відмінити
Зберегти