dawn@0
|
1 /*
|
dawn@0
|
2 * minInterp.c
|
dawn@0
|
3 * determine position of minimum of parabolic fit to local minima
|
dawn@0
|
4 *
|
dawn@0
|
5 * Alain de Cheveigné, CNRS/Ircam Dec 2001
|
dawn@0
|
6 * (c) 2001 CNRS
|
dawn@0
|
7 */
|
dawn@0
|
8
|
dawn@0
|
9 #include <math.h>
|
dawn@0
|
10 #include "mex.h"
|
dawn@0
|
11
|
dawn@0
|
12 /* #define MWRAP */
|
dawn@0
|
13 #include "mwrap_check.h"
|
dawn@0
|
14
|
dawn@0
|
15 /* Input Arguments */
|
dawn@0
|
16 #define X_IN prhs[0]
|
dawn@0
|
17
|
dawn@0
|
18
|
dawn@0
|
19 /* Output Arguments */
|
dawn@0
|
20 #define MIN_OUT plhs[0]
|
dawn@0
|
21 #define IND_OUT plhs[1]
|
dawn@0
|
22
|
dawn@0
|
23
|
dawn@0
|
24 static void mininterp(
|
dawn@0
|
25 double *xp,
|
dawn@0
|
26 unsigned int m,
|
dawn@0
|
27 unsigned int n,
|
dawn@0
|
28 double *minp,
|
dawn@0
|
29 double *indp
|
dawn@0
|
30 )
|
dawn@0
|
31 {
|
dawn@0
|
32 double x1,x2,x3,a,b,min,ind;
|
dawn@0
|
33 int i,j,k;
|
dawn@0
|
34
|
dawn@0
|
35 /* each column is interpolated independently */
|
dawn@0
|
36 /* each local minimum is replaced by the value of the interpolated minimum, and the
|
dawn@0
|
37 position of the interplolated minimum is recorded in indp */
|
dawn@0
|
38
|
dawn@0
|
39 for (j=0; j<n; j++) {
|
dawn@0
|
40 /* first row: don't touch */
|
dawn@0
|
41 SET(indp[j*m])=0;
|
dawn@0
|
42 SET(minp[j*m])=GET(xp[j*m]);
|
dawn@0
|
43 /* intermediate: refine */
|
dawn@0
|
44 for (k=1; k<m-1; k++) {
|
dawn@0
|
45 i=k+j*m;
|
dawn@0
|
46 x1=GET(xp[i-1]); x2=GET(xp[i]); x3=GET(xp[i+1]);
|
dawn@0
|
47 SET(indp[i]) = 0; /* default */
|
dawn@0
|
48 SET(minp[i]) = x2;
|
dawn@0
|
49 if ((x2<=x1) && (x2<=x3)) {
|
dawn@0
|
50 a = (x1 + x3 - 2*x2)/2;
|
dawn@0
|
51 b = (x3 - x1)/2;
|
dawn@0
|
52 if (a) {
|
dawn@0
|
53 SET(indp[i]) = - b / (2*a);
|
dawn@0
|
54 SET(minp[i]) = x2 + - (b*b) / (4*a);
|
dawn@0
|
55 }
|
dawn@0
|
56 }
|
dawn@0
|
57 }
|
dawn@0
|
58 /* last row: don't touch */
|
dawn@0
|
59 SET(indp[m-1 + j*m])=0;
|
dawn@0
|
60 SET(minp[m-1 + j*m])=GET(xp[m-1 + j*m]);
|
dawn@0
|
61 }
|
dawn@0
|
62 return;
|
dawn@0
|
63 }
|
dawn@0
|
64
|
dawn@0
|
65 void mexFunction(
|
dawn@0
|
66 int nlhs, mxArray *plhs[],
|
dawn@0
|
67 int nrhs, const mxArray *prhs[]
|
dawn@0
|
68 )
|
dawn@0
|
69 {
|
dawn@0
|
70 double *minp, *indp, *xp;
|
dawn@0
|
71 unsigned int m,n;
|
dawn@0
|
72
|
dawn@0
|
73 /* Check for proper number of arguments */
|
dawn@0
|
74
|
dawn@0
|
75 if (nrhs != 1) {
|
dawn@0
|
76 mexErrMsgTxt("minParabolic requires one input argument.");
|
dawn@0
|
77 } else if (nlhs > 2) {
|
dawn@0
|
78 mexErrMsgTxt("minParabolic requires one or two output arguments");
|
dawn@0
|
79 }
|
dawn@0
|
80
|
dawn@0
|
81
|
dawn@0
|
82 /* Check type of input */
|
dawn@0
|
83
|
dawn@0
|
84 if (!mxIsNumeric(X_IN) || mxIsComplex(X_IN) ||
|
dawn@0
|
85 mxIsSparse(X_IN) || !mxIsDouble(X_IN)) {
|
dawn@0
|
86 mexErrMsgTxt("minParabolic requires that X be a matrix of doubles");
|
dawn@0
|
87 }
|
dawn@0
|
88
|
dawn@0
|
89 m = mxGetM(X_IN); /* rows */
|
dawn@0
|
90 n = mxGetN(X_IN); /* columns */
|
dawn@0
|
91 if (m<3) { mexErrMsgTxt("number of rows should be 3 or more"); }
|
dawn@0
|
92
|
dawn@0
|
93
|
dawn@0
|
94 /* Create two matrices to return */
|
dawn@0
|
95
|
dawn@0
|
96 MIN_OUT = mxCreateDoubleMatrix(m, n, mxREAL);
|
dawn@0
|
97 IND_OUT = mxCreateDoubleMatrix(m, n, mxREAL);
|
dawn@0
|
98
|
dawn@0
|
99
|
dawn@0
|
100 /* Assign pointers to the various parameters */
|
dawn@0
|
101
|
dawn@0
|
102 minp = mxGetPr(MIN_OUT);
|
dawn@0
|
103 indp = mxGetPr(IND_OUT);
|
dawn@0
|
104 xp = mxGetPr(X_IN);
|
dawn@0
|
105
|
dawn@0
|
106 checkin_matrix((mxArray *) X_IN);
|
dawn@0
|
107 checkin_matrix(MIN_OUT);
|
dawn@0
|
108 checkin_matrix(IND_OUT);
|
dawn@0
|
109
|
dawn@0
|
110 /* Do the actual computations in a subroutine */
|
dawn@0
|
111
|
dawn@0
|
112
|
dawn@0
|
113 mininterp(xp,m,n,minp,indp);
|
dawn@0
|
114
|
dawn@0
|
115 checkout_matrix((mxArray *) X_IN);
|
dawn@0
|
116 checkout_matrix(MIN_OUT);
|
dawn@0
|
117 checkout_matrix(IND_OUT);
|
dawn@0
|
118 return;
|
dawn@0
|
119 }
|
dawn@0
|
120
|
dawn@0
|
121
|