Parameter projection

Hi everyone! Currently, I am trying to reduce the dimension of some parameters by means of a “projection” (I am not sure if project is the right word in this case). According to the example below, I need to reduce the 2-dimensional matrix (a) into the vector vec(k). Hence, vec(k) should equal [1,2,3,1,3,4,1,4,3]. The set g(i,j,k) defines the mapping rule (tuple), but I cannot figure out how to use it to get vec(k). I tried with conditionals, but I cannot make it work. I appreciate any help. Thanks!

Set i /i1*i3 /;

Set j /j1*j3 /;

Set k /k1*k9/;

Set g(k,i,j) /#k:#i.#j/;

Table a(i,j) ‘original matrix’
j1 j2 j3
i1 1 2 3
i2 1 3 4
i3 1 4 3;

Parameter vec(k) ;

*obviously, doesn’t work:
vec(k) $ g= a(i,j) ;

Please use code blocks to post your questions so that the other users can just copy your code.

In your code, only the last line is the problem.

  1. $g makes no sense because you are not saying g(k, i, j) and which k, i, and j.
  2. On the right hand side a(i, j) doesn’t make sense because for that particular expression, you are not telling GAMS what is i and j.
  3. defining a set g which is true for all elements also doesn’t help you in solving this problem.

Solution:
If you think in terms of simple programming terms, the solution is easier.
Replace the last line with the following line

vec(k) = sum((i, j)$( (ord(i) - 1)*card(j) + ord(j) = ord(k)) , a(i,j)) ;

Hello,

I believe night_dog was on the right track. Here’s my version of her code, with the crucial change being the one to the definition of the set g.

Set i /i1*i3 /;
Set j /j1*j3 /;
Set k /k1*k9/;
Set g(k,i,j) /#k:(#i.#j)/;

Table a(i,j) 'original matrix'
    j1 j2 j3
i1  1  2  3
i2  11 12 13
i3  21 22 23;

Parameters
  vec(k) 'suggestion of abhosekar'
  v2(k)  'original intent of night_dog?'
  chk(k)
  ;
vec(k) = sum{(i,j)$[(ord(i) - 1)*card(j) + ord(j) = ord(k)] , a(i,j)};
v2(k) = sum{g(k,i,j), a(i,j)};
chk(k) = vec(k) - v2(k);
execute_unload 'dachshund';
abort$[card(chk)] 'vec - v2 is nonzero', chk;

The idea to construct a mapping g(k,i,j) between indices k and tuples (i,j) and then use a sum to convert i-j-tuples to indices k (or vice versa) is a very useful idiom in GAMS. I like it because the expression

v2(k) = sum{g(k,i,j), a(i,j)};

is terse and easy to understand. To see what it does, we can just look at the map g in Studio or elsewhere. In this case g is simple, but even if the mapping gets very complicated, we need only change the data in g. The code to compute v2 remains unchanged.

-Steve

Great, this is exactly what I was looking for. When working with several dimensions, I would indeed prefer Steve’s way. Analogously, one could use

 ve(k) = sum((i, j)$( g(k,i,j) ) , a(i,j)) ;

Thank you!

Indeed, the code

ve(k) = sum((i, j)$( g(k,i,j) ) , a(i,j)) ;

and

ve(k) = sum(g(k,i,j), a(i,j)) ;

give the identical results and have the same space and time requirements in a running GAMS job. AFAIK they both produce identical internal representations of this statement.

-Steve