dawn@0
|
1 /*
|
dawn@0
|
2 * rdiff_inplace.c
|
dawn@0
|
3 * running difference function
|
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 #define Y_IN prhs[1]
|
dawn@0
|
18 #define R_IN prhs[2]
|
dawn@0
|
19 #define L_IN prhs[3]
|
dawn@0
|
20 #define N_IN prhs[4]
|
dawn@0
|
21
|
dawn@0
|
22 /* Output Arguments */
|
dawn@0
|
23
|
dawn@0
|
24 static void rdiff_inplace(
|
dawn@0
|
25 double *xp, /* input vector 1 */
|
dawn@0
|
26 double *yp, /* input vector 2 */
|
dawn@0
|
27 double *rp, /* df matrix (time X lag) */
|
dawn@0
|
28 double *lp, /* lag matrix */
|
dawn@0
|
29 int N, /* size of summation window */
|
dawn@0
|
30 int m, /* rows in corr matrix */
|
dawn@0
|
31 int n /* columns in corr matrix */
|
dawn@0
|
32 )
|
dawn@0
|
33 {
|
dawn@0
|
34 int j,k,i, xlag, ylag;
|
dawn@0
|
35 double z, d, *r, *x, *y, *bump;
|
dawn@0
|
36
|
dawn@0
|
37
|
dawn@0
|
38 for (j=0;j<n;j++) { /* for each column (lag pair) */
|
dawn@0
|
39 xlag = GET(lp[2*j]);
|
dawn@0
|
40 ylag = GET(lp[2*j+1]);
|
dawn@0
|
41 if (N==1) {
|
dawn@0
|
42 r=&rp[j*m];
|
dawn@0
|
43 x=&xp[xlag];
|
dawn@0
|
44 y=&yp[ylag];
|
dawn@0
|
45 bump=r+m;
|
dawn@0
|
46 while(r<bump) { /* for each row */
|
dawn@0
|
47 d = GET(*x)-GET(*y);
|
dawn@0
|
48 SET(*r) = d*d;
|
dawn@0
|
49 r++; x++; y++;
|
dawn@0
|
50 }
|
dawn@0
|
51 } else {
|
dawn@0
|
52 for (k=0; k<m; k++) { /* for each row */
|
dawn@0
|
53 z=0;
|
dawn@0
|
54 x=&xp[xlag+k*N];
|
dawn@0
|
55 y=&yp[ylag+k*N];
|
dawn@0
|
56 bump=x+N;
|
dawn@0
|
57 while(x<bump) {
|
dawn@0
|
58 d = GET(*x)-GET(*y);
|
dawn@0
|
59 z+=d*d;
|
dawn@0
|
60 x++; y++;
|
dawn@0
|
61 }
|
dawn@0
|
62 SET(rp[j*m+k]) = z;
|
dawn@0
|
63 }
|
dawn@0
|
64 }
|
dawn@0
|
65 }
|
dawn@0
|
66
|
dawn@0
|
67 return;
|
dawn@0
|
68 }
|
dawn@0
|
69
|
dawn@0
|
70 void mexFunction(
|
dawn@0
|
71 int nlhs, mxArray *plhs[],
|
dawn@0
|
72 int nrhs, const mxArray *prhs[]
|
dawn@0
|
73 )
|
dawn@0
|
74 {
|
dawn@0
|
75 double *xp, *yp, *rp, *lp, *up, *np;
|
dawn@0
|
76 int nx, mx, ny, my, nr, mr, nl, ml, xmax, ymax, j, N, xlag, ylag;
|
dawn@0
|
77
|
dawn@0
|
78 /* Check for proper number of arguments */
|
dawn@0
|
79 if (nrhs < 4 || nrhs > 5) {
|
dawn@0
|
80 mexErrMsgTxt("RDIFF_INPLACE takes 4 or 5 input arguments");
|
dawn@0
|
81 }
|
dawn@0
|
82
|
dawn@0
|
83 /* Check type of input */
|
dawn@0
|
84 if (!mxIsNumeric(X_IN) || mxIsComplex(X_IN) ||
|
dawn@0
|
85 mxIsSparse(X_IN) || !mxIsDouble(X_IN) ) {
|
dawn@0
|
86 mexErrMsgTxt("RDIFF_INPLACE: X should be doubles");
|
dawn@0
|
87 }
|
dawn@0
|
88 if (!mxIsNumeric(Y_IN) || mxIsComplex(Y_IN) ||
|
dawn@0
|
89 mxIsSparse(Y_IN) || !mxIsDouble(Y_IN) ) {
|
dawn@0
|
90 mexErrMsgTxt("RDIFF_INPLACE: Y should be doubles");
|
dawn@0
|
91 }
|
dawn@0
|
92 if (!mxIsNumeric(R_IN) || mxIsComplex(R_IN) ||
|
dawn@0
|
93 mxIsSparse(R_IN) || !mxIsDouble(R_IN) ) {
|
dawn@0
|
94 mexErrMsgTxt("RDIFF_INPLACE: R should be doubles");
|
dawn@0
|
95 }
|
dawn@0
|
96 if (nrhs==5) {
|
dawn@0
|
97 if (!mxIsNumeric(N_IN) || mxIsComplex(N_IN) ||
|
dawn@0
|
98 mxIsSparse(N_IN) || !mxIsDouble(N_IN) ) {
|
dawn@0
|
99 mexErrMsgTxt("RDIFF_INPLACE: N should double");
|
dawn@0
|
100 }
|
dawn@0
|
101 np = mxGetPr(N_IN);
|
dawn@0
|
102 N=*np;
|
dawn@0
|
103 } else {
|
dawn@0
|
104 N=1;
|
dawn@0
|
105 }
|
dawn@0
|
106 mx=mxGetM(X_IN); /* rows */
|
dawn@0
|
107 nx=mxGetN(X_IN); /* columns */
|
dawn@0
|
108 my=mxGetM(Y_IN);
|
dawn@0
|
109 ny=mxGetN(Y_IN);
|
dawn@0
|
110 mr=mxGetM(R_IN);
|
dawn@0
|
111 nr=mxGetN(R_IN);
|
dawn@0
|
112 ml=mxGetM(L_IN);
|
dawn@0
|
113 nl=mxGetN(L_IN);
|
dawn@0
|
114
|
dawn@0
|
115 if (nx>1 || ny>1) {
|
dawn@0
|
116 mexErrMsgTxt("RDIFF_INPLACE: X and Y should be column vectors");
|
dawn@0
|
117 }
|
dawn@0
|
118 if (nr !=nl) {
|
dawn@0
|
119 mexErrMsgTxt("RDIFF_INPLACE: result and lag matrices should have same number of columns");
|
dawn@0
|
120 }
|
dawn@0
|
121 if ( ml != 2) {
|
dawn@0
|
122 mexErrMsgTxt("RDIFF_INPLACE: lags should be a two row matrix");
|
dawn@0
|
123 }
|
dawn@0
|
124 if (!nx || !mx || !ny || !my || !nr || !mr || !nl || !ml) {
|
dawn@0
|
125 mexErrMsgTxt("RDIFF_INPLACE: one of the input matrices is empty");
|
dawn@0
|
126 }
|
dawn@0
|
127
|
dawn@0
|
128 xp = mxGetPr(X_IN);
|
dawn@0
|
129 yp = mxGetPr(Y_IN);
|
dawn@0
|
130 rp = mxGetPr(R_IN);
|
dawn@0
|
131 lp = mxGetPr(L_IN);
|
dawn@0
|
132
|
dawn@0
|
133 checkin_matrix((mxArray *) L_IN);
|
dawn@0
|
134
|
dawn@0
|
135 /* find maximum lag for x and y and check that no lag is negative */
|
dawn@0
|
136 xmax=GET(lp[0]);
|
dawn@0
|
137 ymax=GET(lp[1]);
|
dawn@0
|
138 for (j=1;j<nl;j++) {
|
dawn@0
|
139 xlag = GET(lp[2*j]);
|
dawn@0
|
140 ylag = GET(lp[2*j+1]);
|
dawn@0
|
141 if ( xlag<0 || ylag<0 ) {
|
dawn@0
|
142 mexErrMsgTxt("RDIFF_INPLACE: LAGS should be non-negative");
|
dawn@0
|
143 }
|
dawn@0
|
144 if (xlag>xmax ) xmax=xlag;
|
dawn@0
|
145 if (ylag>ymax ) ymax=ylag;
|
dawn@0
|
146 }
|
dawn@0
|
147
|
dawn@0
|
148 if ( (N*mr+ymax)> my) {
|
dawn@0
|
149 mexPrintf("mr*N: %d, ymax: %d, my: %d\n", mr*N, ymax, my);
|
dawn@0
|
150 mexErrMsgTxt("RDIFF_INPLACE: Y data too short");
|
dawn@0
|
151 }
|
dawn@0
|
152 if ( (N*mr+xmax)> mx) {
|
dawn@0
|
153 mexPrintf("mr*N: %d, xmax: %d, mx: %d\n", mr*N, xmax, mx);
|
dawn@0
|
154 mexErrMsgTxt("RDIFF_INPLACE: X data too short");
|
dawn@0
|
155 }
|
dawn@0
|
156
|
dawn@0
|
157 checkin_matrix((mxArray *) X_IN);
|
dawn@0
|
158 if (yp!=xp) checkin_matrix((mxArray *) Y_IN);
|
dawn@0
|
159 checkin_matrix((mxArray *) R_IN);
|
dawn@0
|
160
|
dawn@0
|
161 /* Do the actual computations in a subroutine */
|
dawn@0
|
162 rdiff_inplace(xp,yp,rp,lp,N,mr,nr);
|
dawn@0
|
163
|
dawn@0
|
164 checkout_matrix((mxArray *) X_IN);
|
dawn@0
|
165 if (yp!=xp) checkout_matrix((mxArray *) Y_IN);
|
dawn@0
|
166 checkout_matrix((mxArray *) R_IN);
|
dawn@0
|
167 checkout_matrix((mxArray *) L_IN);
|
dawn@0
|
168 return;
|
dawn@0
|
169 }
|
dawn@0
|
170
|