00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "wavelet.h"
00022 #include <gsl/gsl_wavelet.h>
00023 #include <gsl/gsl_statistics.h>
00024 #include <gsl/gsl_sort.h>
00025 #include <math.h>
00026 #include <float.h>
00027 #include <limits.h>
00028 #include <stdarg.h>
00029 #include <string.h>
00030 #include "helper.h"
00031 #include "mathadd.h"
00032 #include "eeg.h"
00033
00034
00040 double translation_invariant_thresholding(const double *data, int n){
00041 dprintf("Db: translation_invariant_thresholding\n");
00042 double sigma, lambda;
00043
00044 sigma = mad(data, n)/0.6745;
00045 lambda = sigma * sqrt(2*log(n*glog(n, 2)));
00046 return lambda;
00047 }
00048
00054 double conventional_thresholding(const double *data, int n){
00055 dprintf("Db: conventional_thresholding\n");
00056 double sigma, lambda;
00057
00058 sigma = mad(data,n)/0.6745;
00059 lambda = sigma * sqrt(2*log(n));
00060 return lambda;
00061 }
00062
00078 double heuristic_sure(const double *data, int n){
00079 dprintf("Db: heuristic_sure\n");
00080 double hthr, etat, crit;
00081 hthr = sqrt(2*log(n));
00082 etat = (pow(vnorm(data, n, 2), 2)-n)/(double)n;
00083 crit = pow((log(n)/log(2)), 1.5)/sqrt(n);
00084 if(etat < crit)
00085 return hthr;
00086 else
00087 return fmin(sureshrink(data, n), hthr);
00088 }
00089
00094 double sureshrink(const double *data, int n){
00095 int i,k;
00096 double lambda, sigma, sure, suremin;
00097 double *tmp;
00098 dprintf("Db: sureshrink\n");
00099
00100 tmp = (double*)malloc(n*sizeof(double));
00101 sigma = mad(data, n)/0.6745;
00102
00103 for(i=0; i<n; i++)
00104 tmp[i] = fabs(data[i])/sigma;
00105
00106
00107
00108 suremin = DBL_MAX;
00109 qsort(tmp, n, sizeof(double), abscmp);
00110
00111 lambda=0.0;
00112 for(k=0; k<n; k++){
00113 sure = n - 2*(k+1)+(n-k)*pow(fabs(tmp[k]), 2);
00114 for(i=0; i<k; i++)
00115 sure = sure + pow(fabs(tmp[i]), 2);
00116 if(sure<suremin){
00117 suremin = sure;
00118 lambda = fabs(tmp[k]);
00119 }
00120 }
00121 lambda = sigma * lambda;
00122
00123 free(tmp);
00124 return lambda;
00125 }
00126
00133 int wavelet_denoise ( double *data, int n, WaveletParameters P ){
00134 gsl_wavelet *w;
00135 gsl_wavelet_workspace *work;
00136 int j, J, k, offset;
00137 double lambda;
00138 dprintf("Db: generic_denoising\n");
00139
00140 w = gsl_wavelet_alloc( P.wavelet, P.vanishing_moments );
00141 work = gsl_wavelet_workspace_alloc( n );
00142
00143 gsl_wavelet_transform_forward( w, data, 1, n, work );
00144
00145
00146 J = (int)round(glog((double)n, 2));
00147 for(j=P.first_thresholding_level; j<J; j++){
00148 offset = (int)pow(2, j);
00149 lambda = (*(P.threshselfct))(&(data[offset]), offset);
00150
00151 for(k=offset; k<2*offset; k++){
00152
00153 data[k]=(*(P.threshfct))(data[k], lambda);
00154 }
00155 }
00156
00157
00158 gsl_wavelet_transform_inverse(w, data, 1, n, work);
00159 gsl_wavelet_free(w);
00160 gsl_wavelet_workspace_free(work);
00161 return 0;
00162 }
00163
00168 WaveletParameters wavelet_init(){
00169 WaveletParameters P;
00170 P.first_thresholding_level = 5;
00171 P.wavelet = (gsl_wavelet_type*)gsl_wavelet_daubechies;
00172 P.vanishing_moments = 10;
00173 P.threshselfct = heuristic_sure;
00174 P.threshfct = soft_thresholding;
00175 P.sigextfct = sigext_smooth;
00176 return P;
00177 }
00178
00184 int wavelet_extend_and_denoise ( double *data, int n, WaveletParameters P ){
00185 int J;
00186 double *tmp, *dptr;
00187
00188 J = (int)round(glog((double)n, 2));
00189 J++;
00190 if(((int)pow(2, J))<n)
00191 dprintf(" Warning: Signal length %i is not a power of 2 -> extending signal to length %i\n",
00192 n, (int)pow(2,J));
00193 tmp = (double*)malloc((int)pow(2,J) * sizeof(double));
00194 tmp = memcpy(tmp, data, n*sizeof(double));
00195 dptr=(*(P.sigextfct))(tmp, n, (int)pow(2, J));
00196 wavelet_denoise(tmp, (int)pow(2,J), P );
00197
00198 data = memcpy(data, dptr, n*sizeof(double));
00199
00200 free(tmp);
00201 return 0;
00202 }
00203
00209 double soft_thresholding(double d, double lambda){
00210
00211
00212 if(fabs(d)<=lambda){
00213 d=0.0;
00214 } else if(d>lambda){
00215 d=d-lambda;
00216 } else if(d<(-1)*lambda){
00217 d=d+lambda;
00218 }
00219 return d;
00220 }
00226 double hard_thresholding(double d, double lambda){
00227
00228
00229 if(fabs(d)<=lambda)
00230 d=0.0;
00231 return d;
00232 }
00233
00234
00248 EEG* eeg_wavelet_denoise( EEG *eeg, WaveletParameters P, bool alloc ){
00249 #ifdef FIXEEG
00250 int c, i;
00251 EEG *eeg_out;
00252 if( alloc ){
00253 eeg_out = eeg_clone( eeg, EEG_CLONE_ALL );
00254 } else {
00255 eeg_out = eeg;
00256 }
00257
00258 for( c=0; c<eeg->nbchan; c++ ){
00259 for( i=0; i<eeg->ntrials; i++ ){
00260 wavelet_extend_and_denoise( eeg->data[c][i], eeg->n, P );
00261 }
00262 }
00263 return eeg_out;
00264 #endif
00265 }