matlab coder:当它应该始终是 2-D 时,不能转置被错误地认为是 3-D 的矩阵
Posted
技术标签:
【中文标题】matlab coder:当它应该始终是 2-D 时,不能转置被错误地认为是 3-D 的矩阵【英文标题】:matlab coder: cannot transpose a matrix that is incorrectly deemed to be 3-D when it should always be 2-D 【发布时间】:2014-11-11 20:39:45 【问题描述】:我有一个函数(代码如下),我希望将其转换为 MEX 文件。我正在尝试使用 matlab 编码器来做到这一点。
%% Inputs
dof = 3;
num_divs = 72;
ind_cr =
0 0
1 1
1 2
2 2
1 3
2 3
3 3
ind_switch =
1
1
1
0
1
0
0
len_stat_atoms =
1
72
5184
72
373248
5184
72
num_stat_atoms =
108
111
111
3
111
3
3
coordFile =
[3x1 double]
[3x1 double]
[3x72x3 double]
[3x5184x3 double]
[3x373248x4 double]
radii_cell =
[108x1x3 double]
[111x72x3 double]
[111x5184x3 double]
[ 3x72x3 double]
[111x373248x4 double]
[ 3x5184x4 double]
[ 3x72x4 double]
stat_cell =
[3x1x108 double]
[3x72x111 double]
[3x5184x111 double]
[3x72x3 double]
[3x373248x111 double]
[3x5184x3 double]
[3x72x3 double]
%% Code that calls function
for i = 1:(dof*(dof+1)/2+1)
%% Load matrices
radii_mat = radii_celli,1;
stat_mat = stat_celli,1;
if ind_switch(i)
coordFile_mat = coordFileind_cr(i,2)+2;
end
%% Call the function
potential_mat = func_test(i,coordFile_mat,radii_mat,stat_mat,...
ind_cr,len_stat_atoms,num_stat_atoms,num_coord_atoms,...
counter,num_divs,dof);
end
%% Function code
function potential_mat = func_test(i,coordFile_mat,radii_mat,stat_mat,...
ind_cr,len_stat_atoms,num_stat_atoms,num_coord_atoms,...
counter,num_divs,dof);
potential_mat = zeros(num_coord_atoms,num_divs^dof);
for j = 1:size(coordFile_mat,3)
%% Compute distances
a = zeros(3,len_stat_atoms(i));
a = coordFile_mat(:,1:len_stat_atoms(i),j);
b = zeros(3,len_stat_atoms(i),num_stat_atoms(i));
b = repmat(a,[1 1 num_stat_atoms(i)]);
c = zeros(1,len_stat_atoms(i),num_stat_atoms(i));
c = sqrt(sum((b - stat_mat).^2,1));
d = zeros(len_stat_atoms(i),num_stat_atoms(i));
d = shiftdim(c,1);
distances = zeros(num_stat_atoms(i),len_stat_atoms(i));
distances = d';
%% Compute ***es and potentials
***es = distances < radii_mat(:,:,j);
potentials = zeros(size(distances));
potentials(***es) = (1-(distances(***es)./radii_mat(find(***es)+numel(***es)*(j-1))).^6).^2;
%% Iterate over nodes
col = ind_cr(i,1); row = ind_cr(i,2);
if col == 1
ind_kron = repmat(1:size(potentials,2),[num_divs^(dof-row) 1]);
potentials = potentials(:,ind_kron(:)');
elseif row == dof
vec_repmat = [1 num_divs^(col-1)];
potentials = repmat(potentials,vec_repmat);
elseif col > 0
vec_repmat = [1 num_divs^(col-1)];
ind_kron = repmat(1:size(potentials,2),[num_divs^(dof-row) 1]);
potentials = repmat(potentials(:,ind_kron(:)'),vec_repmat);
else
potentials = repmat(sum(potentials),[1 num_divs^dof]);
end
counter = counter+1;
potential_mat(counter,:) = sum(potentials,1);
end
end
问题出现在下面的第二行,因为它无法转置 ND 矩阵而引发错误。
d = shiftdim(c,1);
distances = d';
Matlab 编码器将c
的大小识别为1 x :? x :?
,这是正确的。然后d = shiftdim(c,1)
行应该产生一个大小为:? x :?
的二维矩阵,然后我将其转置。但是,它无法正确移动d
的尺寸,并赋予它:? x :? x :?
的大小。这会导致转置错误。我该如何解决这个问题?此外,为了我自己的启迪,为什么matlab编码器无法正确分配我的变量的维度,具体是a
、b
、c
、d
和distances
?
【问题讨论】:
【参考方案1】:文档将其描述为Incompatibility with MATLAB in Determining Size of Variable-Size N-D Arrays(d
是在循环中创建的,因此似乎是可变大小):
对于可变大小的 N 维数组,size 函数在生成的代码中返回的结果可能与在 MATLAB 中不同。 在生成的代码中,size(A) 返回一个固定长度的输出,因为它不会丢弃可变大小 N 维数组的尾随单一维度。相比之下,MATLAB 中的 size(A) 返回一个可变长度的输出,因为它删除了尾随的单一维度。
例如,如果数组
生成代码中的三元素向量 MATLAB 代码中的二元向量A
的形状是:?x:?x:?
和size(A,3)==1
,size(A)
返回:
上述文档中解决的问题与size
函数的使用有关。但是,在您的情况下,您只希望能够转置。解决方法是使用permute
,因为转置是permute
的一般情况:
% after shiftdim:
distances = permute(d,[2 1 3]) % same as d' for 2d array, but handles 3d
您也可以完全删除shiftdim
:
distances = permute(c,[2 3 1])
另外,我对 Coder 没有太多经验,但它真的需要使用 zeros
进行所有这些初始化吗?它们似乎没有必要。
【讨论】:
以上是关于matlab coder:当它应该始终是 2-D 时,不能转置被错误地认为是 3-D 的矩阵的主要内容,如果未能解决你的问题,请参考以下文章