Last edit: 2016-05-03
A.G.'s answer was the one helped me the most, see explanation at the end of this question.
Original question
In Mathematica you can create out of a set of points in 2D and 3D the convex hull and use it as a region for optimization problem, e.g.,
(*Dimension and number of points*)
d = 2;
np = 10;
(*Generate data and convex hull*)
int = {5, 10};
data = RandomReal[int, {np, d}];
ch = ConvexHullMesh@data;
(*Optimize on convex hull*)
var = Array[v, d];
max = Maximize[var.var, Element[var, ch]];
pic = Show[{ch,
Graphics[{Point[data], PointSize -> Large, Red,
Point[var /. max[[2]]]}]}, Axes -> True]
You can also performe optimization problems in higher dimensions, e.g.,
d = 7;
reg = Ball[ConstantArray[0, d], 3];
var = Array[v, d];
Maximize[var.var, Element[var, reg]]
(* {9, {v[1] -> -3, v[2] -> 0, v[3] -> 0, v[4] -> 0, v[5] -> 0, v[6] -> 0, v[7] -> 0}} *)
But now suppose we have a set of 5D vectors $\{c_1,c_2,...,c_m\}, c_i \in \mathbb{R}^5$ and we consider the set of all possible convex combinations of them (so we consider the convex hull $C$ of them).
\begin{equation} C = \left\{ v \in \mathbb{R}^5 \ : \ \sum_{i=1}^m w_i c_i = v \ , \quad \sum_{i=1}^m w_i = 1 \ , \quad w_i \geq 0 \ \forall \ i \right\} \end{equation}
I know how to obtain the corners of a given set of points (data
), see this question
How to generate higher dimensional convex hull?
But even if we would not know how to, we could still just used the original data. Is there any way to define in Mathematica a region, I dont know, may be with ImplicitRegion
, which then can be used for optimization problems as in the 2D and 7D examples above? By that I mean something like the following (not working) structure.
(*Dimension and number of points*)
d = 5;
np = 4;
(*Generate data and region*)
int = {5, 10};
data = RandomReal[int, {np, d}];
reg = ImplicitRegion[
w1*data[[1, 1]] + w2*data[[2, 1]] + w3*data[[3, 1]] + w4*data[[4, 1]] == x1
&& w1*data[[1, 2]] + w2*data[[2, 2]] + w3*data[[3, 2]] + w4*data[[4, 2]] == x2
&& w1*data[[1, 3]] + w2*data[[2, 3]] + w3*data[[3, 3]] + w4*data[[4, 3]] == x3
&& w1*data[[1, 4]] + w2*data[[2, 4]] + w3*data[[3, 4]] + w4*data[[4, 4]] == x4
&& w1*data[[1, 5]] + w2*data[[2, 5]] + w3*data[[3, 5]] + w4*data[[4, 5]] == x5
&& w1 + w2 + w3 + w4 == 1
&& w1 >= 0 && w2 >= 0 && w3 >= 0 && w4 >= 0
, {x1, x2, x3, x4, x5}
];
(*Optimize on convex hull*)
var = Array[v, d];
max = NMaximize[var.var, Element[var, reg]];
I just dont know how to formulate correctly the region. I can test candidate points cand
for given data/corner points corners
with the function
TestCandidate[corners_, cand_] := Block[
{ws, w, eqs, fi},
ws = Array[w, {Length[corners]}];
eqs = Sum[ws[[i]]*corners[[i]], {i, Length@corners}] - cand;
eqs = Flatten@Join[
Table[eqs[[i]] == 0, {i, Length@eqs}]
, {Total[ws] == 1}
, Table[ws[[i]] >= 0, {i, Length@ws}]
];
eqs = And @@ eqs;
fi = FindInstance[eqs, ws];
Length@fi != 0
];
e.g., I can test that the data
can represent itself
And @@ Table[TestCandidate[data, data[[i]]], {i, Length@data}]
True
and also other candidate points cand
. But I have not been able to formulate a region with this function. Any ideas on how to formulate the region for given data
?
EDIT - 2016-05-03
Thank you very much for the answers. From my point of view, Chip's answer is excellent but A.G.'s answer is the best one, since it made me recognize that the optimization can be carried out a lot easier over the simplex he pointed out. You can treat then any problem for given data following his recommendation as follows
(*Dimension and number of points*)
d = 9;
np = 10^2;
(*Generate data*)
data = RandomReal[{1, 2}, {np, d}];
(*Weights and region*)
ws = Array[w, Length[data]];
reg = Simplex[Table[UnitVector[np, k], {k, np}]];
(*Function and optimization*)
v = Sum[ws[[i]]*data[[i]], {i, Length@data}];
f = Sin[v.v] + 1/v.v;
NMinValue[{f, Total[ws] == 1, Table[0 <= ws[[i]], {i, Length@ws}]},
ws] // Quiet // AbsoluteTiming
NMinValue[f, Element[ws, reg]] // Quiet // AbsoluteTiming
{263.576, -0.942131}
{270.522, -0.942131}
The main problem is not the dimensionality of the vector variables v
, as he pointed out, but the size of the data, and therefore, the number of ws
. As you can see, you can either use the conditions for the ws
directly or use the Simplex
(see also Wikipedia), which is equivalent in this case. Both seem to be equally fast (around 270 seconds for the created data on 4 cores). If you want to reduce your data to the corners of the convex hull, see again the linked question
ImplicitRegion
, you need to use inequalities. To obtain these inequalities, you must necessarily find the convex hull because the inequalities that you need define the facets bounding your region. Fukuda explains very well certain concepts related to your problem on its web page. So if you find the convex hull, you can find the inequalities of the facets, define anImplicitRegion
and use it to your optimization problems. $\endgroup$