## Wednesday, May 6, 2009

Hi Dear all,

I am new to GAMS and I am working on a MILP. I had been my code in AMPL.

Because of my solution capacity for the n > 8 had was too large, and I have a student version of AMPL then I want to change it in the GAMS representation.

I have two loop using FOR in my code, as:

for{i in 1..N} {
for{j in 1..N} {
for{p in 1..N} {
let a[i,j,p,i,j,p] := f[j,j] * d [ i,i] * f[p,p] * d[i,i] ;
for{k in 1..N} {
if(k <> i) then
for{n in 1..N} {
if(n <> j) then
for{q in 1..N} {
if(q <> p) then
let a[i,j,p,k,n,q]:= f[j,n] * d[i,k] * f[p,q] * d[i,k];
}
}
}
}
}
};

In the loop, f and d are two-dimensional matrix and i,j,p,k,n,q mention to elements of the matrices and N is a scalar as follow.

I have written the same loop in GAMS as:

* ----------------------------------------------

sets  i   /1*5/,
j   /1*5/,
p   /1*5/,
k   /1*5/,
n   /1*5/,
q   /1*5/ ;

scalar M size of problem /5/;

parameter   c(i,j,p,k,n,q);

Scalar N /5/ ;

* ----------------------------------------------
Table  f(i,i)
1    2    3    4    5
1         1    1    2    3
2    1         2    1    2
3    1    2         1    2
4    2    1    1         1
5    3    2    2    1       ;

* ------------------------------------------------------
Table  d(k,k)
1    2    3    4    5
1         5    2    4    1
2    5         3         2
3    2    3
4    4                   5
5    1    2         5       ;

* ------------------------------------------------------

for(i=1 to M,
for(j=1 to M,
for(p=1 to M,
a(i,j,p,i,j,p) = f(j,j) * d(i,i) * f(p,p) * d(i,i) ;
for(k=1 to M,
if(k ne i,
for(n=1 to M,
if(n ne j,
for(q=1 to M,
if(q ne p,
a(i,j,p,k,n,q) = f(j,n) * d(i,k) * f(p,q) * d(i,k) ;
);
);
);
);
);
);
);
);
);

* ----------------------------------------------

But there is an error regard to FOR. I know that it should be a scalar instead of i,j,p,k,n,q. but then who can I define the matrices?

This does not make much sense. Wow, this is very ugly and convoluted GAMS. At least from a syntactical point of view better would be:

* ----------------------------------------------
sets  i   /1*5/;
alias(i,j,p,k,n,q);

* ----------------------------------------------
Table  f(i,i)
1    2    3    4    5
1         1    1    2    3
2    1         2    1    2
3    1    2         1    2
4    2    1    1         1
5    3    2    2    1       ;
* ------------------------------------------------------
Table  d(k,k)
1    2    3    4    5
1         5    2    4    1
2    5         3         2
3    2    3
4    4                   5
5    1    2         5       ;
* ------------------------------------------------------

parameter a(i,j,p,k,n,q);
a(i,j,p,k,n,q) = f(j,n) * f(p,q) * sqr(d(i,k));

When you use GAMS in most cases you don’t need explicit loops: an assignment is an implicit loop. Also there is no advantage to split this into two assignments as suggested by the poster. Essentially he does:

a(i,j,p,i,j,p) = f(j,j) * f(p,p) * sqr(d(i,i));
a(i,j,p,k,n,q)\$(ord(k)<>ord(i) and ord(n)<>ord(j) and ord(q)<>ord(p)) = f(j,n) * f(p,q) * sqr(d(i,k));

These two statements have the same effect as the single statement shown before.

There seems to be a big misunderstanding here how to write GAMS and actually how to write loops (the splitting of the assignment is an indication of that).