Given a Real array (e.g. myArray
) and a Boolean array (e.g. myMask
), I'd like to have:
myMask[i] == true
then myArray[i] = myValueTrue
myMask[i] == false
then myArray[i] = myValueFalse
This does work
model BooleanIndexing
parameter Boolean myMask[3] = {false, true, true};
parameter Boolean myMask_negated[3] = {true, false, false};
Real myArray[3];
parameter Real myValueTrue = 3.0;
parameter Real myValueFalse = 5.0;
equation
myArray[Modelica.Math.BooleanVectors.index(myMask)] = fill(myValueTrue, Modelica.Math.BooleanVectors.countTrue(myMask));
myArray[Modelica.Math.BooleanVectors.index(myMask_negated)] = fill(myValueFalse, Modelica.Math.BooleanVectors.countTrue(myMask_negated));
end BooleanIndexing;
but this does not
model BooleanIndexing
parameter Boolean myMask[3] = {false, true, true};
parameter Boolean myMask_negated[3] = not myMask;
Real myArray[3];
parameter Real myValueTrue = 3.0;
parameter Real myValueFalse = 5.0;
equation
myArray[Modelica.Math.BooleanVectors.index(myMask)] = fill(myValueTrue, Modelica.Math.BooleanVectors.countTrue(myMask));
myArray[Modelica.Math.BooleanVectors.index(myMask_negated)] = fill(myValueFalse, Modelica.Math.BooleanVectors.countTrue(myMask_negated));
end BooleanIndexing;
The only difference is how I initialized myMask_negated
.
The errors are, in OpenModelica:
[BooleanIndexing: 9:3-9:139]: Illegal subscript Modelica.Math.BooleanVectors.index({myMask_negated[1], myMask_negated[2], myMask_negated[3]}) for dimensions 3 in component myArray[Modelica.Math.BooleanVectors.index(myMask_negated)].
[BooleanIndexing: 9:3-9:139]: Variable myArray[Modelica.Math.BooleanVectors.index(myMask_negated)] not found in scope BooleanIndexing.
Error occurred while flattening model BooleanIndexing
and in Dymola2018
Translation of BooleanIndexing:
Failed to expand myArray[Modelica.Math.BooleanVectors.index(myMask)].
Errors or failure to expand the equation:
myArray[Modelica.Math.BooleanVectors.index(myMask)] = fill(myValueTrue, Modelica.Math.BooleanVectors.countTrue(myMask));
Found in class BooleanIndexing, C:/workspace/modelica_vehicle/modelica_test/BooleanIndexing.mo at line 8.
Errors or failure to expand vector or matrix expressions.
Translation aborted.
Direct boolean indexing myArray[myMask]
seems not to be the solution here.
I cannot see why they are failing and if there are any more elegant solutions.
Both of your versions do not guarantee that the correct number of equations are generated.
myValueTrue
and myValueTrue_negated
are both parameters, so the user can change the values of the vectors to something which is not complementary.
Hence, I would have recommended to set
final parameter Boolean myMask_negated[3] = not myMask;
but this also does not work, neither in Open Modelica nor in Dymola.
So instead, I recommend to delete myMask_negated
and use for loops instead.
Either with two seperate ones:
model BooleanIndexing
parameter Boolean myMask[3] = {false, true, true};
Real myArray[3];
parameter Real myValueTrue = 3.0;
parameter Real myValueFalse = 5.0;
equation
for i in Modelica.Math.BooleanVectors.index(myMask) loop
myArray[i] = myValueTrue;
end for;
for i in Modelica.Math.BooleanVectors.index(not myMask) loop
myArray[i] = myValueFalse;
end for;
end BooleanIndexing;
or with a single for loop using an array constructor, as shown here:
model BooleanIndexing2
parameter Boolean myMask[3] = {false, true, true};
Real myArray[3];
parameter Real myValueTrue = 3.0;
parameter Real myValueFalse = 5.0;
equation
myArray = {if value then myValueTrue else myValueFalse for value in myMask};
end BooleanIndexing2;