StepArray Operator

The stepArray operator represents a compact way of writing constant arrays with a lot of sparsity. Its aim is to optimize model writing so as to reduce memory and time consumption for constant arrays that are very sparse. For example, Boolean intensity arrays representing machine availability over the time horizon in a scheduling problem can be modeled using the stepArray operator.

The stepArray operator takes two arguments: two constant arrays indices and values of equal size n:

  • The first operand indices must be an array of integer constants sorted in ascending order and without duplicates
  • The second operand values must be an array of constant numbers (Boolean, integer, or double)

The stepArray operator then returns an array x of size indices[n-1] such that x[i] is equal to values[k] for all i between indices[k-1] (included) and indices[k] (excluded):

  • x[i] = values[0] for i in 0...indices[0]
  • x[i] = values[1] for i in indices[0]...indices[1]
  • x[i] = values[n-1] for i in indices[n-2]...indices[n-1]

The behavior of the stepArray operator is illustrated in the example below:

// Array {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}
// represented in compact form as a stepArray:
myStepArray <- stepArray({5, 12, 20}, {0, 1, 0});

count(myStepArray)  // returns 20
myStepArray[0]      // returns 0
myStepArray[5]      // returns 1
myStepArray[15]     // returns 0
# Array [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]
# represented in compact form as a stepArray:
indices = model.array([5, 12, 20])
values = model.array([0, 1, 0])
my_step_array = model.step_array(indices, values)

model.count(my_step_array)  # returns 20
model.at(my_step_array, 0)  # returns 0
model.at(my_step_array, 5)  # returns 1
model.at(my_step_array, 15) # returns 0
// Array {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}
// represented in compact form as a stepArray:
std::vector<hxint> indicesData = {5, 12, 20};
std::vector<hxint> valuesData = {0, 1, 0};
HxExpression indices = model.array(indicesData.begin(), indicesData.end());
HxExpression values = model.array(valuesData.begin(), valuesData.end());
HxExpression myStepArray = model.stepArray(indices, values);

model.count(myStepArray);   // returns 20
model.at(myStepArray, 0);   // returns 0
model.at(myStepArray, 5);   // returns 1
model.at(myStepArray, 15);  // returns 0
// Array {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}
// represented in compact form as a stepArray:
HxExpression indices = model.Array(new long[] { 5, 12, 20 });
HxExpression values = model.Array(new long[] { 0, 1, 0 });
HxExpression myStepArray = model.StepArray(indices, values);

model.Count(myStepArray);  // returns 20
model.At(myStepArray, 0);  // returns 0
model.At(myStepArray, 5);  // returns 1
model.At(myStepArray, 15); // returns 0
// Array {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}
// represented in compact form as a stepArray:
HxExpression indices = model.array(new long[] { 5, 12, 20 });
HxExpression values = model.array(new long[] { 0, 1, 0 });
HxExpression myStepArray = model.stepArray(indices, values);

model.count(myStepArray);  // returns 20
model.at(myStepArray, 0);  // returns 0
model.at(myStepArray, 5);  // returns 1
model.at(myStepArray, 15); // returns 0