-
Notifications
You must be signed in to change notification settings - Fork 36
/
int_hist.c
134 lines (123 loc) · 2.57 KB
/
int_hist.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
* INT_HIST(x, n) is a histogram of all integer values 1..n in x.
* If n is not given, max(x) is used.
*/
#include "mex.h"
#include "util.h"
#define GetMax(T) \
{ T *indata = mxGetData(nArray); \
bins = indata[0]; \
for(i=0;i<len;i++) { \
if(indata[i] > bins) bins = indata[i]; \
} \
}
#define Loop(T) \
{ T *indata = mxGetData(nArray); \
for(i=0;i<len;i++) { \
mwSize v = (mwSize)(*indata++) - 1; \
if((v < 0) || (v >= bins)) \
mexErrMsgTxt("value out of bounds"); \
outdata[v]++; \
} \
}
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
mwSize len, i, bins;
double *outdata;
mxClassID class;
const mxArray *nArray;
if((nrhs < 1) || (nrhs > 2))
mexErrMsgTxt("Usage: h = int_hist(x, n)");
/* prhs[0] is first argument.
* mxGetPr returns double* (data, col-major)
* mxGetM returns int (rows)
* mxGetN returns int (cols)
*/
nArray = prhs[0];
class = mxGetClassID(nArray);
len = mxGetNumberOfElements(nArray);
if(mxIsSparse(nArray))
mexErrMsgTxt("Cannot handle sparse matrices. Sorry.");
if(len == 0) {
plhs[0] = mxCreateDoubleMatrix(1, 0, mxREAL);
return;
}
if(nrhs == 2) {
if(mxGetNumberOfElements(prhs[1]) != 1) mexErrMsgTxt("n is not scalar.");
bins = *mxGetPr(prhs[1]);
} else {
switch(class) {
case mxDOUBLE_CLASS:
GetMax(double);
break;
case mxSINGLE_CLASS:
GetMax(float);
break;
case mxUINT8_CLASS:
GetMax(uint8_T);
break;
case mxUINT16_CLASS:
GetMax(uint16_T);
break;
case mxUINT32_CLASS:
GetMax(uint32_T);
break;
case mxUINT64_CLASS:
GetMax(uint64_T);
break;
case mxINT8_CLASS:
GetMax(int8_T);
break;
case mxINT16_CLASS:
GetMax(int16_T);
break;
case mxINT32_CLASS:
GetMax(int32_T);
break;
case mxINT64_CLASS:
GetMax(int64_T);
break;
default:
mexErrMsgTxt("First argument is not a supported type");
return;
}
}
/* plhs[0] is first output */
plhs[0] = mxCreateDoubleMatrix(1, bins, mxREAL);
outdata = mxGetPr(plhs[0]);
switch(class) {
case mxDOUBLE_CLASS:
Loop(double);
break;
case mxSINGLE_CLASS:
Loop(float);
break;
case mxUINT8_CLASS:
Loop(uint8_T);
break;
case mxUINT16_CLASS:
Loop(uint16_T);
break;
case mxUINT32_CLASS:
Loop(uint32_T);
break;
case mxUINT64_CLASS:
Loop(uint64_T);
break;
case mxINT8_CLASS:
Loop(int8_T);
break;
case mxINT16_CLASS:
Loop(int16_T);
break;
case mxINT32_CLASS:
Loop(int32_T);
break;
case mxINT64_CLASS:
Loop(int64_T);
break;
default:
mexErrMsgTxt("First argument is not a supported type");
}
}