dawn@0
|
1 /*
|
dawn@0
|
2 * minInRange.c
|
dawn@0
|
3 * for each sample, return index of the smallest value within an interval
|
dawn@0
|
4 * of that sample
|
dawn@0
|
5 *
|
dawn@0
|
6 * Alain de Cheveigné, CNRS/Ircam Dec 2001
|
dawn@0
|
7 * (c) 2001 CNRS
|
dawn@0
|
8 */
|
dawn@0
|
9
|
dawn@0
|
10 #include <math.h>
|
dawn@0
|
11 #include "mex.h"
|
dawn@0
|
12
|
dawn@0
|
13 /* #define MWRAP */
|
dawn@0
|
14 #include "mwrap_check.h"
|
dawn@0
|
15
|
dawn@0
|
16 /* Input Arguments */
|
dawn@0
|
17
|
dawn@0
|
18 #define X_IN prhs[0]
|
dawn@0
|
19 #define INTERVAL_IN prhs[1]
|
dawn@0
|
20
|
dawn@0
|
21 /* Output Arguments */
|
dawn@0
|
22
|
dawn@0
|
23 #define IDX_OUT plhs[0]
|
dawn@0
|
24
|
dawn@0
|
25 static void mininrange(
|
dawn@0
|
26 double *xp,
|
dawn@0
|
27 double *intp,
|
dawn@0
|
28 double *idxp,
|
dawn@0
|
29 unsigned int n
|
dawn@0
|
30 )
|
dawn@0
|
31 {
|
dawn@0
|
32 int h,k, idx, left, right, interval;
|
dawn@0
|
33 double min;
|
dawn@0
|
34 double max;
|
dawn@0
|
35
|
dawn@0
|
36
|
dawn@0
|
37 for (k=0; k<n; k++) {
|
dawn@0
|
38 interval=(int) GET(intp[k]);
|
dawn@0
|
39
|
dawn@0
|
40 left = k - interval/2;
|
dawn@0
|
41 right = left+interval;
|
dawn@0
|
42
|
dawn@0
|
43 if (left<0) left=0; /* clip */
|
dawn@0
|
44 if (right>n) right=n;
|
dawn@0
|
45
|
dawn@0
|
46 min = GET(xp[k]);
|
dawn@0
|
47 idx = k;
|
dawn@0
|
48 for (h=left;h<right; h++) {
|
dawn@0
|
49 if (GET(xp[h]) < min) { /* update min */
|
dawn@0
|
50 min = GET(xp[h]);
|
dawn@0
|
51 idx = h;
|
dawn@0
|
52 }
|
dawn@0
|
53 }
|
dawn@0
|
54 SET(idxp[k])=idx+1;
|
dawn@0
|
55 }
|
dawn@0
|
56 return;
|
dawn@0
|
57 }
|
dawn@0
|
58
|
dawn@0
|
59 void mexFunction(
|
dawn@0
|
60 int nlhs, mxArray *plhs[],
|
dawn@0
|
61 int nrhs, const mxArray *prhs[]
|
dawn@0
|
62 )
|
dawn@0
|
63 {
|
dawn@0
|
64 double *xp, *idxp, *intp;
|
dawn@0
|
65 unsigned int m,n;
|
dawn@0
|
66
|
dawn@0
|
67 /* Check for proper number of arguments */
|
dawn@0
|
68
|
dawn@0
|
69 if (nrhs != 2) {
|
dawn@0
|
70 mexErrMsgTxt("MININRANGE requires two input arguments");
|
dawn@0
|
71 } else if (nlhs != 1) {
|
dawn@0
|
72 mexErrMsgTxt("MININRANGE requires one output argument");
|
dawn@0
|
73 }
|
dawn@0
|
74
|
dawn@0
|
75 /* Check type of input */
|
dawn@0
|
76
|
dawn@0
|
77 if (!mxIsNumeric(X_IN) || mxIsComplex(X_IN) ||
|
dawn@0
|
78 mxIsSparse(X_IN) || !mxIsDouble(X_IN)) {
|
dawn@0
|
79 mexErrMsgTxt("MININRANGE: X should be matrix of doubles");
|
dawn@0
|
80 }
|
dawn@0
|
81 if (!mxIsNumeric(INTERVAL_IN) || mxIsComplex(INTERVAL_IN) ||
|
dawn@0
|
82 mxIsSparse(INTERVAL_IN) || !mxIsDouble(INTERVAL_IN)) {
|
dawn@0
|
83 mexErrMsgTxt("MININRANGE X should be matrix of doubles");
|
dawn@0
|
84 }
|
dawn@0
|
85
|
dawn@0
|
86 m = mxGetM(X_IN); /* rows */
|
dawn@0
|
87 n = mxGetN(X_IN); /* columns */
|
dawn@0
|
88 if (m>1 || n <=1) {
|
dawn@0
|
89 mexErrMsgTxt("MININRANGE X should be row vector");
|
dawn@0
|
90 }
|
dawn@0
|
91 if (m != mxGetM(INTERVAL_IN) || n != mxGetN(INTERVAL_IN)) {
|
dawn@0
|
92 mexErrMsgTxt("MININRANGE: INTERVAL should be of same size as X");
|
dawn@0
|
93 }
|
dawn@0
|
94
|
dawn@0
|
95 /* Create matrix to return */
|
dawn@0
|
96
|
dawn@0
|
97 IDX_OUT = mxCreateDoubleMatrix(1, n, mxREAL);
|
dawn@0
|
98
|
dawn@0
|
99 /* Assign pointers to the various parameters */
|
dawn@0
|
100
|
dawn@0
|
101 xp = mxGetPr(X_IN);
|
dawn@0
|
102 intp = mxGetPr(INTERVAL_IN);
|
dawn@0
|
103 idxp = mxGetPr(IDX_OUT);
|
dawn@0
|
104
|
dawn@0
|
105 checkin_matrix((mxArray *) X_IN);
|
dawn@0
|
106 checkin_matrix((mxArray *) INTERVAL_IN);
|
dawn@0
|
107 checkin_matrix(IDX_OUT);
|
dawn@0
|
108
|
dawn@0
|
109 /* Do the actual computations in a subroutine */
|
dawn@0
|
110
|
dawn@0
|
111 mininrange(xp,intp,idxp,n);
|
dawn@0
|
112
|
dawn@0
|
113 checkout_matrix((mxArray *) X_IN);
|
dawn@0
|
114 checkout_matrix((mxArray *) INTERVAL_IN);
|
dawn@0
|
115 checkout_matrix(IDX_OUT);
|
dawn@0
|
116 return;
|
dawn@0
|
117 }
|
dawn@0
|
118
|
dawn@0
|
119
|