Search code examples
matlabcompiler-errorssimulink

Compiling error due to variable size Matrix in simulink (matlab function block)


Looks like multiple people are having trouble with this, none of the workarounds worked for me though.

I am using Matlab 2014b with Simulink 8.4. I am solving a DAE system that describes a turbocharged engine. The system consists of 4 equations, 2 of them are DAEs, 2 are ODEs. For the DAEs I tried using the Algebraic Constraint Block, couldn't get it to simulate correctly though. The two DAEs are of the form: Polynomial of 6th degree in x = 0, and the coefficients are calculated every step of the simulation. I know for a fact that the coefficients are in a range which results in only one real positive root of the polynomial. That is the one I am looking for.

Tried the following code:

function x_4 = fcn(A, B)
c = [1, -1, 2*B, -2*B, B^2, -B^2, -A^2];
r = roots(c);

realR = r(imag(r)==0);
posR = realR(realR>0);
x_4 = posR^0.25;

Error message for this one is

Data 'x_4' is inferred as a variable size matrix, while its specified type is something else.

and

An error occurred while propagating data type 'double' through 'gleichungssystem_poly/Gleichung 4/x_4_calc/A'.

I also tried this code:

function x_4 = fcn(A, B)
c = [1, -1, 2*B, -2*B, B^2, -B^2, -A^2];
r = roots(c);

x_4 = zeros(1);
if isreal(r(1)) && real(r(1))>0
   x_4 = r(1)^0.25;
elseif isreal(r(5)) && real(r(5))>0
    x_4 = r(5)^0.25;
elseif isreal(r(2)) && real(r(2))>0
    x_4 = r(2)^0.25;
elseif isreal(r(3)) && real(r(3))>0
    x_4 = r(3)^0.25;
elseif isreal(r(4)) && real(r(4))>0
    x_4 = r(4)^0.25;
elseif isreal(r(6)) && real(r(6))>0
    x_4 = r(6)^0.25;
end

Tried the whole thing in a for loop as well. Funny thing is it let me compile and simulate the model, however x_4 would never be anything but the initialized 0... I looking into the exact calculations in debugging mode, the condition is fulfilled for one of the roots, nontheless x_4 remains at zero..

I would really appreciate input on this one!


Solution

  • From the documentation at http://www.mathworks.com/help/coder/ug/functions-supported-for-code-generation--categorical-list.html#bq1h2z8-25 for roots function in MATLAB coder, the output of roots is always variable size and complex. That explains the error and the output from your examples. You might want to change your condition from isreal to a comparison against 0 for the complex part while taking care of some tolerance. For example,

    abs(imag(r(1))) < eps(r(1))