Matlab coder Non-constant expression or empty matrix
Show older comments
Hello, I am trying to make a function made by Matlab transformed into MEX file to enhance execution speed of the function but the coder show the error:
Non-constant expression or empty matrix. This expression must be constant because its value determines the size or class of some expression. The part of the code that causes the problem is
indx=mat==max(mat);
nominees={acceptedB{indx,:}};
I also tried not to use logical indexing using
indx=find(mat==max(mat));
but the same error appeared. Any idea how to solve this problem without affecting execution speed of the function ?
Answers (2)
Walter Roberson
on 5 Jun 2016
First assign to the variable an array that is of the right class and is the maximum size that could possibly be encountered. For example,
indx = zeros(numel(mat),1);
You need to use numel of mat because of the possibility that all of the elements in mat are the same value so your find() might return every index.
Then you can do
indx = find(mat(:) == max(mat(:)));
The result might well be shorter than the size you originally allocated, and that is okay: you can reassign a matrix as shorter but not as longer.
However, I am concerned because it looks to me as if
nominees={acceptedB{indx,:}}
is indefinite size. Would
nominees = acceptedB(index,:);
be acceptable instead?
7 Comments
Mohamed
on 5 Jun 2016
Walter Roberson
on 5 Jun 2016
nrow = length(indx);
ncol = size(acceptedB,2);
nominees = cell(nrow, ncol);
for R = 1 : nrow
fromrow = indx(R);
for C = 1 : ncol
nominees{R, C} = acceptedB{fromrow, C};
end
end
Mohamed
on 6 Jun 2016
Walter Roberson
on 6 Jun 2016
I doubt that you are going to be able to do it by way of MATLAB Coder; you are going to have to hand-write the C. MATLAB Coder is aimed at stand-alone code that does not have the MATLAB infrastructure, whereas MEX files have the full power of MATLAB to draw on (by calling back into MATLAB if necessary.)
My above code was not correct, by the way: it should have been
nrow = length(indx);
ncol = size(acceptedB,2);
nominees = cell(1, nrow*ncol);
for R = 1 : nrow
fromrow = indx(R);
for C = 1 : ncol
nominees{1, R + (C-1)*nrow} = acceptedB{fromrow, C};
end
end
You could push this further using a single loop that went from 1 to nrow * ncol:
for K = 1 : nrow * ncol
nominees{1, K} = acceptedB{ indx(mod(K-1,nrow)+1), floor((K-1)/nrow)+1 };
end
I would tend to doubt that you would be permitted to vectorize this, as the vectorized version would require either using a left hand side of
[nominess{1,1:end}]
or else using () for the cell array and you say that using () for the cell array is not permitted. If using () for cell array items was permitted then you could vectorize, I think.
Mohamed
on 6 Jun 2016
Ayim Manuel De la fuente de Pablo
on 5 Mar 2018
Hi,
I am facing this same problem, did you get to solve it?
Thanks!
Chris Volpe
on 28 Aug 2023
I am having the same error, but in the context of referencing a struct field whose name is contained in a variable, i.e. an experssion of the form "foo.(bar)". However, for the present context, the proposed solution seems to suggest using non-curly braces to index into a cell array, which Coder considers gauche.
In my case I had the same error using a Matlab Function. The code inside preallocated the output matrix to force the right sw type (single) and size (pred_hor x ny), with pred_hor and ny being workspace parameters:
Ref = single(zeros(pred_hor,ny));
I got that error on the above line, and I solved it by going to data editor ("Edit Data") for the matlab function, and specifying that the two parameters are not tunable (I had to deselect the corresponding chck box). This allowed the parser to infer the right dimension and run correctly.
Categories
Find more on Logical in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!