matlabFunction: Index exceeds the number of array elements for Matlab R2021a

57 visualizaciones (últimos 30 días)
Hi all,
I am currently trying to write a symbolic expression into a matlab function using the matlab command. This works perfectly for smaller symbolic expressions, but for larger ones I encounter the following error in R2021a:
matlabFunction(C, 'vars', {q, qdot, alpha, l, rho}, 'file', strcat(dpath,'/C_fun'), 'Optimize', true);
Index exceeds the number of array elements (54).
Error in sym/matlabFunction>addVars (line 817)
varArr = addElem(varArr,split(join(elem(start:ende),','),','));
Error in sym/matlabFunction>handleBlocks (line 928)
blocks(end).lhs = addVars(blocks(end).lhs, lhsVars, linesWritten+1,linesWritten+newLines);
Error in sym/matlabFunction>writeOutput (line 616)
blocks = handleBlocks(blocks, body, fmt, lhsVars, rhsVars, ifNargout);
Error in sym/matlabFunction>writeMATLAB (line 506)
blocks = writeOutput(outputs,f,1,sparseMat,blocks,false);
Error in sym/matlabFunction (line 196)
[g, blocks] = writeMATLAB(funs,file,varnames,outputs,body, opts.Optimize, opts.Sparse,
opts.Comments, blocks);
Is there a possibility to increase the maximal length of the matlabFunction command?

Respuesta aceptada

Walter Roberson
Walter Roberson el 15 de Abr. de 2021
matlabFunction has a bug in writing any function using piecewise to a file in expression that is complicated enough that the function is not generated as a single line.
For example if it generates temporary code like
if ((q1 ~= 0.0) & (q2 ~= 0.0))
t3 = (1.0./q0.^2.*1.0./q2.^5.*(et100+et101+et102+et103+et104+et105+et106+et107+et108+et109+et110+et111+et112+et113+et114+et115+et116))./(q1.*1.0e+6);
else
t3 = NaN;
end
then in post-processing it will crash.
Internally, the code is assuming that each line of temporary code assigns to one (distinct) variable -- a pure sequence of assignment expressions. But notice in the above temporary code that the first, third, and fifth line do not assign to any variables, and that the variable assigned to in the fourth line is the same as the one assigned to on the second line. In such a situation, the code crashes.
I do not have any work-around at the moment. The logic of the relevant function is broken, but it also relies on mistaken infrastructure variables being carried around. The most natural fix would require changes to internal code of the Symbolic Engine.
This is going to require a repair from Mathworks.
  2 comentarios
Maximilian Stölzle
Maximilian Stölzle el 15 de Abr. de 2021
Editada: Maximilian Stölzle el 15 de Abr. de 2021
Thank you so much for investigating this issue Walter. Do you know if this bug also exists in prior Matlab releases (e.g. 2020b and prior)? And is there a way to make Mathworks aware of this apparent bug?
Walter Roberson
Walter Roberson el 15 de Abr. de 2021
The error does not exist before R2021a. The R2021a matlabFunction() has substantial rewrites.
I just finished writing a bug report for Mathworks, so they will know as soon as they read my report.
If my analysis is correct, it is not only piecewise() that can lead to this problem, and that the problem can also occur an array of output is being created instead of a vector.
My analysis is that this is something that has no easy fix; the problem logic at the MATLAB level could potentially work (maybe) if the output from the MuPAD level were different. I think Mathworks might end up having to change what is emitted from MuPAD, as the alternative requires parsing the generated MATLAB code looking for assignment statements when there can be multiple assignments on the same line and can be a branching if/elseif structure; it would be more robust to change the MuPAD side.

Iniciar sesión para comentar.

Más respuestas (1)

Walter Roberson
Walter Roberson el 13 de Abr. de 2021
matlabFunction(C, 'vars', {q, qdot, alpha, l, rho}, 'file', strcat(dpath,'/C_fun'), 'Optimize', true);
Index exceeds the number of array elements (54).
You did not mention your release. I predict that you are using R2020a or before (and I am not positive it was fixed in R2020b though I was told i was). If so then you need to use 'Optimize', false .
Unfortunately in a range of versions of MATLAB, matlabFunction with 'optimize' turned on generates incorrect output when it produces output at all. It generates correct output to a point, and then gets messed up. Effects varied: sometimes it generated additional lines but did not use any of them, returning a partial result instead; sometimes (more rarely) it did not generate additional lines but tried to use the elements it would have generated, generating index out of range errors.
I have use matlabFunction to generate fairly large expressions. It can turn painfully slow (especially with optimize turned on.) A small number of releases ago, I think they mentioned that performance had been improved a fair bit, but I am not certain about that.
Note: When you use 'Optimize', 'on', then the matching process seems to be at least O(n^2.3) in my tests. Because of that, if you have an expression made up of adding or multiplying multiple parts, it can be much faster to generate functions for each of the parts individually, and then add an extra function to hook the parts together. Doing this can lose out on some optimizations, but it can cut down a lot when working with expressions that do not have much in common (because the optimizer does not know they do not have a lot in common.)
  4 comentarios
Walter Roberson
Walter Roberson el 15 de Abr. de 2021
It turns out that R20201a substantially rewrote file handling code for matlabFunction() .
However, that bug was in a step after the problem you are observing.
If you post enough of your code for me to test, I will attempt to debug the problem.
Maximilian Stölzle
Maximilian Stölzle el 15 de Abr. de 2021
Hi Walter,
Thank you so much. That would be great.
So first you need to load the C_matrix.mat in the attachment into your workspace.
Subsequently, we run the matlabFunction command:
matlabFunction(C, 'vars', {q, qdot, alpha, l, rho}, 'file', strcat(pwd,'/C_fun'), 'Optimize', false);
Best regards,
Maximilian

Iniciar sesión para comentar.

Community Treasure Hunt

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

Start Hunting!

Translated by