How to filter elements with identical indices in GAMS? - gams-math

I have a GAMS model where I have
Set i / 1*6 /;
Alias (i,ip,il) ;
Variables
x(i,ip) ;
And I want to generate equations which operates on the scalar products of all vectors in x, excluding the product of the same vector. Something like:
scalarProduct(i)..
sum(ip,x(i,ip)x(i,il)) =e= someConstant;
However this does not exclude the product of identical vectors. How to add this? Can I do it with a dollar statement somehow? There's probably a few bugs in that statement anyway, I didn't try it because I think the exclusion I want is missing.

so what I wanted to do is this:
Sets
i / 1*13 /
ii(i,i) diagonal elements / #i:#i /
ij(i,i) all elements / #i.#i /
ij_wo_ii(i,i);
get all combinations without the diagonal elements:
ij_wo_ii(i,j) = ij(i,j) - ii(i,j);
and then I use it in an equation like this:
equation(j,k)..
sum(i,x(i,j)*x(i,k)$ij_wo_ii(j,k)) =l= 1;
This does something similar to orthogonality, except that the product of vectors in a matrix must be smaller than some value and not necessarily 0. don't know if there is a term for this. Hope it will be of use to someone else as well.

Related

is it possible to multiply two Gurobi linear expressions?

I want to perform the following operation in Gurobi for Java:
Create the summatory terms is easy through GRBLinExpr but I donwt know hot to multiply those two GRBLinExpr. is it possible?
No, but you can do this by adding intermediate variables for the sums, e.g. sx = sum(x[i]) and sy = sum(y[i]); then you can replace the product of the linear expressions by the product sx * sy.

In AMPL, how to refer to part of the result, and use them in multiple places

I'm learning AMPL to speed up a model currently in excel spreadsheet with excel solver. It basically based on the matrix multiplication result of a 1 x m variables and an m x n parameters. And it would find the variables to maximize the minimum of certain values in the result while keeping some other values in the same result satisfying a few constraints. How to do so in AMPL?
Given: P= m x n parameters
Variable: X= 1 x m variable we tried to solve
Calculate: R= X x P , result of matrix multiplication of X and P
Maximize: min(R[1..3]), the minimum value of the first 3 values in the result
Subject to: R[2]<R[4]
min(R[6..8])>20
R[5]-20>R[7]
X are all integers
I read several tutorials and look up the manual but can't find the solution to this seemingly straightforward problem. All I found is maximize a single value, which is the calculation result. And it was used only once and does not appear again in the constraint.
The usual approach for "maximize the minimum" problems in products like AMPL is to define an auxiliary variable and set linear constraints that effectively define it as the minimum, converting a nonlinear function (min) into linear rules.
For instance, suppose I have a bunch of decision variables x[i] with i ranging over an index set S, and I want to maximize the minimum over x[i]. AMPL syntax for that would be:
var x_min;
s.t. DefineMinimum{i in S}: x_min <= x[i];
maximize ObjectiveFunction: x_min;
The constraint only requires that x_min be less than or equal to the minimum of x[i]. However, since you're trying to maximize x_min and there are no other constraints on it, it should always end up exactly equal to that minimum (give or take machine-arithmetic epsilon considerations).
If you have parameters (i.e. values are known before you run the optimisation) and want to refer to their minimum, AMPL lets you do that more directly:
param p_min := min{j in IndexSet_P} p[j];
While AMPL also supports this syntax for variables, not all of the solvers used with AMPL are capable of accepting this type of constraint. For instance:
reset;
option solver gecode;
set S := {1,2,3};
var x{S} integer;
var x_min = min{s in S} x[s];
minimize OF: sum{s in S} x[s];
s.t. c1: x_min >= 5;
solve;
This will run and do what you'd expect it to do, because Gecode is programmed to recognise and deal with min-type constraints. However, if you switch the solver option to gurobi or cplex it will fail, since these only accept linear or quadratic constraints. To apply a minimum constraint with those solvers, you need to use something like the linearization trick I discussed above.

In GAMS, how to deal with divisions?

In my GAMS model, I have a objective function that involves a division.
GAMS sets the initial values to zero whenever it solves something...brilliant idea, how could that possibly ever go wrong!....oh wait, now there's division by zero.
What is the approach to handle this? I have tried manually setting lower bounds such that division by zero is avoided, but then GAMS spits out "infeasible" solution.
Which is wrong, since I know the model is feasible. In fact, removing the division term from my model and resolving does produce a solution. This solution ought to be feasible for the original problem as well, since we are just adding terms to the objective.
Here are some common approaches:
set a lower bound. E.g. Z =E= X/Y, add Y.LO = 0.0001;
similarly, write something like: Z =E= X/(Y+0.0001)
set a initial value. E.g. Y.L = 1
Multiply both sides by Y: Z*Y =E= X
For any non-linear variable you should really think carefully about bounds and initial values (irrespective of division).
Try using the $ sign. For example: A(i,j)$C(i,j) = B(i,j) / C(i,j)

"Precomputation" of a matrix in mathprog

I have a domain problem formulation in MathProg, where the cost function uses geometrical distances. The data sets contain only X,Y coordinates and not the actual distances. Right now, my formulation calculates the distances directly:
minimize total: sum{(f, c) in S} x[f, c] * sqrt(((facilityXs[f] - customerXs[c])**2) + ((facilityYs[f] - customerYs[c])**2));
And I want to know, whether the MathProg compiler is smart enough to see that the expression inside sqrt is constant and thus the whole thing can be precomputed, or whether it recalculates the expression every time, and how can I write it in a more elegant way.
Yes the MathProg 'compiler' is smart enough. It will precompute all equations containing solely parameters (and then create a computation matrix containing just one numeric value per cell). If you put variables in non linear functions like sqrt() the precomputation will fail.
A more elegant way is to keep your core set of equations linear. I often use separate parameters calculated by 'prequations', to keep the main formulations clean and simple.
param distance{(f,c) in S} := sqrt(((facilityXs[f] - customerXs[c])**2) + ((facilityYs[f] - customerYs[c])**2);
minimize total: sum{(f, c) in S} x[f, c] * distance[f,c]);
If the expression inside sqrt doesn't contain variables, then it will be evaluated at the translation stage and sent to the solver as a constant (coefficient of x[f, c]).

how to use scipy.ndimage.convolve for a given stencil?

I need to do something very similar to what is detailed in this post. But the way the stencils are done are not obvious to me... well the stencil for _flux is, but the ones for temp_bz & temp_bx are not.
I think the picture would get clearer with variables, instead of numbers (something like stencil = np.array([[a, b], [c, d]]) with a=0.5, b=...
As example, if the recurrence relation is
flux2[i,j] = a*flux2[i-1,j] + b*bz[i-1,j]*dx + c*flux2[i,j-1] - d*bx[i,j-1]*dz
how the code would be changed ?
Having flux2, bz and bx variables, and assuming they are numpy arrays (if they are not, they should), you could write that ecuation in a vectorized form as follows:
flux2[1:,1:] = a * flux2[:-1,1:] + b * bz[:-1,1:] * dx + c * flux2[1:,:-1] - d * bx[1:,:-1] * dz
Note that, since you didn't mention dz, I assumed it is a constant, if it is a matrix of the same shape as flux2, replace with dz[1:, 1:] (same applies to dx).
That line above will vectorize the operation to every i,j of the matrix, and thus, remove the for loop, giving a considerable speedup.
You would have to define the boundary conditions for row and column 0, as your equation doesn't define what to do in those special cases.
So, in short, as your stencil only uses one position for each variable, and only has 4 interactions, I would say is way faster to calculate it in its analytic form, rather than convolving 3 images with almost all-0 stencils (which would be quite a lot of overkill).