diff src/ltpda_smoother/ltpda_smoother.c @ 0:f0afece42f48

Import.
author Daniele Nicolodi <nicolodi@science.unitn.it>
date Wed, 23 Nov 2011 19:22:13 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ltpda_smoother/ltpda_smoother.c	Wed Nov 23 19:22:13 2011 +0100
@@ -0,0 +1,197 @@
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <mex.h>
+
+#include "version.h"
+#include "ltpda_smoother.h"
+#include "quick.c"
+
+#define DEBUG 0
+/*
+ * A smoother function that uses various methods to smooth data.
+ *
+ * M Hewitson  28-08-01
+ *
+ * $Id: ltpda_smoother.c,v 1.4 2008/09/25 08:16:16 hewitson Exp $
+ */
+
+
+/*
+   function sy = ltpda_smoother(y, bw, ol, method);
+ 
+ */
+void  mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
+{
+  int status;
+  int buff_len;
+  
+  /* outputs */
+  double  *outputPtr;
+  double  *nxx;
+  int      a;
+  
+  /* inputs */
+  double *xx;
+  int     bw;
+  double  ol;
+  int     nx;
+  char   *method;
+  
+  /* parse input functions */
+  
+  if( (nrhs == 0) || (nlhs == 0) )
+  {
+    print_usage(VERSION);
+  }
+  
+  if( (nrhs == 4) && (nlhs == 1) )/* let's go */
+  {    
+    /*----------------- set inputs*/
+    xx = mxGetPr(prhs[0]);
+    bw = (int)floor(mxGetScalar(prhs[1]));
+    ol = mxGetScalar(prhs[2]);
+    nx = mxGetNumberOfElements(prhs[0]);
+
+    /* Read the method*/
+    buff_len = (mxGetM(prhs[3]) * mxGetN(prhs[3])) + 1;
+    method = mxCalloc(buff_len, sizeof(char));
+    status = mxGetString(prhs[3], method, buff_len);
+    if(status != 0) 
+      mexWarnMsgTxt("Not enough space. String is truncated.");
+    
+    /* create output vector*/
+    nxx = (double*)mxCalloc(nx, sizeof(double));
+    
+    /* nfest*/
+    smooth(nxx, xx, nx, bw, ol, method);
+    
+    /* output noise-floor vector*/
+    plhs[0] = mxCreateDoubleMatrix(1,nx,mxREAL);
+    outputPtr = mxGetPr(plhs[0]);
+    for(a=0; a<nx; a++)
+      outputPtr[a] = nxx[a];
+    
+    mxFree(nxx);
+  }
+  else
+  {
+    print_usage(VERSION);
+  }
+}
+
+void print_usage(char *version)
+{
+  mexPrintf("ltpda_smoother version %s\n", version);
+  mexPrintf("  usage:    function sy = ltpda_smoother(y, bw, ol, method); \n");
+  mexErrMsgTxt("### incorrect usage");
+}
+/*
+ * Smoother
+ */
+int smooth(double *nxx, double *xx, int nx, int bw, double ol, char *method)
+{
+  int     k, j, idx;
+  int     hbw;
+  double *seg;
+  
+  seg = (double*)mxCalloc(bw+1, sizeof(double));
+  
+  /* go through each element */  
+  for(k=0; k<nx; k++)
+  {
+    /* get segment*/
+    for(j=0; j<=bw; j++)
+    {
+      idx = k+j-bw/2;
+      if (idx<0)
+        idx = 0;
+      if (idx>=nx)
+        idx = nx-1;      
+      seg[j] = xx[idx];
+    }
+    /* sort segment*/
+    quickSort(seg, bw-1);
+    /* stop index*/
+    idx = (int)floor(ol*bw);
+    /* Which smoothing method? */
+    if (strcmp(method, "median")==0)
+    {
+      /* make median estimate of selected samples */
+      nxx[k] = median(seg, idx);
+    }
+    else if (strcmp(method, "mean")==0)
+    {
+      /* make mean estimate of selected samples */
+      nxx[k] = mean(seg, idx);
+    }
+    else if (strcmp(method, "min")==0)
+    {
+      /* make min estimate of selected samples */
+      nxx[k] = smin(seg, idx);
+    }
+    else if (strcmp(method, "max")==0)
+    {
+      /* make max estimate of selected samples */
+      nxx[k] = smax(seg, idx);
+    }
+  }
+  
+  /* Clean up */
+  mxFree(seg);
+  
+  return 0;
+}
+
+
+double smin(double *x, int nx)
+{
+  double m;
+  int    j;
+  
+  m = x[0];
+  
+  for (j=1; j<nx; j++)
+    if (x[j] < m)
+      m = x[j];
+
+  return m;  
+}
+
+double smax(double *x, int nx)
+{
+  double m;
+  int    j;
+  
+  m = x[0];
+  
+  for (j=1; j<nx; j++)
+    if (x[j] > m)
+      m = x[j];
+
+  return m;  
+}
+
+double mean(double *x, int nx)
+{
+  int    j;
+  double sx = 0.0;
+  
+  for (j=0; j<nx; j++)
+    sx += x[j];
+
+  return sx/nx;  
+}
+
+double median(double *x, int nx)
+{
+  double m;
+  
+  if (nx%2 == 0) /* even*/
+    m = (x[nx/2] + x[nx/2 -1])/2.0;
+  else
+    m = x[(nx-1)/2];
+  
+  return m;
+}