DarioMangoni
DarioMangoni

Reputation: 311

Array indexing with boolean array

Given a Real array (e.g. myArray) and a Boolean array (e.g. myMask), I'd like to have:

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.

Upvotes: 1

Views: 131

Answers (1)

marco
marco

Reputation: 6655

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;

Upvotes: 2

Related Questions