Multidimensional matrix multiplication with mex

8 views (last 30 days)
Hi
I am trying to do matrix multiplication via Mex.
So fare i have, using this as guide :
#include "mex.h"
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
float *x;
float *y;
double *z;
mwSize rFirst, cFirst, cSecond;
x = mxGetData(prhs[0]);
y = mxGetData(prhs[1]);
rFirst = mxGetM(prhs[0]);
cFirst = mxGetN(prhs[0]);
cSecond = mxGetN(prhs[1]);
plhs[0] = mxCreateDoubleMatrix(rFirst, cFirst, mxREAL);
z = mxGetPr(plhs[0]);
int i;
int j;
int k;
for(k = 0; k <= cSecond - 1 ; k++) {
for(i = 0; i <= rFirst - 1 ; i++) {
z[i][k] = 0;
for(j = 0; j <= cFirst - 1; j++) {
z[i][k] = z[i][k] + x[i][j]*y[j][k];
}
}
}
}
When i try and implement this i get the error:
> mex matrixMultiplication.c
error: subscripted value is neither array nor pointer
I then tried changing the script to:
float **x;
float **y;
double **z;
But that results in:
> mex matrixMultiplication.c
warning: assignment from incompatible pointer type
Does anyone know how to fix this?
Here is an extra question: I tried importing a mex file from File Exchange: mTimesx. I unzipped the folder and placed the content in my working directory. I then tried initializing it (Or what you call it).
> mex mTimesx.c
undefined reference to 'foobar'
I got this error many many times. How do you import a C-mex file correctly?
Hope someone knows the answers to these things :) Thanks in advance!!

Accepted Answer

James Tursa
James Tursa on 12 Apr 2017
Edited: James Tursa on 12 Apr 2017
Your basic problem is a misunderstanding of how pointers work in C. Take your z variable for instance:
double *z;
:
z = mxGetPr(plhs[0]);
:
z[i][k] = 0;
The variable z is a "pointer to double". You need to think of it as pointing into a linear array of double values. Since it points to a double, the result of dereferencing it once is a double. E.g., the expression z[i] by itself is a double ... it is not another pointer. So now when you try to apply another dereference with the [k] part, the compiler complains because z[i] is not a pointer so it can't be dereferenced. You can only dereference z once. In other words, you can't use two indexes with z the way you have z defined. You would need to manually calculate the location in memory and use that as a linear subscript. E.g., this would work:
z[i+k*rFirst] = 0;
Same comment applies to your x and y variables. You would need to manually calculate an equivalent linear index to use as a single subscript. E.g.
z[i+k*rFirst] = z[i+k*rFirst] + x[i+j*rFirst]*y[j+k*cFirst];
There are ways to use [i][k] subscripting, but you have to define your pointers differently and do some prep work up front to get things to work properly. I will not include that code here but will refer you to this link:
https://www.mathworks.com/matlabcentral/answers/309434-matlab-crashing-when-evaluating-mex
Additionally, you don't have your output dimensions correct. The line
plhs[0] = mxCreateDoubleMatrix(rFirst, cFirst, mxREAL);
should be
plhs[0] = mxCreateDoubleMatrix(rFirst, cSecond, mxREAL);
Also, I will point out that your code will likely crash MATLAB if the inputs are not exactly as expected. I.e., check that there are two inputs and they are each single class matrices and that their inner dimensions agree and that they are not complex. If you were to allow double class inputs, you would need to check that they were not sparse as well. You should put in code to check for those things.
Your second problem is that the author of the MTIMESX submission on the FEX has neglected for some time to get it updated for the newer MATLAB versions and for 64-bit machines. He needs to somehow get access to a newer MATLAB version with a C compiler and find some time to work on that. What MATLAB version are you using, and are you running 32-bit or 64-bit?
  7 Comments
James Tursa
James Tursa on 14 Apr 2017
If you are doing just the straightforward calculation (large 2D matrix) * (large 2D matrix), MTIMESX will not be able to help you.
Michael Madelaire
Michael Madelaire on 14 Apr 2017
Thank you very much for the help! Although I didn't find some black magic to speed up my simulations :)

Sign in to comment.

More Answers (0)

Categories

Find more on Write C Functions Callable from MATLAB (MEX Files) in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!