If an array function like SUM is called with an expression that contains subscripts (more than one level deep), SDEverywhere currently emits incorrect code.
For example (based on similar equations in the En-ROADS model):
DimA: A1, A2, A3
~~|
A Values[DimA]
~~|
A Values Avg =
ZIDZ(
SUM(
IF THEN ELSE(
A Values[DimA!]=:NA:,
0,
A Values[DimA!]
)
),
SUM(
IF THEN ELSE(
A Values[DimA!]=:NA:,
0,
1
)
)
)
~~|
The generated C code for this is incomplete:
// A Values Avg = ZIDZ(SUM(IF THEN ELSE(A Values[DimA!]=:NA:,0,A Values[DimA!])),SUM(IF THEN ELSE(A Values[DimA!]=:NA:,0,1)))
double __t1 = 0.0;
__t1 += ;
double __t2 = 0.0;
__t2 += ;
_a_values_avg = _ZIDZ(
_IF_THEN_ELSE(_LOOKUP(_a_values[undefined[undefined]], _time) == _NA_,
0.0,
_LOOKUP(_a_values[undefined[undefined]], _time))__t1,
_IF_THEN_ELSE(_LOOKUP(_a_values[undefined[undefined]], _time) == _NA_,
0.0,
1.0)__t2);
SDEverywhere does correctly handle SUM of a subscripted variable, like this:
A Values Total =
SUM( A Values[DimA!] )
~~|
But it doesn't handle the case where the subscripts are inside of an expression passed to SUM.
The code in EquationGen that handles subscripts currently only checks to see if the "current function" is an array function (e.g. SUM), but this will not be the case if the variable is used inside e.g. IF THEN ELSE. To fix, we can keep a separate "current array function" variable and use that for deciding if we are anywhere (possibly more than one level deep) within an array function call.
If an array function like
SUMis called with an expression that contains subscripts (more than one level deep), SDEverywhere currently emits incorrect code.For example (based on similar equations in the En-ROADS model):
The generated C code for this is incomplete:
SDEverywhere does correctly handle
SUMof a subscripted variable, like this:But it doesn't handle the case where the subscripts are inside of an expression passed to
SUM.The code in
EquationGenthat handles subscripts currently only checks to see if the "current function" is an array function (e.g.SUM), but this will not be the case if the variable is used inside e.g.IF THEN ELSE. To fix, we can keep a separate "current array function" variable and use that for deciding if we are anywhere (possibly more than one level deep) within an array function call.