Multidimensional arrays do not work in mex functions?

11 views (last 30 days)
I am slowly trying to integrate C/C++ functions into my MATLAB code, but I always have trouble with multidimensional arrays.. I am converting the following code to a mex function:
function [dphidtSum] = matsum4(dphidt,po,gnum,xynum)
dphidtSum = zeros(gnum,xynum);
for a=1:gnum
for b=1:gnum
if a~=b
ind = (po(a,:) & po(b,:));
if a>b
dphidtSum(a,ind) = dphidtSum(a,ind)-dphidt(ind,b,a)';
else
dphidtSum(a,ind) = dphidtSum(a,ind)+dphidt(ind,a,b)';
end
end
end
end
The following is my attempt:
void matsum(double *dphidt, double *po, int gnum, int xynum, double *dphidtSum)
{
long i;
long a;
long b;
for (i = 0; i<xynum; i++)
{
for (a = 0; a<gnum; a++)
{
for (b = 0; b<gnum; b++)
{
if (a!=b)
{
if (po[a][i] & po[b][i])
{
if (a>b) { dphidtSum[a][i] += -dphidt[i][b][a]; }
else { dphidtSum[a][i] += dphidt[i][a][b]; }
}
}
}
}
}
}
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
/* DECLARATIONS*/
double *po, *dphidt, *dphidtSum;
int gnum, xynum;
/* INPUTS */
gnum = mxGetScalar(prhs[0]);
xynum = mxGetScalar(prhs[1]);
po = mxGetPr(prhs[2]);
dphidt = mxGetPr(prhs[3]);
/* OUTPUTS */
plhs[0] = mxCreateDoubleMatrix(gnum,xynum,mxREAL); /*Creates a matrix*/
dphidtSum = mxGetPr(plhs[0]); /*Set to be the first of the output values*/
/* CALL ROUTINE */
matsum(dphidt,po,gnum,xynum,dphidtSum);
}
When I try to compile the mex function I get 6 "subscripted value is neither array nor pointer nor vector" errors, basically everywhere I try to access a multidimensional array. What the heck is wrong?

Answers (1)

James Tursa
James Tursa on 13 May 2019
Edited: James Tursa on 13 May 2019
You can't use multi-level [ ][ ]... syntax with simple pointers. E.g., look at these lines:
void matsum(double *dphidt, double *po, int gnum, int xynum, double *dphidtSum)
:
if (a>b) { dphidtSum[a][i] += -dphidt[i][b][a]; }
dphidt is a pointer-to-double
dphidt[i] is a double
dphidt[i][b] is an error ... you can't dereference a double. That's too many levels of indirection.
Same comment for po and dphidtSum.
So how to fix this? The simplest way is to manually calculate the equivalent linear index of the 2D or 3D indexing you are trying to do and use that inside a single pair of brackets [ ]. E.g., dphidtSum is a 2D matrix of dimension gnum X xynum. So this (invalid) expression:
dphidtSum[a][i]
would need to be replaced with
dphidtSum[ a + i*gnum ]
Similar fix for po. For your 3D array behind dphidt, you need to calculate the equivalent linear index of your 3D indexing and place that inside a single pair of brackets [ ] also.
If you insist on using the multi-level bracket syntax, you would need to allocate and fill in an array of column and page pointers. It can be done, but is usually not worth the effort IMO so I am not showing that code.

Categories

Find more on Resizing and Reshaping Matrices in Help Center and File Exchange

Products

Community Treasure Hunt

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

Start Hunting!