matlab coder report Size mismatch (size [0 x 0] ~= size [1 x 2])

I tried to use matlab coder to convert my matlab file into C\C++ source file. In my *.m file,I defined a dynamic array:
...
coord_list = [];
I_list = [];
...
for i=1:n
....
coordinate = yy;
I = zz;
coord_list = [coord_list;coordinate];
I_list = [I_list;I]
end
The error occurs like:
??? Size mismatch (size [0 x 0] ~= size [1 x 2]).
The size to the left is the size of the left-hand side of the assignment.
How could I fix this bug? how should I modify my matlab code so that It meets the requirements of C\C++ style for matlab-coder?

1 Comment

hi Raghu,
I am alsp facing same issue like the error below:
Size mismatch (size [1 x 0] ~= size [16 x 0]).
need your help for solving it

Sign in to comment.

 Accepted Answer

...
coord_list = zeros(n, m1); % m1 is the length of yy below
I_list = zeros(n, m2); % m2 is the lenght of zz
...
for i=1:n
....
coordinate = yy;
I = zz;
coord_list(i, :) = coordinate;
I_list(i, :) = I;
end

14 Comments

the value of coordinate might be zero. Is there other ways to define coord_list and I_list?
sorry, I didn't express my question clearly , here are my complete structure:
...
coord_list = zeros(n, m1); % m1 is the length of yy below
I_list = zeros(n, m2); % m2 is the lenght of zz
...
for i=1:n
....
coordinate = yy;
I = zz;
coord_list(i, :) = coordinate;
I_list(i, :) = I;
%% handle with coord_list and I_list
coord_list = f(coord_list);
I_list = g(I_list);
%% the iteration stopped if the condition is meet
if condition
break
end
end
take coord_list as an example, the row of coord_list < n. If coord_list is defined as zeros(n, m1) in the beginning, how should I deal the zeros in coord_list?
coord_list = zeros(n, m1); % m1 is the length of yy below
coder.varsize('coord_list', [n, m1], [1 0]); %first dimension can vary, not second
That is:
...
coord_list = [];
I_list = [];
coder.varsize('coord_list', [n, m1], [1 0]);
coder.varsize('I_list', [n, m1], [1 0]);
...
for i=1:n
....
coordinate = yy;
I = zz;
coord_list = [coord_list;coordinate];
I_list = [I_list;I]
%% handle with coord_list and I_list
coord_list = f(coord_list);
I_list = g(I_list);
%% the iteration stopped if the condition is meet
if condition
break
end
end
Do it correct?
No you should assign it zeros before the coder call. The coder call is locking in the size of the second dimension, so with you having assigned [] you are locking in empty for the array
I changed the definition:
coord_list = zeros(0,2);
I_list = zeros(0,1);
coder.varsize('coord_list',[max_iter 2],[1 0]);
coder.varsize('I_list',[max_iter 1],[1 0]);
...
for i=1:max_iter
....
coordinate = yy;
I = zz;
coord_list = [coord_list;coordinate];
I_list = [I_list;I]
%% handle with coord_list and I_list
coord_list = f(coord_list);
I_list = g(I_list);
%% the iteration stopped if the condition is meet
if condition
break
end
end
error occurs that:
Dimension 1 is fixed on the left-hand side but varies on the right ([0 x 2] ~= [:40 x 2]). <a href="matlab:helpview('coder','msginfo_Coder_builtins_StaticDynamicSizeMismatchOnAssignment');">More information</a>
Dimension 1 is fixed on the left-hand side but varies on the right ([0 x 1] ~= [:40 x 1]). <a href="matlab:helpview('coder','msginfo_Coder_builtins_StaticDynamicSizeMismatchOnAssignment');">More information</a>
The problem was solved, thanks a lot!
One more question, I compare the execution time between **.mexw64 and **.m file( the same input, same output). The result indicate that in my implementation, the mex file cost much more time. Does such result make sense? Generally speaking , mex file runs faster than matlab file.
.mex files do not take advantage of automatic multi-threading that is used in MATLAB. The generated code needs to be able to be run on systems that only have single cores, or which do not have the ability to handle multiple threads, so the generated code is single-threaded.
@zhou caiwei "The result indicate that in my implementation, the mex file cost much more time."
Can you give details: how much is "much longer" and what is the function implementation and typical data size. It sounds not normal to me.
here is the one of the results.
I noticed that the mex file(generated from Matlab coder) takes twice as long to execute as the m file, no matter the data size.
TVSTORM processing time: 15.7764 seconds
TVSTORM mex processing time: 29.826 seconds
here is the test function which could be excute directly:
%% This is to test the TVSTORM algorithm with 2D STORM image reconstruction
close all;
clear;
clc;
%% Set up the parameters
density = 20; % emitter density (fluorophores per um^2)
pixelsize = 0.075; % camera pixel size (um)
width = 30; % image width (pixel)
height = 30; % image height (pixel)
g_noise = 5; % gaussian noise level (photons/pixel)
photons = 500; % average photon number
sigma = 1.5; % standard deviation of system PSF (pixel)
% measurement matrix for ADCG
div2 = 2;
A2 = STORM_2D_Gen_Meas_Mat(width, height, div2, sigma);
%% Generate simulated image
disp('Generating simulated image ...');
[im, emitterList] = STORM_2D_Simulation(density, pixelsize, ...
width, height, g_noise, photons, sigma);
%% TVSTORM
ns = 0.9;
thresh = 150;
t1 = tic;
[clustCent3, I_list3] = TVSTORM_2D_mex(A2, im, height, width, sigma, div2, ns, thresh);
disp(['TVSTORM processing time: ', num2str(toc(t1)), ' seconds']);
ns = 0.9;
thresh = 150;
t1 = tic;
[clustCent3, I_list3] = TVSTORM_2D_mex_mex(A2, im, height, width, sigma, div2, ns, thresh);
disp(['TVSTORM mex processing time: ', num2str(toc(t1)), ' seconds']);
here is the main function to build:
function [clustCent, I_list] = TVSTORM_2D_mex(A, im, height, width, sigma,...
div, ns, thresh)%#codegen
% PURPOSE:
% STORM 2D reconstruction using TVSTORM.
%---------------------------------------------------
% USAGE:
% [clustCent, I_list] = TVSTORM(A, im, height, width, sigma, div, ns, thresh)
%---------------------------------------------------
% INPUTS:
% A: measurement matrix
% im: acquired image
% height: image height
% width: image width
% sigma: standard deviation of system PSF (pixel)
% div: upsampling factor in x y-dimension
% ns: parameter that controls the balance between
% data fidelity and sparsity
% typically 1.5 is used for Poisson noise
% thresh: threshold for backward step
%---------------------------------------------------
% OUTPUTS:
% clustCent(:, 1): x coordinates (pixel)
% clustCent(:, 2): y coordinates (pixel)
% I_list: intensity list
%---------------------------------------------------
%% Pre-processing for TVSTORM
im = double(im(:));
eps = ns * sqrt(sum(im));
[xxx, yyy] = meshgrid(0.5 + 1 / div / 2 : 1 / div : width + 0.5 - 1 / div / 2,...
0.5 + 1 / div / 2 : 1 / div : height + 0.5 - 1 / div / 2);
%% Iterate
bg = min(im);
iter = 1;
max_iter = 40;
coder.varsize('coord_list',[200 2],[1 0]);
coder.varsize('I_list',[200 1],[1 0]);
coder.varsize('coord_list_before',[max_iter 2],[1 0]);
coder.varsize('I_list_before',[max_iter 1],[1 0]);
coord_list = zeros(0,2);
I_list = zeros(0,1);
coord_list_before = zeros(0,2);
I_list_before = zeros(0,1);
while iter < max_iter
% calculate the residual
im_gen = Gen_Im_From_2D_Coord(coord_list, I_list, height, width, sigma);
res = im - im_gen;
res_iter = norm(res);
% terminate if residual small enough
if res_iter <= eps
break;
end
if sum(I_list < thresh) ~= 0
if sum(I_list < thresh) == 1 && I_list(end) < thresh
coord_list = coord_list_before;
I_list = I_list_before;
break;
else
while sum(I_list < thresh) ~= 0
list = I_list > thresh;
coord_list = coord_list(list, :);
I_list = I_list(list, :);
[coord_list, I_list, bg] = Coordinate_Descent_2D(...
coord_list, I_list, bg, im, height, width, sigma);
end
break;
end
end
coord_list_before = coord_list;
I_list_before = I_list;
% find one atom
coeff = A' * (res - bg);
[~, idx] = max(coeff);
coord_list = [coord_list; xxx(idx), yyy(idx)];
I_list = [I_list; max(coeff(idx) / norm(A(:, idx)) ^ 2, 100)];
% coordinate descent on the support
[coord_list, I_list, bg] = Coordinate_Descent_2D(...
coord_list, I_list, bg, im, height, width, sigma);
iter = iter + 1;
end
clustCent = coord_list;
the related function files:
function [coord_list, I_list, bg] = Coordinate_Descent_2D(...
coord_list, I_list, bg, im, height, width, sigma)%#codegen
% PURPOSE:
% Gradient descent on 2D coordinate and weight refinement.
%---------------------------------------------------
% USAGE:
% [coord_list, I_list, bg] = Coordinate_Descent_2D(...
% coord_list, I_list, bg, height, width, sigma)
%---------------------------------------------------
% INPUTS:
% coord_list: list of input coordinate
% I_list: list of input intensity
% bg: background photon
% im: acquired image
% height: image height
% width: image width
% sigma: standard deviation of system PSF (pixel)
%---------------------------------------------------
% OUTPUTS:
% coord_list: list of output coordinate
% I_list: list of output intensity
% bg: background photon
%---------------------------------------------------
%%
iter = 1;
max_iter = 200;
[xx, yy] = meshgrid(1 : width, 1 : height);
xx_r = xx(:); yy_r = yy(:);
A = Gen_Meas_From_2D_Coord(coord_list, height, width, sigma);
coder.varsize('res_list',[1 max_iter],[0 1]);
res_list = zeros(1,0);
%%
while iter < max_iter
mu = A * I_list + bg;
res_list = [res_list, sum(mu - im .* log(mu + 1e-5))];
%% background descent
grad_bg = sum((mu - im) ./ (mu + 1e-5));
% backtracking
alpha = 0.5;
epsilon = 1;
if grad_bg > 0
epsilon = min(epsilon, bg / grad_bg);
end
df = -1e-6 * norm(grad_bg) ^ 2;
mu = A * I_list + bg;
fc = sum(mu - im .* log(mu + 1e-5));
bg_temp = bg - epsilon * grad_bg;
mu_base = A * I_list;
mu = mu_base + bg_temp;
while sum(mu - im .* log(mu + 1e-5)) > fc + epsilon * df
epsilon = epsilon * max(alpha, 0.1);
alpha = alpha * 0.8;
if epsilon < 1e-10
epsilon = 0;
break;
end
bg_temp = bg - epsilon * grad_bg;
mu = mu_base + bg_temp;
end
bg = bg - epsilon * grad_bg;
%%
for i = 1 : size(coord_list, 1)
%% intensity descent
temp_xx = erf((xx + 0.5 - coord_list(i, 1)) / sqrt(2) / sigma) -...
erf((xx - 0.5 - coord_list(i, 1)) / sqrt(2) / sigma);
temp_yy = erf((yy + 0.5 - coord_list(i, 2)) / sqrt(2) / sigma) -...
erf((yy - 0.5 - coord_list(i, 2)) / sqrt(2) / sigma);
grad_I = sum((mu - im) ./ (mu + 1e-5) .* temp_xx(:) .* temp_yy(:));
% backtracking
alpha = 0.5;
epsilon = 1000;
if grad_I > 0
epsilon = min(epsilon, I_list(i) / grad_I);
end
df = -1e-6 * norm(grad_I) ^ 2;
mu = A * I_list + bg;
fc = sum(mu - im .* log(mu + 1e-5));
I = I_list(i) - epsilon * grad_I;
mu_base = A(:, [1 : i - 1, i + 1 : end]) * I_list([1 : i - 1, i + 1 : end], :);
mu = mu_base + A(:, i) * I + bg;
while sum(mu - im .* log(mu + 1e-5)) > fc + epsilon * df
epsilon = epsilon * max(alpha, 0.1);
alpha = alpha * 0.8;
if epsilon < 1e-10
epsilon = 0;
break;
end
I = I_list(i) - epsilon * grad_I;
mu = mu_base + A(:, i) * I + bg;
end
I_list(i) = I_list(i) - epsilon * grad_I;
%% x y coord descent
mu = A * I_list + bg;
d_mu_x = I_list(i) / (2 * sqrt(2 * pi) * sigma) *...
(exp(-(xx - 0.5 - coord_list(i, 1)) .^ 2 / (2 * sigma ^ 2)) -...
exp(-(xx + 0.5 - coord_list(i, 1)) .^ 2 / (2 * sigma ^ 2))) .* temp_yy;
d_mu_y = I_list(i) / (2 * sqrt(2 * pi) * sigma) * temp_xx .*...
(exp(-(yy - 0.5 - coord_list(i, 2)) .^ 2 / (2 * sigma ^ 2)) -...
exp(-(yy + 0.5 - coord_list(i, 2)) .^ 2 / (2 * sigma ^ 2)));
grad_xy = [sum((mu - im) ./ (mu + 1e-5) .* d_mu_x(:)),...
sum((mu - im) ./ (mu + 1e-5) .* d_mu_y(:))];
% backtracking
alpha = 0.5;
epsilon = 1e-1;
df = -1e-6 * norm(grad_xy) ^ 2;
mu = A * I_list + bg;
fc = sum(mu - im .* log(mu + 1e-5));
coord = coord_list(i, :) - epsilon * grad_xy;
mu_base = A(:, [1 : i - 1, i + 1 : end]) * I_list([1 : i - 1, i + 1 : end], :);
meas_col = 1 / 4 *...
(erf((xx_r + 0.5 - coord(1)) / sqrt(2) / sigma) -...
erf((xx_r - 0.5 - coord(1)) / sqrt(2) / sigma)) .*...
(erf((yy_r + 0.5 - coord(2)) / sqrt(2) / sigma) -...
erf((yy_r - 0.5 - coord(2)) / sqrt(2) / sigma));
mu = mu_base + meas_col * I_list(i) + bg;
while sum(mu - im .* log(mu + 1e-5)) > fc + epsilon * df
epsilon = epsilon * max(alpha, 0.1);
alpha = alpha * 0.8;
if epsilon < 1e-10
epsilon = 0;
meas_col = A(:, i);
break;
end
coord = coord_list(i, :) - epsilon * grad_xy;
meas_col = 1 / 4 *...
(erf((xx_r + 0.5 - coord(1)) / sqrt(2) / sigma) -...
erf((xx_r - 0.5 - coord(1)) / sqrt(2) / sigma)) .*...
(erf((yy_r + 0.5 - coord(2)) / sqrt(2) / sigma) -...
erf((yy_r - 0.5 - coord(2)) / sqrt(2) / sigma));
mu = mu_base + meas_col * I_list(i) + bg;
end
A(:, i) = meas_col;
coord_list(i, :) = coord_list(i, :) - epsilon * grad_xy;
end
if iter > 1 && res_list(iter - 1) - res_list(iter) < 1e-2
break;
end
iter = iter + 1;
end
..
function im = Gen_Im_From_2D_Coord(coord_list, I_list, height, width, sigma)
% PURPOSE:
% Generate image based on input emitter coordinate and intensity.
%---------------------------------------------------
% USAGE:
% im = Gen_Im_From_Coord(coord_list, I_list, height, width, sigma)
%---------------------------------------------------
% INPUTS:
% coord_list: list of input coordinate
% I_list: list of input intensity
% height: image height
% width: image width
% sigma: standard deviation of system PSF (pixel)
%---------------------------------------------------
% OUTPUTS:
% im: generated image
%---------------------------------------------------
[xx, yy] = meshgrid(1 : width, 1 : height);
xx_r = xx(:); yy_r = yy(:);
im = zeros(height * width, 1);
% iterate through all input coordinate
for i = 1 : size(coord_list, 1)
% generate measurement on a given point
im = im + I_list(i) / 4 *...
(erf((xx_r + 0.5 - coord_list(i, 1)) / sqrt(2) / sigma) -...
erf((xx_r - 0.5 - coord_list(i, 1)) / sqrt(2) / sigma)) .*...
(erf((yy_r + 0.5 - coord_list(i, 2)) / sqrt(2) / sigma) -...
erf((yy_r - 0.5 - coord_list(i, 2)) / sqrt(2) / sigma));
end
...
function A = Gen_Meas_From_2D_Coord(coord_list, height, width, sigma)
% PURPOSE:
% Generate measurement matrix based on input emitter coordinate.
%---------------------------------------------------
% USAGE:
% A = Gen_Meas_From_2D_Coord(coord_list, height, width, sigma)
%---------------------------------------------------
% INPUTS:
% coord_list: list of input coordinate
% height: image height
% width: image width
% sigma: standard deviation of system PSF (pixel)
%---------------------------------------------------
% OUTPUTS:
% A: generated measurement matrix
%---------------------------------------------------
[xx, yy] = meshgrid(1 : width, 1 : height);
xx_r = xx(:); yy_r = yy(:);
A = zeros(height * width, size(coord_list, 1));
% iterate through all input coordinate
for i = 1 : size(coord_list, 1)
% generate measurement on a given point
A(:, i) = 1 / 4 *...
(erf((xx_r + 0.5 - coord_list(i, 1)) / sqrt(2) / sigma) -...
erf((xx_r - 0.5 - coord_list(i, 1)) / sqrt(2) / sigma)) .*...
(erf((yy_r + 0.5 - coord_list(i, 2)) / sqrt(2) / sigma) -...
erf((yy_r - 0.5 - coord_list(i, 2)) / sqrt(2) / sigma));
end
@Bruno Luong@Walter Roberson @Chunrucould you please give me some guidance or references?
Your code is too long for me to look in detail. I notice that the code is not even optimized (growing array, call function in the loop, some common calculation is repeated, some constant quantity is computed inside the loop, etc...)
My recommendation is working on your matlab code before feed it to the coder.
you are right, I think I should optimize my code.Is there any reference materials?

Sign in to comment.

More Answers (1)

Hi,
MATLAB Coder supports growing an array only by concatenation, growing an array by index is not supported. Please see: https://in.mathworks.com/help/coder/ug/limitations-with-variable-size-support-for-code-generation.html
If you wish to assign varying sized arrays to same variable, you can use coder.varize .
Also if you would like to optimize the MEX runtime, you can try disabling IntegrityChecks and ResponsivenessChecks in the MEX coder config.

3 Comments

Size mismatch (size [1 x 0] ~= size [16 x 0]).
geeting this error can you help me in sloving this please
need help to solve the above error
You are assigning an empty array with 16 rows to a variable that was first assigned an empty array with one row.
When you use MATLAB Function Blocks in Simulink, then unless you use coder.varsize then the first assignment to a variable sets the limits on how large the variable is. This is different from regular MATLAB as regular MATLAB adjusts sizes as needed.

Sign in to comment.

Categories

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!