Как я могу добавить конечное одноэлементное измерение в матрицу

Как видно из заголовка, как я могу добавить конечное одноэлементное измерение в матрицу в Matlab?

A=ones(3,3,1); дает матрицу 3x3, в то время как A=ones(1,3,3); дает матрицу 1x3x3

Добавление к конкретной проблеме:

У меня есть приложение, в котором у меня N матриц MxM, и мне нужно сложить их, в результате получается матрица MxMxN. Тем не менее, N может быть 1, и если это так, мне нужно, чтобы матрица была MxMx1.

Примечание: я знаю, что для сценариев Matlab это не имеет большого смысла, как предположил Лорен, в Matlab существуют бесконечные "одноэлементные" измерения после не одноэлементных. Тем не менее, это иначе в мексиканской среде, где mxGetNumberOfDimensions используется.

2 ответа

Решение

Задний синглтон отбрасывается MATLAB даже с точки зрения MEX API. Документы дляmxSetDimensions скажи так:

MATLAB® автоматически удаляет любые задние размеры синглтона, указанные в dims аргумент. Например, если ndim равно 5 и dims равно [4 1 7 1 1], результирующий массив имеет размеры 4 на 1 на 7.

Опять же, это из mxSetDimensions Docs.

Вот тест, чтобы попробовать это с mxSetDimensions или же 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);
}

Тест MATLAB:

>> 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

Примечание с этим size(M,454235) тест: это то, что ndim документы означают, когда они говорят Trailing singleton dimensions are ignored, Их действительно не игнорируют, их просто нет!

Тест MEX (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

Я предлагаю адаптировать ваш код для обработки случая, когда mxGetNumberOfDimensions возвращает 2.

Ты можешь использовать permute вводить синглтон.

A = rand(50,50); %50 x 50
B = permute(A, [1 3 2]); %50 x 1 x 50

3 относится к трейлинг-синглтону по умолчанию. "4" не ссылается ни на что, поэтому вам нужно повторить несколько инъекций (вы также не можете повторить "3").

Другие вопросы по тегам