Das abschließende Singleton wird von MATLAB sogar aus der Sicht der MEX-API gelöscht. Die docs for mxSetDimensions
sagen so viel:
MATLAB® entfernt automatisch alle nachgestellten Singleton Dimensionen angegeben im dims
Argument. Wenn beispielsweise ndim
gleich 5 und dims
gleich [4 1 7 1 1] ist, hat das resultierende Array die Dimensionen 4-mal-1-mal-7.
Auch dies ist von der mxSetDimensions
docs.
Hier ist ein Test, dies zu versuchen, mit mxSetDimensions
oder mxCreateNumericArray
:
// mexSizeTest.cpp
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[])
{
if (nrhs!=1)
mexErrMsgTxt("Just one input please.");
mxArray *M = mxDuplicateArray(prhs[0]);
const mwSize ndimsOrig = mxGetNumberOfDimensions(M);
const mwSize *dimsOrig = mxGetDimensions(M);
mexPrintf("Number of dimensions (input): %d\n\n", ndimsOrig);
const mwSize ndims = ndimsOrig + 1;
mwSize *dims = (mwSize*) mxMalloc(ndims*sizeof(mwSize));
for (int i=0; i<ndimsOrig; ++i) dims[i] = dimsOrig[i];
dims[ndims-1] = 1;
mexPrintf("Target dimensions: [");
for (int i=0; i<ndims-1; ++i) mexPrintf("%d ",dims[i]);
mexPrintf("%d]\n\n",dims[ndims-1]);
mexPrintf("Reshaping to #dims = %d with trailing singleton.\n", ndims);
mxSetDimensions(M, dims, ndims);
mexPrintf("Number of Dimensions: %d\n\n", mxGetNumberOfDimensions(M));
// Let's be dangerous to see if the 1 is just hiding under the hood
const mwSize *dimsSet = mxGetDimensions(M);
mexPrintf("Being dangerous: %d\n\n", dimsSet[ndims-1]); // !!!
mxDestroyArray(M);
mexPrintf("Creating fresh mxArray of #dims = %d with trailing singleton.\n",
ndims);
M = mxCreateNumericArray(ndims, dims, mxDOUBLE_CLASS, mxREAL);
mexPrintf("Number of Dimensions: %d\n",mxGetNumberOfDimensions(M));
mxDestroyArray(M); mxFree(dims);
}
Der MATLAB-Test:
>> M = rand(24,55,1);
>> size(M)
ans =
24 55
>> ndims(M)
ans =
2
>> size(M,454235) % note we can check the 454235th dimension
ans =
1
Randbemerkung mit diesem size(M,454235)
Test: Das, was ist die ndim
docs meinen, wenn sie sagen, Trailing singleton dimensions are ignored
. Sie werden wirklich nicht ignoriert, sie sind einfach nicht wirklich da!
Das MEX-Test (mexSizeTest.cpp):
>> mexSizeTest(M)
Number of dimensions (input): 2
Target dimensions: [24 55 1]
Reshaping to #dims = 3 with trailing singleton.
Number of Dimensions: 2
Being dangerous: -994713024
Creating fresh mxArray of #dims = 3 with trailing singleton.
Number of Dimensions: 2
Ich schlage vor, den Code anzupassen, den Fall zu behandeln, in denen mxGetNumberOfDimensions
kehrt 2.
Ich dachte, eine 3x3 Matrix und ein 3x3x1 3D Array wären in Matlab wirklich gleich. Ist das nicht der Fall in Mex-Dateien? –
Haben Sie versucht, es einfach auf '[M M 1]' umzuformen? –
@LuisMendo In Mex-Dateien sind alle Daten (wie es intern in Matlab ist) ein 1D-Array mit Dimensionsdaten. Wenn Sie während der Kodierung eines mex-Wrappers überprüfen müssen, ob die Daten korrekt eingegeben wurden, benötigen Sie Funktionen wie 'mxGetNumberOfDimensions' oder' mxGetDimensions'. Wenn eine Eingabe 3D sein muss, aber eine der Dimensionen 1 sein kann, kann 'mxGetNumberOfDimensions == 3' nicht verwendet werden! –