repmat vs repelem in code generation

If I use repmat as below, I get the following error in code generation. Not with repelem.
Size argument must be scalar.
The above error may be reported because of a limitation rather than a true error condition. When detecting errors, complex control flow sometimes creates false positives.
Error in ==> myTest Line: 34 Column: 26
configNames.txt and configValues.txt contain a line with entries MaxTrackLim and 10 respectively.
function myTest()
%#codegen
domainID = 0;
Name = "/detectionNode";
Node = ros2node(Name, domainID);
fid_names = fopen('configNames.txt','r');
fid_values = fopen('configValues.txt','r');
row = 1;
value = fscanf(fid_values,'%f\n');
s = {''};
s{row} = fgetl(fid_names);
vnames = {'variable', 'value'};
T = table (s, value,'VariableNames',vnames);
fclose(fid_values);
fclose(fid_names);
% preallocate memory for variable array
findVar = strcmp(T.variable, 'MaxTrackLim');
MaxTrackLim = floor(T.value(find(findVar)));
detectionList = ros2publisher(Node, ...
"/obstacleList","geometry_msgs/PoseArray" ,...
"Reliability","reliable","Durability","volatile");
detectionState = ros2message("geometry_msgs/Pose");
detectionListMsg.poses = repmat(detectionState,MaxTrackLim,1);

2 件のコメント

Andinet
Andinet 2023 年 6 月 23 日
Further point: if you replace the last line in the code with detectionListMsg.poses = repmat(detectionState,10,1); you woundn't get a code generation error.
Bruno Luong
Bruno Luong 2023 年 6 月 23 日
編集済み: Bruno Luong 2023 年 6 月 24 日
Can you try with
MaxTrackLim = max([0; floor(T.value(find(findVar)))]); % edit semicolon separator since findVar could be a column vector
or
MaxTrackLim = sum(floor(T.value(find(findVar))));

サインインしてコメントする。

回答 (1 件)

dpb
dpb 2023 年 6 月 23 日
編集済み: dpb 2023 年 6 月 23 日

1 投票

"configNames.txt and configValues.txt contain a line with entries MaxTrackLim and 10 respectively"
But your code contains
MaxTrackLim = floor(T.value(find(findVar)));
which is of indeterminate size; it's unknown until runtime the size find() will return -- from empty to numel(T.value) is possible.
You can try and see if
MaxTrackLim = floor(T.value(find(findVar,1)));
will be enough for the analyzer.
I'd probably rewrite the lookup table code something more on the line of
vars=readcell('configNames.txt');
vals=readmatrix('configValues.txt');
vnames = {'variable', 'value'};
T=table(vals,'VariableNames',vnames,'RowNames',vars);
MaxTrackLim=floor(T{'MaxTrackLim','variable'});
which shortens up the input code and also will handle a table of more than one variable. It will also eliminate the explicit lookup operation; whether it will be recognized as a single row or not, I don't know.
I'd also suggest to put the two separate text files together into one so they variable and the value are always together and be much easier to ensure the two match in length and intended values rather than being completely separate entities as now.
Your code is specific for just one record per file; the above would handl multiple cases/variables so especially if it is going to be so that the two files are used, it should catch that the lengths of the two are the same.
Oh...and this also presumes that readcell/readmatrix can be used by code generator, of course.

6 件のコメント

dpb
dpb 2023 年 6 月 23 日
ADDENDUM
Oh, I was going to ask -- should the floor above be ceil instead, maybe????
Andinet
Andinet 2023 年 6 月 23 日
Thanks dpb
You guessed right, both readcell/readmatrix are not supported for code generation. When it comes to file I/O functions, there are restrictions in the code generation step that twisted my arm to use low level routines like fopen, fscanf, fgetl, etc. My first implementation was a single text file with multiple key/value pairs in it, but the varying lengths of key variables ( and the resulting codegen errors) made me change that path.
The codegen failed with your suggestion
MaxTrackLim = floor(T.value(find(findVar,1)));
in place of
MaxTrackLim = floor(T.value(find(findVar)));
Apart from size issues, however it still begs the question why it complained with repmat and not with repelem.
with regard to floor / ceil, yes ceil looks more appropriate in this context. I just wanted to make sure the data type is an integer.
dpb
dpb 2023 年 6 月 23 日
It looks like you could use fileread to bring in the file as text, then create the cell arrays for names,values and then create the table from those. Agree that isn't the real issue, however.
Did the alternative of addressing the table created with rownames instead of using to variables solve the problem by eliminating the lookup? That shouldn't be hard to test.
Alternatively, does
Found=(T.value(find(findVar,1)));
MaxTrackLim=ceil(found);
fool mother nature by not being the result of the find operation directly?
Alternatively, even more explicit
MaxTrackLim(1)=ceil(found);
?
As to the difference between repmat and repelem, I've no klew, no. As the error message says, it can generate false positives; looks like one.
Andinet
Andinet 2023 年 6 月 23 日
unfortunately, none of those changes made a difference when repmat is used. I believe I will have to use repelem for now with my previous settings.
dpb
dpb 2023 年 6 月 23 日
Looks to be worthy of reducing to the minimum to reproduce the issue and submit as bug/service report/request. If nothing else will serve as additional fodder for TMW to improve the diagnostics engine by supplying another test case.
Bruno Luong
Bruno Luong 2023 年 6 月 24 日
編集済み: Bruno Luong 2023 年 6 月 24 日
In various modifications suggested by @dpb or original code, if findVar is empty MaxTrackLim is empty array. It is not a scalar in this circumstance.
IMO repelem should throw an error as well.

サインインしてコメントする。

カテゴリ

製品

リリース

R2023a

質問済み:

2023 年 6 月 23 日

編集済み:

2023 年 6 月 24 日

Community Treasure Hunt

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

Start Hunting!

Translated by