1

I'm using the mxCreateNumericMatrix function at my mex file:

mxArray *mxCreateNumericMatrix(mwSize m, mwSize n, mxClassID classid, mxComplexity ComplexFlag);

I want to get array of type mwSize. For that I need to determine if using mxUINT32_CLASS or mxUINT64_CLASS as classid.

I can determine it in runtime with if statement on sizeof(mwSize), but is there a more elegant way to determine the class ID of mwSize? Maybe some define that depends on the system which has one value or the other?

Just a matter of aesthetics.

BTW, at Fortran there is a function mxClassIDFromClassName: http://www.mathworks.com/help/matlab/apiref/mxclassidfromclassname.html

mwSize is used for among the other reasons, so that the mxCreateDoubleMatrix function will be portable. It is strange if no elegant solution exists for mxCreateNumericMatrix.

Edit:

As @Praetorian explained, in my case I have no reason to use the type that fits the system (32 or 64 bits), as I specifically prefer it to be 64-bit integer array, and I can define this size also in 32-bit system.

But on the other hand, I also want to return two indices to the array that I return. In my case, I know that the array itself is short, and I use uint16_T anyway, but if I wanted it to fit the mwIndex, I would have to use some macro (@Amro suggested some good options), because apparently, there is no function as mxCreateDoubleMatrix for integers (that fits the system).

To sum it up, @Praetorian helped me with my case in the comments below and @Amro gave probably the best options available for the general case.

ip84
  • 190
  • 1
  • 1
  • 9
  • Are you using C or C++? – Praetorian Jul 31 '13 at 15:41
  • @Praetorian I'm using **C** – ip84 Jul 31 '13 at 18:50
  • In that case your best option for determining 32/64 bit at compile time is to use macros. Perhaps `#if SIZE_MAX == UINT64_MAX` will work – Praetorian Jul 31 '13 at 18:57
  • I hadn't actually read your question completely earlier. I don't understand why you want to create a matrix containing `mwSize` elements; typically one creates matrices containing one of the [mxClassID](http://www.mathworks.com/help/matlab/apiref/mxclassid.html) types, at least if you want to be able to operate on that matrix from the MATLAB side. Maybe if you could explain your use case a bit more, an alternative solution can be found. – Praetorian Jul 31 '13 at 19:17
  • @Praetorian I create the matrix (actually an array) in order to return it as an **output parameter of the mex function**. I used the `mwSize` because it was explained at the documentation about mex file that it's the way to do it if you want your code to be portable (they also mentioned `mwIndex`). In the example I saw, they used `mxCreateDoubleMatrix` function, and I searched for alternative function, for returning integer type. – ip84 Jul 31 '13 at 22:00
  • 2
    I think you've misinterpreted the documentation. To create a matrix (or vector) use `mxCreateNumericMatrix` with the appropriate `mxClassID` depending on the data type of elements you want. When you have a variable in your code referring to the *size* of a matrix, make sure the type of that variable is `mwSize`. This ensures that when you recompile the mex source when switching platforms, everything will compile and function correctly. That's the portability they're talking about, not binary portability as you seem to have interpreted that as. – Praetorian Jul 31 '13 at 22:05
  • @Praetorian If I use mxUINT64_CLASS and I'm at 32-bit system, I guess it will give me an error rather than interpret it as mxUINT32_CLASS (which maybe would be reasonable in this case). Right? – ip84 Jul 31 '13 at 22:18
  • 1
    It'll do neither. You can create a matrix containing 64-bit integers even if you're on a 32-bit system. – Praetorian Jul 31 '13 at 22:23
  • @Praetorian You are right. Anyway I've already replaced all the definitions of integers to uint8_t, uint16_t, uint32_t etc, as was suggested. Thank you! – ip84 Jul 31 '13 at 22:34

2 Answers2

3

The goal of mxCreateNumericMatrix and other mxCreate* functions is to create an mxArray (MATLAB fundamental type). Such arrays can be returned to MATLAB from the MEX-function.

mwSize is just a typedef to a size_t type (might be different for 32-bit vs. 64-bit), which is not a valid MATLAB datatype (not part of mxClassID). If actually you want to create an array of mwSize, allocate memory in C the usual way mxMalloc (but I doubt this is what you want in this case).


As Praetorian notes, the actual C type to which mwSize and mwIndex are typedef'ed is determined by the flags you pass to the mex command (or the default value if you didnt explicitly specify one):

>> mex -largeArrayDims file.c
>> mex -compatibleArrayDims file.c

If we inspect the tmwtypes.h header file which gets included, here is the relevant block of code:

#ifdef MX_COMPAT_32
typedef int mwSize;
typedef int mwIndex;
typedef int mwSignedIndex;
#else
typedef size_t    mwSize;         /* unsigned pointer-width integer */
typedef size_t    mwIndex;        /* unsigned pointer-width integer */
typedef ptrdiff_t mwSignedIndex;  /* a signed pointer-width integer */
#endif

(Recall that size_t is itself platform-dependent).


As mentioned in the comments above, I think you are misinterpreting the documentation. mwIndex and mwSize are meant to be used when indexing into a matrix and when dealing with matrix sizes respectively when writing MEX-function (instead of using non-portable plain int). They do not have corresponding mxClassID (so you cannot create mxArray's of those types and pass them back to MATLAB).

Now if you want to create an array of indices and return it to MATLAB to be used as a regular variable, you could create an mxArray of the equivalent type to unsigned integers (matching the bit-ness of your architecture: 32-bit vs 64-bit). Use macros to determine which one you are compiling for, and use mxUINT32_CLASS or mxUINT64_CLASS accordingly.

For example, we could use the same macro MATLAB is using:

#ifdef MX_COMPAT_32
typedef mxUINT32_CLASS INDICES_CLASS;
#else
typedef mxUINT64_CLASS INDICES_CLASS;
#endif

mxArray *arr = mxCreateNumericMatrix(10, 1, INDICES_CLASS, mxReal);
// ... fill arr with indices
Community
  • 1
  • 1
Amro
  • 123,847
  • 25
  • 243
  • 454
  • `mwSize` can also be `int` if the `-largeArrayDims` switch is not passed to the mex function (I believe this switch is set by default) – Praetorian Jul 31 '13 at 18:54
  • I create the matrix in order to return it as an output parameter of the mex function. I used the mwSize because it was explained at the documentation about mex file that it's the way to do it if you want your code to be portable (they also mentioned mwIndex). This is my first time using mex file, and I'm pretty new with Matlab, so I followed the recommendations. I don't know if I can return the matrix using mxMalloc, but I see that I still would have to determine if it's 32-bit or 64-bit. – ip84 Jul 31 '13 at 19:02
0

Have you tried mxClassIDFromClassName in C? According to this list of undocumented libmx functions discussed here, it seems to exist. But yes, if you want to stick to what is listed in the online documentation, I don't know of a way other than using an if statement. Creating things other than double matrices in mex is always messier.

horchler
  • 18,384
  • 4
  • 37
  • 73