Bob Fourer
4...@ampl.com
Thanks for your reply.
What about applying the following method: declaring the variable, and
then using a constraint - which includes an "if-then-else" statement -
to define it? My code would be as follows:
var Falfa {t in SBC};
subject to Falfa_polynomial {t in SBC}:
Falfa[t] = if (a0[t]<=PG_A<=a1[t]) then
b0[t]+(PG_A-a0[t])*(b1[t]-b0[t])/(a1[t]-a0[t])
else if (a1[t]<PG_A<=a2[t]) then b1[t]+(PG_A-a1[t])*(b2[t]-b1[t])/(a2[t]-a1[t])
else if (a2[t]<PG_A<=a3[t]) then b2[t]+(PG_A-a2[t])*(b3[t]-b2[t])/(a3[t]-a2[t]);
where:
- SBC is a set
- ai[t] and bi[t] are parameters defined in SBC
- PG_A is an indipendent variable (one of the outputs of my optimization probem)
- Falfa is a function of PG_A, which should be mathematically
represented by means of different polynomials depending on the values
PG_A assumes
May the above-mentioned code be correct and well- managed by AMPL, in
the context of a main optimization model (it's an OPTIMAL POWER FLOW
model)?
Looking forward to hearing back from you again soon.
Thanks in advance for your help.
Regards,
Claudia
2009/1/29, Robert Fourer <4...@ampl.com>:
--
Claudia Battistelli
St. Paul's United College at the University of Waterloo
196 Westmount Road North
Waterloo, Ontario, Canada N2L 3G5
Home Phone: (+1) 519-772-8666
Cell Phone: (+1) 519-498-7940
A variable in the expression after "if" is not going to work in a
constraint, for the same reason that it does not work in a var declaration.
However, it appears you're trying to write a piecewise-linear function of
the variable PG_A, which is such a common case that AMPL has a special
expression for it, in terms of the breakpoints and slopes of the function.
You could say
var PG_A >= a0, <= a3;
var Falfa {t in SBC} = b0[t] + <<a1[t],a2[t];
(b1[t]-b0[t])/(a1[t]-a0),
(b2[t]-b1[t])/(a2[t]-a1[t]),
(b3[t]-b2[t])/(a3-a2[t])>> (PG_A,a0);
Inside the delimiters <<...>> are a list of breakpoints and a list of slopes
surrounding the breakpoints. The argument "(PG_A,a0)" indicates that this
is a piecewise-linear function of the variable PG_A, and that the function
has value 0 at a0; adding b0[t] causes it to have value b0[t] at a0, as
required.
You can specify a0[t] and a3[t] in place of a0 and a3, because each Falfa[t]
needs to be defined over the full range of possible values of PG_A.
See chapter 17 of the AMPL book for more on piecewise-linear functions.
It doesn't work to use expressions like
var phiZ {i in 1..dimx, j in 1..dimy, k in 1..n} =
if (pz[k] < minz) then ...
where there is a variable in the condition between the "if" and the "then". Some nonlinear solvers will attempt to evaluate the if-expressions and solve such a problem, but they will not be able to deal with the discontinuities in the slopes of these functions.
I should have said, "... you will have to introduce some zero-one variables and convert your model to a form that can be handled by a solver for linear mixed-integer programming." This means replacing definitions like
var zi {i in 1..n, j in 1..dimz} =
if (pz[i] >= i + minz and pz[i] < i + 1 + minz) then 1 else 0;
with linear constraints on "var zi {...} binary;". When you use one-dimensional piecewise-linear notation, AMPL does this for you, but that does not help when you are doing 3D interpolation. Instead you might extend the ideas in the following post concerning 2D interpolation:
http://groups.google.com/group/ampl/browse_thread/thread/ce5d9a5b57868f20/099a400a4a6176ea?lnk=gst&q=anyhow+to+specify+the+sos2#099a400a4a6176ea
The "SOS2" mentioned there is a way of specifying that out of an ordered set of variables, at most two adjacent ones can be nonzero.
Bob Fourer
From: ying...@gmail.com [mailto:ying...@gmail.com]
Sent: Sunday, April 28, 2013 10:00 PM
To: am...@googlegroups.com
Cc: 'C B'; 4...@ampl.com
Subject: Re: [AMPL 2194] Re: "If" statement on a variable
Hi Robert,
I was having a similar problem with AMPL's if statements and I found this post. I'll really appreciate it if you could give me some helpful information.
In the code below, there is a 3D grid with dimensions: dimx, dimy, dimz and a phi value in each cell. px, py, pz are the coordinates of n points. What I want to do is to get the phi value at each point by interpolation.
param dimx;
param dimy;
param dimz;
param minx;
param miny;
param minz;
param phi {1..dimx, 1..dimy, 1..dimz};
param n;
var px;
var py;
var pz;
var phiZ {i in 1..dimx, j in 1..dimy, k in 1..n} =
if (pz[k] < minz) then phi[i,j,1]
else if (pz[k] >= minz and pz[k] < 1+minz) then phi[i,j,1] * (1-(pz[k]-minz)) + phi[i,j,2] * (pz[k]-minz)
etc.
var phiYZ {i in 1..dimx, j in 1..n} =
if (py[j] < miny) then phiZ[i,1,j]
else if (py[j] >= miny and py[j] < 1+miny) then phiZ[i,1,j] * (1-(py[i]-miny)) + phiZ[i,2,j] * (py[j]-miny)
etc.
However, this doesn't work. phiZ and phiYZ seem to be fixed after pz and py are initialized. I saw you saying "none of the solvers currently hooked to AMPL will know what to do with the resulting if-then-else expression", but I don't know how exactly AMPL treats these expressions. And you said "So as a practical matter, you will have to introduce some zero-one variables and convert your model to a form that can be handled by a solver for mixed-integer programming." Did you mean this:
var zi {i in 1..n, j in 1..dimz} =
if (pz[i] >= i + minz and pz[i] < i + 1 + minz) then 1
else 0;
var phiZ {i in 1..dimx, j in 1..dimy, k in 1..n} = sum (expression[k] * zi[k]);
I also tried the piecewise-linear function approach. It works for phiZ but not for phiYZ since the piecewise-linear function has variable phiZ in it.
Could you think of any solution to my problem? Thanks for your attention!
Best,
Lucy