Cri*_*ngo 12 arrays matlab types casting complex-numbers
自MATLAB R2018a以来,复值矩阵在内部存储为单个数据块,每个矩阵元素的实部和虚部存储在彼此相邻的位置 - 它们称之为"交错复合体".(以前这样的矩阵有两个数据块,一个用于所有实际组件,一个用于所有虚构组件 - "单独复杂".)
我认为,由于存储现在允许它,因此应该可以将复值数组转换为具有两倍元素的实值数组,而无需复制数据.
MATLAB有一个函数typecast
,它将数组转换为不同类型而不复制数据.例如,它可以用于将具有16个8位值的数组转换为具有2个双浮点数的数组.它在不复制数据的情况下执行此操作,将位模式重新解释为新类型.
遗憾的是,这个函数在复值数组上根本不起作用.
我想复制这段代码:
A = fftn(randn(40,60,20)); % some random complex-valued array
assert(~isreal(A))
sz = size(A);
B = reshape(A,1,[]); % make into a vector
B = cat(1,real(B),imag(B)); % interleave real and imaginary values
B = reshape(B,[2,sz]); % reshape back to original shape, with a new first dimension
assert(isreal(B))
Run Code Online (Sandbox Code Playgroud)
矩阵A
和B
(在R2018a和更新版本中)完全相同的数据,完全相同的顺序.但是,为了达到目的,B
我们必须将数据复制两次.
我尝试创建一个MEX文件来执行此操作,但我没有看到如何创建一个引用输入数组中的数据的新数组.这个MEX文件有效,但是在清除变量时会导致MATLAB崩溃,因为有两个数组引用相同的数据而没有意识到它们共享数据(即引用计数没有递增).
// Build with:
// mex -R2018a typecast_complextoreal.cpp
#include <mex.h>
#if MX_HAS_INTERLEAVED_COMPLEX==0
#error "This MEX-file must be compiled with the -R2018a flag"
#endif
#include <vector>
void mexFunction(int /*nlhs*/, mxArray* plhs[], int nrhs, const mxArray* prhs[]) {
// Validate input
if(nrhs != 1) {
mexErrMsgTxt("One input argument expected");
}
if(!mxIsDouble(prhs[0]) && !mxIsSingle(prhs[0])) {
mexErrMsgTxt("Only floating-point arrays are supported");
}
// Get input array sizes
mwSize nDims = mxGetNumberOfDimensions(prhs[0]);
mwSize const* inSizes = mxGetDimensions(prhs[0]);
// Create a 0x0 output matrix of the same type, but real-valued
std::vector<mwSize> outSizes(nDims + 1, 0);
plhs[0] = mxCreateNumericMatrix(0, 0, mxGetClassID(prhs[0]), mxREAL);
// Set the output array data pointer to the input array's
// NOTE! This is illegal, and causes MATLAB to crash when freeing both
// input and output arrays, because it tries to free the same data
// twice
mxSetData(plhs[0], mxGetData(prhs[0]));
// Set the output array sizes
outSizes[0] = mxIsComplex(prhs[0]) ? 2 : 1;
for(size_t ii = 0; ii < nDims; ++ii) {
outSizes[ii + 1] = inSizes[ii];
}
mxSetDimensions(plhs[0], outSizes.data(), outSizes.size());
}
Run Code Online (Sandbox Code Playgroud)
我很想听听有关如何从这里开始的任何想法.我不一定需要修复MEX文件,如果解决方案纯粹是MATLAB代码,那就更好了.
请参阅此 FEX 提交,它可以在不复制数据的情况下执行复杂的 --> 2 reals 重新解释(它甚至可以指向数据的内部连续子部分而无需复制):
如果您只是在 R2018a 及更高版本中读写交错的复杂数据文件,请参阅此 FEX 提交:
https://www.mathworks.com/matlabcentral/fileexchange/77530-freadcomplex-and-fwritecomplex