0

I want to use an index equation to iterate over a tensors, whereas I always want to extract the value at index i and index i+1. An example:

Variable x; x.up = 10;

Parameter T /1=1,2=2,3=3,4=4,5=5/;
Set a /1,2,4/;

equation eq(a); eq(a).. x =g= T[a+1];
*x ist restricted by the values of T at the indices 2,3 and 5.

Model dummy /all/;
solve dummy min x use lp;

I am aware that gams sees the indices as string-keys rather than numerical ones, so the addition is not intended. Is this possible anyway? This e.g. can be solved by defining another tensor, unfortunaly my given conditions require the index operation inline (i.e. I am not allowed to define additional parameters or sets.

wittn
  • 298
  • 5
  • 16
  • Maybe I did not understand the problem, but your code looks just fine. The `a+1` is a valid index operation. Even if GAMS does not care about the numeric meaning of you indices, this works since GAMS uses "the next" index after `i` here. This concept is explained here: https://www.gams.com/38/docs/UG_OrderedSets.html#UG_OrderedSets_LagLeadOperators – Lutz Apr 26 '22 at 07:46
  • Yes, unfortunaly '+1' will get the next entry in the set, not the next value of the value, it is applied to. E.g. if I want to iterate over at set /1,2,4/ and I want the indices /2,3,5/ (i.e. the next value for each entry, not the next set entry, this does not work. – wittn Apr 26 '22 at 08:42
  • Not sure how that should work. If you have a set with elements, 1,2,4, you should have a domain violation if you try to access it with 2,3,5. – Lutz Apr 26 '22 at 09:03
  • @Lutz Edited my example to make more clear what I am trying to do. – wittn Apr 26 '22 at 11:49

1 Answers1

1

Does this work for you?

Variable x; x.up = 10;

Set aa /1*6/;
Parameter T(aa) /1=1,2=2,3=3,4=4,5=5/;
Set a(aa) /1,2,4/;

equation eq(a); eq(a(aa)).. x =g= T[aa+1];
*x ist restricted by the values of T at the indices 2,3 and 5.

Model dummy /all/;
solve dummy min x use lp;
Lutz
  • 2,197
  • 1
  • 10
  • 12
  • Unfortunaly this does not fullfill my requirement of the index operations being inline, but I found a way to circumvent the neccessarity to use the index addition in my program at all. – wittn Apr 29 '22 at 12:43
  • I ended up using your way after all. Quick follow-up on that; do you think there is a way to do this for nested indexed equations, i.e. Variable x; x.up = 10; Parameter p /4=4,5=5,6=6/; Set a1 /1,2/; Set a2 /3,4/; equation eq(a1,a2); eq(a1,a2).. x =g= p[a1+a2]; wheras x will be 6 minimized. – wittn Jun 03 '22 at 11:42
  • The part of `p[a1+a2];` looks a little tricky. You probably need something like `sum(ax$(ord(ax)=ord(a1)+ord(a2)),p[ax]);` – Lutz Jun 03 '22 at 12:05
  • And ax would again be a set containing all indices? – wittn Jun 03 '22 at 13:04
  • Another idea I had was to create another set based on the wanted index operation. Is there some possibility of mapping index sets, because the original set might be needed in the equation as well? – wittn Jun 03 '22 at 13:20
  • > And ax would again be a set containing all indices? Yes, or an Alias to it. – Lutz Jun 03 '22 at 13:25
  • > Is there some possibility of mapping index sets, ... ? - Yes, a map is just a multidimensional set. – Lutz Jun 03 '22 at 13:27
  • Could you give an example how such map would look like? Also, do you have a solution if I want to add the entries of two sets together (instead of just adding a constant value)? E.g. if I have sets with 1,4 and with 7,8 I want the indices to be 8,9,11,12. – wittn Jun 17 '22 at 08:11
  • > Could you give an example how such map would look like? - Here is an exmple with set i and j and a map between the two called ijmap (format in the comments here does not look so nice): Set i /i1*i3/, j /j1*j3/, ijmap(i,j) /i1.j2, i2.(j1,j3), i3.(j1,j2)/; – Lutz Jun 17 '22 at 10:30
  • But how can I use them as an index later? Like lets say I want to map the set i to the set with i+1: Parameter T /1=1,2=2,3=3,4=4,5=5/; Set i /1,2,3/, imap(i,*) /1.2,2.3,3.4/; equation eqcon; eqcon(i).. T[map(i)] =l= x; – wittn Jun 18 '22 at 09:39
  • 1
    You need to use the map with a sum, like this: Parameter T /1=1,2=2,3=3,4=4,5=5/; Set i /1,2,3,4/ imap(i,i) /1.2,2.3,3.4/; Alias (i,j); variable x; equation eqcon; eqcon(i).. sum(imap(i,j),T[j]) =l= x; – Lutz Jun 20 '22 at 10:04
  • I see. I suppose this is the only way? I am working the optimization program in a tree structure, so usally when parsing an index access e.g. T['1'] the part of the program parsing the '1' does not have knowledge about the T (which makes it hard implement in the way you presented). Otherwise it works phenomenal. – wittn Jun 21 '22 at 12:47
  • I made it work like you suggested. Is it possible to make it work with multiple indices? E.g. sum(imap1(i,j),imap2(i,k),T[j,k]) (with fitting sets and maps)? – wittn Jun 28 '22 at 10:04
  • Yes, this is no problem – Lutz Jun 28 '22 at 10:16
  • Sorry, did not specify:, how exactly do I accomplish this? With the syntax above I get an error ("expected ')' after imap2(i,k)"). – wittn Jun 28 '22 at 13:32
  • Sorry, I overlooked that. There is a pair of brackets missing (around the maps driving the indices in the sum statement before the comma). Try this: sum((imap1(i,j),imap2(i,k)),T[j,k]) – Lutz Jun 28 '22 at 14:34