如何向矩阵添加尾随单维
How can I add a trailing singleton dimension to a matrix
正如标题所说,如何在 Matlab 中向矩阵添加尾随单维度?
A=ones(3,3,1);
给出一个 3x3 矩阵,而 A=ones(1,3,3);
给出一个 1x3x3 矩阵
添加到具体问题:
我有一个应用程序,其中有 N 个 MxM 矩阵,我需要堆叠它们,结果变成 MxMxN 矩阵。但是,N可以为1,如果是,我需要矩阵为MxMx1。
注意:我知道这对 Matlab 脚本来说意义不大,因为 Loren suggested,在 Matlab 中,在非单例维度之后有无限的 "singleton" 维度。但是,这在使用 mxGetNumberOfDimensions
的 mex 环境中是不同的。
即使从 MEX API 的角度来看,MATLAB 也删除了尾随的单例。 docs for mxSetDimensions
说了这么多:
MATLAB® automatically removes any trailing singleton dimensions specified in the dims
argument. For example, if ndim
equals 5 and dims
equals [4 1 7 1 1], the resulting array has the dimensions 4-by-1-by-7.
同样,这来自 mxSetDimensions
文档。
这是一个用 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
returns 2.
的情况
您可以使用 permute
将尾随默认单一维度注入非尾随位置。例如:
A = rand(50,50); % produces a 50 x 50 matrix
B = permute(A, [1 3 2]); % produces a 50 x 1 x 50 array
这里,3指的是数组中的第三个维度,一个隐含的大小为1的维度。
正如标题所说,如何在 Matlab 中向矩阵添加尾随单维度?
A=ones(3,3,1);
给出一个 3x3 矩阵,而 A=ones(1,3,3);
给出一个 1x3x3 矩阵
添加到具体问题:
我有一个应用程序,其中有 N 个 MxM 矩阵,我需要堆叠它们,结果变成 MxMxN 矩阵。但是,N可以为1,如果是,我需要矩阵为MxMx1。
注意:我知道这对 Matlab 脚本来说意义不大,因为 Loren suggested,在 Matlab 中,在非单例维度之后有无限的 "singleton" 维度。但是,这在使用 mxGetNumberOfDimensions
的 mex 环境中是不同的。
即使从 MEX API 的角度来看,MATLAB 也删除了尾随的单例。 docs for mxSetDimensions
说了这么多:
MATLAB® automatically removes any trailing singleton dimensions specified in the
dims
argument. For example, ifndim
equals 5 anddims
equals [4 1 7 1 1], the resulting array has the dimensions 4-by-1-by-7.
同样,这来自 mxSetDimensions
文档。
这是一个用 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
returns 2.
您可以使用 permute
将尾随默认单一维度注入非尾随位置。例如:
A = rand(50,50); % produces a 50 x 50 matrix
B = permute(A, [1 3 2]); % produces a 50 x 1 x 50 array
这里,3指的是数组中的第三个维度,一个隐含的大小为1的维度。