dawn@0
|
1 /*
|
dawn@0
|
2 * rsum_inplace.c
|
dawn@0
|
3 * in-place running sum
|
dawn@0
|
4 *
|
dawn@0
|
5 * Alain de Cheveigné, CNRS/Ircam Jun 2002
|
dawn@0
|
6 * (c) 2002 CNRS
|
dawn@0
|
7 */
|
dawn@0
|
8
|
dawn@0
|
9 /* Replaces each sample of the input matrix by the sum of itself and its N-1
|
dawn@0
|
10 * neighbors. The operation is done in-place on the input argument. The last
|
dawn@0
|
11 * N-1 samples of each row are invalid. */
|
dawn@0
|
12
|
dawn@0
|
13 #include <math.h>
|
dawn@0
|
14 #include "mex.h"
|
dawn@0
|
15
|
dawn@0
|
16 /* #define MWRAP */
|
dawn@0
|
17 #include "mwrap_check.h"
|
dawn@0
|
18
|
dawn@0
|
19 /* Input Arguments */
|
dawn@0
|
20 #define X_IN prhs[0]
|
dawn@0
|
21 #define N_IN prhs[1]
|
dawn@0
|
22
|
dawn@0
|
23 /* Output Arguments */
|
dawn@0
|
24
|
dawn@0
|
25 static void rsmth(
|
dawn@0
|
26 double *xp, /* matrix to sum */
|
dawn@0
|
27 double N, /* window size */
|
dawn@0
|
28 int m, /* rows */
|
dawn@0
|
29 int n /* columns */
|
dawn@0
|
30 )
|
dawn@0
|
31 {
|
dawn@0
|
32 int j,k, Ni;
|
dawn@0
|
33 double Nr, tmp, sum, *x, *xx, *bump;
|
dawn@0
|
34
|
dawn@0
|
35 Ni = (int) floor(N);
|
dawn@0
|
36 Nr = N - (double) Ni;
|
dawn@0
|
37
|
dawn@0
|
38
|
dawn@0
|
39 if (Nr == 0.0) {
|
dawn@0
|
40 /* N is integer: simple summation */
|
dawn@0
|
41 for (j=0;j<n;j++) { /* for each column */
|
dawn@0
|
42 /* prefill running sum */
|
dawn@0
|
43 sum=0.0;
|
dawn@0
|
44 x=&xp[j*m];
|
dawn@0
|
45 bump=x+Ni-1;
|
dawn@0
|
46 while (x<bump) { /* for each row */
|
dawn@0
|
47 sum += GET(*x);
|
dawn@0
|
48 x++;
|
dawn@0
|
49 }
|
dawn@0
|
50 /* N */
|
dawn@0
|
51 x=&xp[j*m];
|
dawn@0
|
52 bump=x+m-(Ni-1);
|
dawn@0
|
53 xx=x+Ni-1;
|
dawn@0
|
54 while(x<bump) {
|
dawn@0
|
55 tmp = GET(*x);
|
dawn@0
|
56 sum += GET(*xx);
|
dawn@0
|
57 SET(*x) = sum;
|
dawn@0
|
58 sum -= tmp;
|
dawn@0
|
59 x++; xx++;
|
dawn@0
|
60 }
|
dawn@0
|
61 }
|
dawn@0
|
62 } else {
|
dawn@0
|
63 /* N is fractionary: interpolate */
|
dawn@0
|
64 for (j=0;j<n;j++) { /* for each column */
|
dawn@0
|
65 /* prefill running sum */
|
dawn@0
|
66 sum=0.0;
|
dawn@0
|
67 x=&xp[j*m];
|
dawn@0
|
68 bump=x+Ni-1;
|
dawn@0
|
69 while (x<bump) { /* for each row */
|
dawn@0
|
70 sum += GET(*x);
|
dawn@0
|
71 x++;
|
dawn@0
|
72 }
|
dawn@0
|
73 /* N */
|
dawn@0
|
74 x=&xp[j*m];
|
dawn@0
|
75 bump=x+m-(Ni-1);
|
dawn@0
|
76 xx=x+Ni-1;
|
dawn@0
|
77 while(x<bump) {
|
dawn@0
|
78 tmp = GET(*x);
|
dawn@0
|
79 sum += GET(*xx);
|
dawn@0
|
80 SET(*x) = sum + Nr * GET(*xx);
|
dawn@0
|
81 sum -= tmp;
|
dawn@0
|
82 x++; xx++;
|
dawn@0
|
83 }
|
dawn@0
|
84 }
|
dawn@0
|
85 }
|
dawn@0
|
86 return;
|
dawn@0
|
87 }
|
dawn@0
|
88
|
dawn@0
|
89 void mexFunction(
|
dawn@0
|
90 int nlhs, mxArray *plhs[],
|
dawn@0
|
91 int nrhs, const mxArray *prhs[]
|
dawn@0
|
92 )
|
dawn@0
|
93 {
|
dawn@0
|
94 double *xp, *Np, N;
|
dawn@0
|
95 int n, m;
|
dawn@0
|
96
|
dawn@0
|
97 /* Check for proper number of arguments */
|
dawn@0
|
98 if (nrhs != 2) {
|
dawn@0
|
99 mexErrMsgTxt("RSUM_INPLACE takes 2 input arguments");
|
dawn@0
|
100 }
|
dawn@0
|
101
|
dawn@0
|
102 /* Check type of input */
|
dawn@0
|
103 if (!mxIsNumeric(X_IN) || mxIsComplex(X_IN) ||
|
dawn@0
|
104 mxIsSparse(X_IN) || !mxIsDouble(X_IN) ) {
|
dawn@0
|
105 mexErrMsgTxt("RSUM_INPLACE: X should be doubles");
|
dawn@0
|
106 }
|
dawn@0
|
107 if (!mxIsNumeric(N_IN) || mxIsComplex(N_IN) ||
|
dawn@0
|
108 mxIsSparse(N_IN) || !mxIsDouble(N_IN) ) {
|
dawn@0
|
109 mexErrMsgTxt("RSUM_INPLACE: N should be doubles");
|
dawn@0
|
110 }
|
dawn@0
|
111 m=mxGetM(X_IN); /* rows */
|
dawn@0
|
112 n=mxGetN(X_IN); /* columns */
|
dawn@0
|
113
|
dawn@0
|
114 if (mxGetM(N_IN)*mxGetN(N_IN) != 1) {
|
dawn@0
|
115 mexErrMsgTxt("RSUM_INPLACE: N should be a scalar");
|
dawn@0
|
116 }
|
dawn@0
|
117
|
dawn@0
|
118 xp = mxGetPr(X_IN);
|
dawn@0
|
119 Np = mxGetPr(N_IN);
|
dawn@0
|
120 N = *Np;
|
dawn@0
|
121
|
dawn@0
|
122 if (m < ceil(N)) {
|
dawn@0
|
123 mexErrMsgTxt("RSUM_INPLACE: X should have at least N rows");
|
dawn@0
|
124 }
|
dawn@0
|
125
|
dawn@0
|
126 checkin_matrix((mxArray *) X_IN);
|
dawn@0
|
127
|
dawn@0
|
128 /* Do the actual computations in a subroutine */
|
dawn@0
|
129 rsmth(xp, N, m, n);
|
dawn@0
|
130
|
dawn@0
|
131 checkout_matrix((mxArray *) X_IN);
|
dawn@0
|
132 return;
|
dawn@0
|
133 }
|
dawn@0
|
134
|