Mex matlab编码器:当矩阵应始终为二维时,不能转换被错误视为三维的矩阵

Mex matlab编码器:当矩阵应始终为二维时,不能转换被错误视为三维的矩阵,mex,matlab-coder,Mex,Matlab Coder,我有一个函数(下面给出了代码),我希望将其转换为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

我有一个函数(下面给出了代码),我希望将其转换为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_cell{i,1};
    stat_mat = stat_cell{i,1};
    if ind_switch(i)
        coordFile_mat = coordFile{ind_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 clashes and potentials
    clashes = distances < radii_mat(:,:,j);
    potentials = zeros(size(distances));
    potentials(clashes) = (1-(distances(clashes)./radii_mat(find(clashes)+numel(clashes)*(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

Matlab编码器确定
c
的大小为
1 x:?x:?
,这是正确的。然后,
d=shiftim(c,1)
行应生成大小为
:?x:?
,然后我将其转置。但是,它无法正确移动
d
的维度,并将其大小设置为
:?x:?x:?
。这将导致转置错误。我如何解决这个问题?此外,出于我自己的启发,为什么matlab coder不能正确分配变量的维度,特别是
a
b
c
d
,和
距离

文档将其描述为(
d
是在循环中创建的,因此似乎是可变大小):

对于可变大小的N-D阵列,size函数在生成的代码中返回的结果可能与在MATLAB中返回的结果不同在生成的代码中,size(A)返回一个固定长度的输出,因为它不会删除可变大小N-D数组的尾随单例维度。相比之下,MATLAB中的size(A)返回一个可变长度的输出,因为它会删除后面的单个维度

例如,如果数组
A
的形状是
:?x:?x:?
大小(A,3)=1
大小(A)
返回:

  • 生成代码中的三元向量
  • MATLAB代码中的二元向量
上述文档中涉及的问题与
size
功能的使用有关。然而,在您的情况下,您只希望能够转置。解决方法是使用
permute
,因为转置是
permute
的一般情况:

% after shiftdim:
distances = permute(d,[2 1 3])   % same as d' for 2d array, but handles 3d
您也可以将
shiftim
完全剪掉:

distances = permute(c,[2 3 1])

另外,我对Coder没有太多经验,但它真的需要所有那些使用
零的初始化吗?它们似乎没有必要

distances = permute(c,[2 3 1])