-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCmean2.c
148 lines (129 loc) · 4.78 KB
/
Cmean2.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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/*
* Computes the mean of a matrix
*
* INPUT:
* matrix: [double] or [float]
* dim : [int] dimension to calculate mean along (up to 2D matrices)
*
* OUTPUT:
* mean : the mean of the given vector/matrix
*
* Sagi Perel, 02/2012
*/
//#include <string.h> /* needed for memcpy() */
#include "mex.h"
int debug=0;
void matrix_mean(double* matrix, int num_rows, int num_cols, double** mean, int dim)
{
int i,j;
double* mean_ptr = (*mean);
if(dim==1)
{
//add up the columns
for(i=0; i<num_cols; i++)
for(j=0; j<num_rows; j++)
mean_ptr[i] += matrix[i*num_rows+j];
//compute the mean
for(i=0; i<num_cols; i++)
mean_ptr[i] = mean_ptr[i]/num_rows;
}else{
//add up the rows
for(i=0; i<num_rows; i++)
for(j=0; j<num_cols; j++)
mean_ptr[i] += matrix[i+j*num_rows];
//compute the mean
for(i=0; i<num_rows; i++)
mean_ptr[i] = mean_ptr[i]/num_cols;
}
}
void matrix_mean_f(float* matrix, int num_rows, int num_cols, float** mean, int dim)
{
int i,j;
float* mean_ptr = (*mean);
//add up the columns
for(i=0; i<num_cols; i++)
for(j=0; j<num_rows; j++)
mean_ptr[i] += matrix[i*num_rows+j];
for(i=0; i<num_cols; i++)
mean_ptr[i] = mean_ptr[i]/num_rows;
}
void
mexFunction(
int num_output_args, // Number of left hand side (output) arguments
mxArray *output_arg[], // Array of left hand side arguments
int num_input_args, // Number of right hand side (input) arguments
const mxArray *input_arg[]) // Array of right hand side arguments
{
double *matrix, *mean, *double_ptr;
float *matrix_f, *mean_f, *float_ptr;
int num_rows, num_cols, i;
int dim, mean_len;
mxClassID matrix_type;
size_t bytes_to_copy;
//sanity check for input arguments
if( num_input_args < 1 || num_input_args > 2)
mexErrMsgTxt( "Cmean2.c: wrong syntax: You should use Cmean2(matrix,[dim])\n");
matrix_type = mxGetClassID(input_arg[0]);
if( matrix_type != mxDOUBLE_CLASS && matrix_type != mxSINGLE_CLASS )
mexErrMsgTxt( "Cmean2.c: the matrix must of type double or float\n");
if(mxGetNumberOfDimensions(input_arg[0]) > 2)
mexErrMsgTxt( "Cmean2.c: does not support matrices with more than two dimensions\n");
if(num_input_args==1)
{
dim =1;
}else{
double_ptr = (double *) mxGetData( input_arg[1]);
dim = (int)(*double_ptr);
if(dim != 1 && dim != 2)
mexErrMsgTxt( "Cmean2.c: dim must be either 1 (default) or 2 \n");
}
num_rows = mxGetM(input_arg[0]);
num_cols = mxGetN(input_arg[0]);
if(debug)
printf("input_arg[0] size = [%d,%d]\n",num_rows,num_cols);
//read input arguments:
//-read the matrix
switch(matrix_type)
{
case mxDOUBLE_CLASS:
matrix = (double *) mxGetData( input_arg[0]);
if(dim==1)//calculate mean across the columns
mean_len = num_cols;
else //calculate mean across the rows
mean_len = num_rows;
mean = (double*) mxCalloc(mean_len, sizeof(double));
matrix_mean(matrix, num_rows, num_cols, &mean, dim);
//create an output array
if(dim==1)
output_arg[0] = mxCreateDoubleMatrix(1, num_cols, mxREAL);
else
output_arg[0] = mxCreateDoubleMatrix(num_rows, 1, mxREAL);
double_ptr=mxGetPr(output_arg[0]);//works only for double arrays
for(i=0; i<mean_len; i++)
double_ptr[i] = mean[i];
//free memory
mxFree((void*)mean);
break;
case mxSINGLE_CLASS:
matrix_f = (float *) mxGetData( input_arg[0]);
if(dim==1)//calculate mean across the columns
mean_len = num_cols;
else //calculate mean across the rows
mean_len = num_rows;
mean_f = (float*) mxCalloc(mean_len, sizeof(float));
matrix_mean_f(matrix_f, num_rows, num_cols, &mean_f, dim);
//create an output array
if(dim==1)
output_arg[0] = mxCreateNumericMatrix(1, num_cols, mxSINGLE_CLASS, mxREAL);
else
output_arg[0] = mxCreateNumericMatrix(num_rows, 1, mxSINGLE_CLASS, mxREAL);
float_ptr = (float*)mxGetData(output_arg[0]);
for(i=0; i<mean_len; i++)
float_ptr[i] = mean_f[i];
//bytes_to_copy = num_cols * mxGetElementSize(output_arg[0]);
//memcpy(float_ptr,&mean_f,bytes_to_copy);
//free memory
mxFree((void*)mean_f);
break;
}
}