I have a function (with the code given below) that I wish to convert into a MEX file. I am trying to use matlab coder to do so.
%% 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
The problem occurs at the second line below, where it throws an error because it cannot transpose an ND matrix.
d = shiftdim(c,1);
distances = d';
Matlab coder identifies c
to be of size 1 x :? x :?
, which is correct. The d = shiftdim(c,1)
line should then yield a 2D matrix of size :? x :?
, which I then transpose. However, it fails to correctly shift the dimensions of d
, and gives it a size of :? x :? x :?
. This then causes the transpose error. How can I resolve this problem? Furthermore, for my own edification, why is matlab coder unable to correctly assign the dimensions of my variables, specifically a
, b
, c
, d
, and distances
?
The docs describe this as an Incompatibility with MATLAB in Determining Size of Variable-Size N-D Arrays (
d
is created in a loop, so seems to be variable size):The issue addressed in the above documentation pertains to the use of the
size
function. However, in your case, you just want to be able to transpose. The workaround is to usepermute
, since the transpose is a general case ofpermute
:You could also cut out the
shiftdim
entirely:Also, I don't have much experience with Coder, but does it really require all those initializations with
zeros
? They seem unnecessary.