Trouble with pointers in MEX file

3 views (last 30 days)
Alex
Alex on 11 Nov 2014
Commented: Alex on 11 Nov 2014
I am trying to write a function that takes in a couple of arrays, and returns a couple of arrays. I pretty much copied the syntax of the arrayProduct.c example.
/*==========================================================
* trainstumps.c
*
* Calculates the optimal threshold, toggle, and error
* given weights and feature scores
*
* The calling syntax is:
*
* [threshold, toggle, error] = trainstumps(pos_features, neg_features, pos_weights, neg_weights)
*
*
*
*========================================================*/
#include "mex.h"
/* The computational routine */
void trainstumps(double *pos_features, double *neg_features,
double *pos_weights, double *neg_weights, double *threshold,
double *toggle, double *error, mwSize p, mwSize n, mwSize f)
{
mwSize i;
for (i=0; i<f; i++) {
int feat_i[p+n];
mwSize j;
for (j=0; j<p; j++) {
feat_i[j] = pos_features[j][i];
}
for (j=0; j<n; j++) {
feat_i[p+j] = neg_features[j][i];
}
sort(feat_i, feat_i + p + n);
double t;
double e_star = 2;
double t_star = 0;
double toggle_star = 0;
double error_plus;
double error;
double toggle;
for (j=1; j<p+n; j++) {
if (feat_i[j] = feat_i[j-1] && j>1) {
continue;
}
t = (feat_i[j]+feat_i[j-1])/2;
error_plus = 0;
mwSize k;
for (k=0; k<p; k++) {
if(pos_features[k][i] <= t) error_plus += pos_weights[k];
}
for (k=0; k<n; k++) {
if(neg_features[k][i] > t) error_plus += neg_weights[k];
}
if (error_plus <= .5) {
error = error_plus;
toggle = 1;
} else {
error = 1-error_plus;
toggle = -1;
}
if (error < e_star) {
e_star = error;
t_star = t;
toggle_star = toggle;
}
}
threshold[i] = t_star;
toggle[i] = toggle_star;
error[i] = e_star;
}
}
/* The gateway function */
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
double *pos_features; /* PxF input pos feature score matrix */
double *neg_features; /* NxF input neg feature score matrix */
double *pos_weights; /* Px1 input pos weight matrix */
double *neg_weights; /* Nx1 input pos weight matrix */
size_t p; /* num of pos imgs */
size_t n; /* num of neg imgs */
size_t f; /* num of features */
double *threshold; /* 1xF output threshold matrix */
double *toggle; /* 1xF output toggle matrix */
double *error; /* 1xF output error matrix */
/* check for proper number of arguments */
if(nrhs!=4) {
mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nrhs","4 inputs required.");
}
if(nlhs!=3) {
mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nlhs","3 output required.");
}
/* create a pointer to the real data in the input matricies */
pos_features = mxGetPr(prhs[0]);
neg_features = mxGetPr(prhs[1]);
pos_weights = mxGetPr(prhs[2]);
neg_weights = mxGetPr(prhs[3]);
/* get dimensions of the input matricies */
p = mxGetM(prhs[0]);
n = mxGetM(prhs[1]);
f = mxGetN(prhs[1]);
/* create the output matricies */
plhs[0] = mxCreateDoubleMatrix(1,(mwSize)f,mxREAL);
plhs[1] = mxCreateDoubleMatrix(1,(mwSize)f,mxREAL);
plhs[2] = mxCreateDoubleMatrix(1,(mwSize)f,mxREAL);
/* get a pointer to the real data in the output matricies */
threshold = mxGetPr(plhs[0]);
toggle = mxGetPr(plhs[1]);
error = mxGetPr(plhs[2]);
/* call the computational routine */
trainstumps(pos_features, neg_features, pos_weights, neg_weights, threshold, toggle, error, (mwSize)p, (mwSize)n, (mwSize)f);
}
I get compiler errors on lines 30,33,58,61,80,81 saying 'subscripted value is neither array nor pointer'. So for example, toggle[i] is a problem. From what I understand, double *toggle; makes toggle a pointer, and toggle = mxGetPr(plhs[1]); points it at an array. So when I pass double *toggle, we should be back to an array?
I don't see how my code differs from the example in this regard.
Any thoughts are appreciated.
Thanks, Alex

Accepted Answer

Geoff Hayes
Geoff Hayes on 11 Nov 2014
Alex - the errors, subscripted value is not an array, pointer, or vector, at lines 80 and 81 of the code
toggle[i] = toggle_star;
error[i] = e_star;
can be explained because you have created local variables with the same names within the outer loop
double error;
double toggle;
So it is these local variables that are being used as arrays instead of the two input parameters of the same name. Just rename the local variables to something different, and these two errors should disappear.
As for the two error messages that correspond to
feat_i[j] = pos_features[j][i];
and
feat_i[p+j] = neg_features[j][i];
look how you are declaring these two input variables pos_features and neg_features in the function signature
void trainstumps(double *pos_features, double *neg_features,...
The function is treating these inputs as vectors because that is how they have been declared in the signature, but the code body is treating them as matrices (multidimensional arrays). Hence the error. You have two options - leave the function signature as is and modify your assignment code to something like
feat_i[j] = pos_features[j*f + i];
and
feat_i[p+j] = neg_features[j*f + i];
Make sure that you verify that the above, j*f + i, makes sense given the dimensions of your matrices.
Or, you can change the signature of the function to
void trainstumps(double **pos_features, double **neg_features,...
and the calling of this function to
trainstumps(&pos_features, &neg_features,...

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!