Error executing "display" command

Hello!! :slightly_smiling_face:
I am using AMPL+CPLEX along with C++…
I’ve come across a bug and it would help me if I could visualize one of my sets named "setA "by displaying its values on a terminal (linux).
I usually use the following:

ampl.eval(“display setA;”);

However, when I try to display this set I get the following error:

terminate called after throwing an instance of ‘ampl::AMPLException’

  • what(): Error executing “display” command:*
    error processing set setB:
  • invalid subscript parC[4]*

where setB is a copy of setA,
and parC is a parameter defined as parC[setC], where set C is initialized and then modified in the code with

ampl.eval(“let setC := setC diff setA”);

I understand that they are “connected” but why can’t I simply see the values of a set with the display command??
Knowing the values of the set would be helpful in understanding where the bug might be…

Hope I was clear enough… :blush:

Thank you in advance

1 Like

Hi @Samuele_Viaro,

Could you please provide the declarations of the three sets? From the error message setA seems to be defined in function of setB that seems to be defined in function of parC. Is that the case?

Nevertheless, from the “let setC := setC diff setA;” and the fact that parC is indexed over the set setC, that error happens because if you load the data for parC for all indices in setC initially, and then remove values from setC, you end up with data for invalid subscripts (data for deleted subscripts) in parC. You can clear the data for parC with ampl.eval("reset data parC;"); when you update setC.

ampl.eval("reset data parC; let setC := setC diff setA;")

in my .mod file I declare:
param parC[setC] >= 0
set setC default {1…N}
set setA := {1}

then in my C++ code:
ampl.readData(“./src/exec_ampl/dataIn.dat”); //data for parC
ampl.eval(“redeclare set setA = {j in setD: MTX[j, parC[j]] < X};”);
ampl.eval(“set setB;”);
ampl.getSet(“setB”).setValues(, .size());
ampl.eval(“let setC := setC diff setA;”);
ampl.eval(“reset data parC;”);
ampl.eval(“redeclare param parC{setC} >= 0;”);

I am doing all these changes because at every simulation setA changes based on the results of the previous simulation.
I basically have to update the values of the set based on the result of the previous simulation…
Could it be that after I do reset data parC I have to add new

Thanks again

Hi @Samuele_Viaro,

Since you load the data for parC from a data file, in order to avoid invalid indices in parC, you can just change its indexing set to be the original value of setC.

param parC{1..N} >= 0
set setC default {1…N}
set setA := {1}

Then you don’t need to worry about parC anymore as it will contain all the data, and by indexing using setC you will only access the elements that still exist in a given iteration.

Yes, this is what I was doing before.
However, everytime I run a simulation I add values to setC, and the number of constraints and variables increase greatly with setC…
At every simulation I reduce the size of setC removing values that I no longer need in order to reduce the size of the problem and decrease the computation time…

Hi @Samuele_Viaro,

You can keep using setC for indexing in the rest of the model (variables and constraints). You just need to avoid using it in parameters like parC that will be holding data for all values.

Ok, this I could try… :blush:
But, increasing the size of a parameter won’t affect the computation time?

No, the only computation times relative to the parameter is essentially the time to load the data into it, and we need to do that anyways for the first iteration. After that the performance is mostly affected by variables and constraints.

This helps a lot!! :hugs: