0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
1 #include <math.h>
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
2 #include <stdio.h>
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
3 #include <stdlib.h>
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
4 #include <string.h>
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
5 #include <mex.h>
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
6
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
7 #include "version.h"
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
8 #include "ltpda_smoother.h"
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
9 #include "quick.c"
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
10
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
11 #define DEBUG 0
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
12 /*
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
13 * A smoother function that uses various methods to smooth data.
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
14 *
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
15 * M Hewitson 28-08-01
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
16 *
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
17 * $Id: ltpda_smoother.c,v 1.4 2008/09/25 08:16:16 hewitson Exp $
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
18 */
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
19
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
20
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
21 /*
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
22 function sy = ltpda_smoother(y, bw, ol, method);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
23
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
24 */
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
25 void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
26 {
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
27 int status;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
28 int buff_len;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
29
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
30 /* outputs */
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
31 double *outputPtr;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
32 double *nxx;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
33 int a;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
34
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
35 /* inputs */
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
36 double *xx;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
37 int bw;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
38 double ol;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
39 int nx;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
40 char *method;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
41
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
42 /* parse input functions */
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
43
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
44 if( (nrhs == 0) || (nlhs == 0) )
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
45 {
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
46 print_usage(VERSION);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
47 }
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
48
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
49 if( (nrhs == 4) && (nlhs == 1) )/* let's go */
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
50 {
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
51 /*----------------- set inputs*/
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
52 xx = mxGetPr(prhs[0]);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
53 bw = (int)floor(mxGetScalar(prhs[1]));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
54 ol = mxGetScalar(prhs[2]);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
55 nx = mxGetNumberOfElements(prhs[0]);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
56
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
57 /* Read the method*/
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
58 buff_len = (mxGetM(prhs[3]) * mxGetN(prhs[3])) + 1;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
59 method = mxCalloc(buff_len, sizeof(char));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
60 status = mxGetString(prhs[3], method, buff_len);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
61 if(status != 0)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
62 mexWarnMsgTxt("Not enough space. String is truncated.");
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
63
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
64 /* create output vector*/
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
65 nxx = (double*)mxCalloc(nx, sizeof(double));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
66
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
67 /* nfest*/
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
68 smooth(nxx, xx, nx, bw, ol, method);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
69
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
70 /* output noise-floor vector*/
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
71 plhs[0] = mxCreateDoubleMatrix(1,nx,mxREAL);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
72 outputPtr = mxGetPr(plhs[0]);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
73 for(a=0; a<nx; a++)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
74 outputPtr[a] = nxx[a];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
75
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
76 mxFree(nxx);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
77 }
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
78 else
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
79 {
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
80 print_usage(VERSION);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
81 }
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
82 }
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
83
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
84 void print_usage(char *version)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
85 {
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
86 mexPrintf("ltpda_smoother version %s\n", version);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
87 mexPrintf(" usage: function sy = ltpda_smoother(y, bw, ol, method); \n");
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
88 mexErrMsgTxt("### incorrect usage");
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
89 }
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
90 /*
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
91 * Smoother
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
92 */
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
93 int smooth(double *nxx, double *xx, int nx, int bw, double ol, char *method)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
94 {
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
95 int k, j, idx;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
96 int hbw;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
97 double *seg;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
98
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
99 seg = (double*)mxCalloc(bw+1, sizeof(double));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
100
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
101 /* go through each element */
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
102 for(k=0; k<nx; k++)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
103 {
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
104 /* get segment*/
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
105 for(j=0; j<=bw; j++)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
106 {
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
107 idx = k+j-bw/2;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
108 if (idx<0)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
109 idx = 0;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
110 if (idx>=nx)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
111 idx = nx-1;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
112 seg[j] = xx[idx];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
113 }
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
114 /* sort segment*/
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
115 quickSort(seg, bw-1);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
116 /* stop index*/
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
117 idx = (int)floor(ol*bw);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
118 /* Which smoothing method? */
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
119 if (strcmp(method, "median")==0)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
120 {
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
121 /* make median estimate of selected samples */
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
122 nxx[k] = median(seg, idx);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
123 }
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
124 else if (strcmp(method, "mean")==0)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
125 {
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
126 /* make mean estimate of selected samples */
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
127 nxx[k] = mean(seg, idx);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
128 }
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
129 else if (strcmp(method, "min")==0)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
130 {
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
131 /* make min estimate of selected samples */
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
132 nxx[k] = smin(seg, idx);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
133 }
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
134 else if (strcmp(method, "max")==0)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
135 {
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
136 /* make max estimate of selected samples */
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
137 nxx[k] = smax(seg, idx);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
138 }
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
139 }
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
140
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
141 /* Clean up */
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
142 mxFree(seg);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
143
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
144 return 0;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
145 }
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
146
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
147
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
148 double smin(double *x, int nx)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
149 {
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
150 double m;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
151 int j;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
152
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
153 m = x[0];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
154
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
155 for (j=1; j<nx; j++)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
156 if (x[j] < m)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
157 m = x[j];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
158
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
159 return m;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
160 }
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
161
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
162 double smax(double *x, int nx)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
163 {
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
164 double m;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
165 int j;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
166
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
167 m = x[0];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
168
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
169 for (j=1; j<nx; j++)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
170 if (x[j] > m)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
171 m = x[j];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
172
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
173 return m;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
174 }
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
175
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
176 double mean(double *x, int nx)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
177 {
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
178 int j;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
179 double sx = 0.0;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
180
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
181 for (j=0; j<nx; j++)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
182 sx += x[j];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
183
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
184 return sx/nx;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
185 }
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
186
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
187 double median(double *x, int nx)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
188 {
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
189 double m;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
190
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
191 if (nx%2 == 0) /* even*/
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
192 m = (x[nx/2] + x[nx/2 -1])/2.0;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
193 else
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
194 m = x[(nx-1)/2];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
195
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
196 return m;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
197 }
|