Define the function for distance matrix in ampl. Keep getting "i is not defined" - ampl

I'm trying to set up a ampl model which clusters given points in a 2-dimensional space according to the model of Saglam et al(2005). For testing purposes I want to generate randomly some datapoints and then calculate the euclidian distance matrix for them (since I need this one). I'm aware that I could only make the distance matrix without the data points but in a later step the data points will be given and then I need to calculate the distances between each the points.
Below you'll find the code I've written so far. While loading the model I keep getting the error message "i is not defined". Since i is a subscript that should run over x1 and x1 is a parameter which is defined over the set D and have one subscript, I cannot figure out why this code should be invalid. As far as I understand, I don't have to define variables if I use them only as subscripts?
reset;
# parameters to define clustered
param m; # numbers of data points
param n; # numbers of clusters
# sets
set D := 1..m; #points to be clustered
set L := 1..n; #clusters
# randomly generate datapoints
param x1 {D} = Uniform(1,m);
param x2 {D} = Uniform(1,m);
param d {D,D} = sqrt((x1[i]-x1[j])^2 + (x2[i]-x2[j])^2);
# variables
var x {D, L} binary;
var D_l {L} >=0;
var D_max >= 0;
#minimization funcion
minimize max_clus_dis: D_max;
# constraints
subject to C1 {i in D, j in D, l in L}: D_l[l] >= d[i,j] * (x[i,l] + x[j,l] - 1);
subject to C2 {i in D}: sum{l in L} x[i,l] = 1;
subject to C3 {l in L}: D_max >= D_l[l];
So far I tried to change the line form param x1 to
param x1 {i in D, j in D} = ...
as well as
param d {x1, x2} = ...
Alas, nothing of this helped. So, any help someone can offer is deeply appreciated. I searched the web but I found nothing useful for my task.

I found eventually what was missing. The line in which I calculated the parameter d should be
param d {i in D, j in D} = sqrt((x1[i]-x1[j])^2 + (x2[i]-x2[j])^2);
Retrospectively it's clear that the subscripts i and j should have been mentioned on the line, I don't know how I could miss that.

Related

Variable size element in embedded function but fixed input and output

I have a fixed input and output for my simulink embeded function.
However I would like to compute a variable size element inside the function, (only used for calculation).
Therefore I would prefer not to declare the block as receiving or sending dynamic size signal. (or using coder.varsize)
ex:
K = find( p_var(:) == 0 ); % p_var is a vector containing some zeros
p_var(K) = []; % p_var is a therefore a varsize vector
% the variability is something I need for reason
n = length(p_var) % n is dynamic
M = ones(10,n) % M & L are also dynamic
L = ones(n,50)
G = M*L; % G is fixed of size [10*50]
Here the variable G is always fixed... but I have this type of error :
Dimension 2 is fixed on the left-hand side but varies on the right ([1 x 9] ~= [1 x :?])
Thank you for your time.
You have to define an upper bound for the size of p_var. This can be done in a couple of ways, such as using coder.varsize as shown below.
A couple of other things to note:
If p_var is an input to your function you cannot change its size,but would need a temporary variable as shown below.
You most likely do not want to use find as you have done, but should use logical indexing instead.
function G = fcn(u)
p_var = u;
coder.varsize('p_var', [10,1]);
p_var(p_var(:) == 0) = []; % p_var is therefore a varsize vector
the variability is something I need for reason
n = length(p_var); % n is dynamic
M = ones(10,n); % M & L are also dynamic
L = ones(n,50);
G = M*L; % G is fixed of size [10*50]

Constrained quadratic minimization in Mathematica with matrices

I'm attempting to solve the familiar mean-variance optimization problem using matrices in Mathematica, with a few added constraints on the solution vector "w". (The mean-variance optimization problem is basically choosing how to allocate a given budget over a number of assets according to their means and covariances in order to minimize the risk of the portfolio for a chosen level of mean return.)
My question: I'm not sure which function to use to perform the minimization of the objective function, which is quadratic:
obj = 0.5*w'* Sig * w
where w is the Nx1 vector of weights for each of the N assets and Sig is the NxN covariance matrix
From what I've been able to find (I'm fairly new to Mathematica), it seems that FindMinimum, NMinimize, etc. are meant to deal only with scalar inputs, while LinearProgramming is meant for an objective function that's linear (not quadratic) in the weight vector w. I could very well be wrong here--any help in steering me toward the correct function would be much appreciated!
If it helps, I've attached my sample code--I'm not sure how, but if there's a place to upload the sample .csv data, I can do that as well if someone could point me to it.
Thank you very much for any help you can provide.
-Dan
CODE
(* Goal: find an Nx1 vector of weights w that minimizes total \
portfolio risk w'*Sig*w (where Sig is the covariance matrix) subject to:
-The portfolio expected return is equal to the desired level d: w'*M \
= d, where M is the Nx1 vector of means
-There are exactly two assets chosen from each of the refining, \
construction, hitech, and utility sectors, and exactly one asset \
chosen from the "other" sector
^ The above two constraints are represented together as w'*R = k, \
where R is the matrix [M SEC] and k is the vector [d 2 2 2 2 1]
-Each weight in w takes an integer value of either 0 or 1, \
representing buying or not buying that physical asset (ex. a plant) -- \
this constraint is achieved as a combination of an integer constraint \
and a boundary constraint
**Note that for the T=41 days of observations in the data, not every \
asset generates a value for every day; by leaving the days when the \
asset is "off" as blanks, this shouldn't affect the mean or \
covariance matrices.
*)
Clear["Global`*"]
(* (1) Import the data for today *)
X = Import["X:\\testassets.csv", "Data"];
Dimensions[X];
(* (2) Create required vectors and matrices *)
P = Take[X, {2, 42}, {4}];
Dimensions[P]; (* Should be N assets x 1) *)
r = Take[X, {2, 42}, {10, 50}];
Dimensions[r]; (* Should be N x T *)
Sig = Covariance[
r]; (* When there's more time, add block diagonal restriction here \
*)
Dimensions[Sig]; (* Should be N x N *)
M = Mean[r\[Transpose]];
Dimensions[M]; (* Should be N x 1 *)
SEC = Take[X, {2, 42}, {5, 9}];
Dimensions[SEC]; (* Should be N x 5 *)
(* (3) Set up constrained optimization *)
d = 200; (* desired level of return *)
b = 60000;(* budget constraint *)
R = Join[M, POS];
Dimensions[R]; (* Should be N x 6 *)
k = {d, 2, 2, 2, 2, 1};
obj = w*Sig*w\[Transpose];
constr = w*R;
budgetcap = w*P;
lb = ConstantArray[0, 41];
ub = ConstantArray[1, 41];
FindMinimum[{obj, constr = k, budgetcap <= b, Element[w, Integers],
lb <= w <= ub}, w]

AMPL: Subscript out of bound

Hello fellow optimizers!
I'm having some issues with the following constraint:
#The supply at node i equals what was present at the last time period + any new supply and subtracted by what has been extracted from the node.
subject to Constraint1 {i in I, t in T, c in C}:
l[i,t-1,c] + splus[i,t] - sum{j in J, v in V, a in A} x[i,j,v,t,c,a]= l[i,t,c];
which naturally causes this constraint to provide errors the first time it loops, as the t-1 is not defined (for me, l[i,0,c] is not defined. Where
var l{I,T,C} >= 0; # Supply at supply node I in time period T for company C.
param splus{I,T}; # Additional supply at i.
var x{N,N,V,T,C,A} integer >= 0; #Flow from some origin within N to a destination within N using vehicle V, in time T, for company C and product A.
and set T; (in the .mod) is a set defined as:
set T := 1 2 3 4 5 6 7; in the .dat file
I've tried to do:
subject to Constraint1 {i in I, t in T: t >= 2, c in C}:
all else same
which got me a syntax error. I've also tried to include "let l[1,0,1] := 0" for all possible combinations, which got me the error
error processing var l[...]:
no data for set I
I've also tried
subject to Constraint1 {i in I, t in T, p in TT: p>t, c in C}:
l[i,t,c] + splus[i,p] - sum{j in J, v in V, a in A} x[i,j,v,p,c,a]= l[i,p,c];
where
set TT := 2 3 4 5 6;
in the .dat file (and merely set TT; in the .mod) which also gave errors. Does someone have any idea of how to do this?
One way to fix this is to specify the condition t >= 2 at the end of the indexing expression:
subject to Constraint1 {i in I, t in T, c in C: t >= 2}:
...
See also Section A.3 Indexing expressions and subscripts for more details on syntax of indexing expressions.

Matlab: how do I run the optimization (fmincon) repeately?

I am trying to follow the tutorial of using the optimization tool box in MATLAB. Specifically, I have a function
f = exp(x(1))*(4*x(1)^2+2*x(2)^2+4*x(1)*x(2)+2*x(2)+1)+b
subject to the constraint:
(x(1))^2+x(2)-1=0,
-x(1)*x(2)-10<=0.
and I want to minimize this function for a range of b=[0,20]. (That is, I want to minimize this function for b=0, b=1,b=2 ... and so on).
Below is the steps taken from the MATLAB's tutorial webpage(http://www.mathworks.com/help/optim/ug/nonlinear-equality-and-inequality-constraints.html), how should I change the code so that, the optimization will run for 20 times, and save the optimal values for each b?
Step 1: Write a file objfun.m.
function f = objfun(x)
f = exp(x(1))*(4*x(1)^2+2*x(2)^2+4*x(1)*x(2)+2*x(2)+1)+b;
Step 2: Write a file confuneq.m for the nonlinear constraints.
function [c, ceq] = confuneq(x)
% Nonlinear inequality constraints
c = -x(1)*x(2) - 10;
% Nonlinear equality constraints
ceq = x(1)^2 + x(2) - 1;
Step 3: Invoke constrained optimization routine.
x0 = [-1,1]; % Make a starting guess at the solution
options = optimoptions(#fmincon,'Algorithm','sqp');
[x,fval] = fmincon(#objfun,x0,[],[],[],[],[],[],...
#confuneq,options);
After 21 function evaluations, the solution produced is
x, fval
x =
-0.7529 0.4332
fval =
1.5093
Update:
I tried your answer, but I am encountering problem with your step 2. Bascially, I just fill the my step 2 to your step 2 (below the comment "optimization just like before").
%initialize list of targets
b = 0:1:20;
%preallocate/initialize result vectors using zeros (increases speed)
opt_x = zeros(length(b));
opt_fval = zeros(length(b));
>> for idx = 1, length(b)
objfun = #(x)objfun_builder(x,b)
%optimization just like before
x0 = [-1,1]; % Make a starting guess at the solution
options = optimoptions(#fmincon,'Algorithm','sqp');
[x,fval] = fmincon(#objfun,x0,[],[],[],[],[],[],...
#confuneq,options);
%end the stuff I fill in
opt_x(idx) = x
opt_fval(idx) = fval
end
However, it gave me the output is:
Error: "objfun" was previously used as a variable, conflicting
with its use here as the name of a function or command.
See "How MATLAB Recognizes Command Syntax" in the MATLAB
documentation for details.
There are two things you need to change about your code:
Creation of the objective function.
Multiple optimizations using a loop.
1st Step
For more flexibility with regard to b, you need to set up another function that returns a handle to the desired objective function, e.g.
function h = objfun_builder(x, b)
h = #(x)(objfun(x));
function f = objfun(x)
f = exp(x(1))*(4*x(1)^2+2*x(2)^2+4*x(1)*x(2)+2*x(2)+1) + b;
end
end
A more elegant and shorter approach are anonymous functions, e.g.
objfun_builder = #(x,b)(exp(x(1))*(4*x(1)^2+2*x(2)^2+4*x(1)*x(2)+2*x(2)+1) + b);
After all, this works out to be the same as above. It might be less intuitive for a Matlab-beginner, though.
2nd Step
Instead of placing an .m-file objfun.m in your path, you will need to call
objfun = #(x)(objfun_builder(x,myB));
to create an objective function in your workspace. In order to loop over the interval b=[0,20], use the following loop
%initialize list of targets
b = 0:1:20;
%preallocate/initialize result vectors using zeros (increases speed)
opt_x = zeros(length(b))
opt_fval = zeros(length(b))
%start optimization of list of targets (`b`s)
for idx = 1, length(b)
objfun = #(x)objfun_builder(x,b)
%optimization just like before
opt_x(idx) = x
opt_fval(idx) = fval
end

"Out of domain" error in MathProg (GLPK)

I am struggling with a seemingly simple model in MathProg. The model is as follows:
set W;
set V;
param b {W, V} binary;
param p;
var w {j in W} <= 0, >= 1;
minimize obj: 0;
subject to within_radius_of {i in V}:
sum {j in W} b[i,j] * w[j] >= 1;
subject to p_limit:
sum {j in W} w[j] <= p;
end;
When I run it, it gives me the error feasibility.glp:11: b[v1,w1] out of domain. I have no idea what is going wrong. Even more strange to me, if I change the relevant line to b[j,i] it keeps giving the exact same error (not b[w1,v1] as I expected).
I inspected the AMPL Diet Example carefully, and despite me seeing no difference in the relevant part of my model it still doesn't work. What is wrong?
Parameter b is declared as binary so it can only take values 0 or 1. You haven't provided a data file, but the error message suggests that the data for b is out of domain (not 0 or 1), for example:
data;
set W := w1;
set V := v1;
param b := w1 v1 0.5;
AMPL gives a more detailed error message in this case:
error processing param b['w1','v1']:
failed check: param b['w1','v1'] = 0.5
is not binary (0 or 1);
The reason why the order of indices doesn't matter in this case is that the data for b is checked completely before the model is actually instantiated. So it seems that w1 and v1 may be swapped in the data file.