• API Main Page
  • Documentation
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

src/wavelet.c

Go to the documentation of this file.
00001 /* **************************************************************************
00002  *   Copyright (C) 2008 by Matthias Ihrke   *
00003  *   mihrke@uni-goettingen.de   *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
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> /* memcpy */
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; /* population sd, threshold */
00043   
00044   sigma  = mad(data, n)/0.6745; /* funny constant, eh? */
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; /* population sd, threshold */
00057   
00058   sigma  = mad(data,n)/0.6745; /* funny constant, eh? */
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   /*  tmp = memcpy(tmp, data, n*sizeof(double)); */
00106  
00107   /* compute the SURESHRINK threshold */
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; /* population sd, threshold */
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   /* -- thresholding here -- */
00146   J = (int)round(glog((double)n, 2));
00147   for(j=P.first_thresholding_level; j<J; j++){ /* loop through levels */
00148     offset = (int)pow(2, j);
00149     lambda = (*(P.threshselfct))(&(data[offset]), offset);
00150 
00151     for(k=offset; k<2*offset; k++){ /* loop through coefficients */
00152       /* soft or hard thresholding */
00153       data[k]=(*(P.threshfct))(data[k], lambda);
00154     }
00155   }
00156   /* -- thresholding end -- */
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   /* soft thresholding, formula (6) */
00211 /*   dprintf("Db: eta_s\n"); */
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   /* hard thresholding */
00228 /*   dprintf("Db: eta_h\n"); */
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 }

Generated on Fri Jun 25 2010 14:10:22 for libeegtools by  doxygen 1.7.0