Create region/limits for NMinimize from list

NMinimize can accept a region to optimize over. I'm looking to create an expression that represents a region from a list of limits e.g.

limits = {{500, 5000}, {1000, 4000}, {1000, 10000}, {1000, 50000}};


Output:

{500<t[1]<5000 && 1000<t[2]< 4000 && 1000<t[3]<10000 && 1000<t[4]<500000}


However, I can't do it from the list, this is the best I can do

variables = Table[t[i], {i, Length[taus]}];
limits = {{500, 5000}, {1000, 4000}, {1000, 10000}, {1000, 50000}};

limits = Flatten[
Table[{limits[[i, 1]] < variables[[i]] < limits[[i, 2]] "&&"}, {i,
1, Length[variables], 1}]]

(* Output is wrong: {500 < t[1] < 5000 "&&", 1000 < t[2] < 4000 "&&",
1000 < t[3] < 10000 "&&", 1000 < t[4] < 50000 "&&"} *)

• NMinimize[f, Array[t, Length@limits] \[Element] Cuboid @@ Transpose@limits]. Mar 25, 2021 at 20:31

limits = {{500, 5000}, {1000, 4000}, {1000, 10000}, {1000, 50000}};
ClearAll[f]
f[{min_, max_}, {pos_}] := min < t[pos] < max
And @@ MapIndexed[f, limits]

(* Out: 500 < t[1] < 5000 && 1000 < t[2] < 4000 && 1000 < t[3] < 10000 && 1000 < t[4] < 50000 *)


Note that the output format is slightly different from what you asked. It seems to me that it would be better to either have a list of conditions, or conditions joined by And, but not both. If you do actually need a single-element list of the conditions joined by And, then change the last line to List[And @@ MapIndexed[f, limits]].

We can use Thread.

limits = {{500, 5000}, {1000, 4000}, {1000, 10000}, {1000, 50000}};
variables = Array[t, Length@limits];
NMinimize[{Norm[variables],
Thread[First /@ limits < variables < Last /@ limits]}, variables]


{1802.78, {t[1] -> 500.001, t[2] -> 1000., t[3] -> 1000., t[4] -> 1000.}}

Or

limits = {{500, 5000}, {1000, 4000}, {1000, 10000}, {1000, 50000}};
variables = Array[t, Length@limits];
NMinimize[{Norm[variables],
Thread[limits[[All, 1]] < variables < limits[[All, 2]]]}, variables]


{1802.78, {t[1] -> 500.001, t[2] -> 1000., t[3] -> 1000., t[4] -> 1000.}}

Or

limits = {{500, 5000}, {1000, 4000}, {1000, 10000}, {1000, 50000}};
variables = Array[t, Length@limits];
NMinimize[{Norm[variables],
Thread[variables ∈ Interval /@ limits]}, variables]


{1802.78, {t[1] -> 500.001, t[2] -> 1000., t[3] -> 1000., t[4] -> 1000.}}

• Thread[Thread[limits][[1]] < variables < Thread[limits][[2]]] Mar 25, 2021 at 23:51
constraint = Thread @* Between;

constraint [Array[t, Length @ limits], limits]

{500 <= t[1] && t[1] <= 5000,
1000 <= t[2] && t[2] <= 4000,
1000 <= t[3] && t[3] <= 10000,
1000 <= t[4] && t[4] <= 50000}

 Simplify @ %

{500 <= t[1] <= 5000,
1000 <= t[2] <= 4000,
1000 <= t[3] <= 10000,
1000 <= t[4] <= 50000}


Let us call the function you want to minimize f[x]. For a simple example I choose f[x_]=x^2. With this:

f[x_] = x^2;
limits = {{500, 5000}, {1000, 4000}, {1000, 10000}, {1000, 50000}};
NMinimize[{f[x], #[[1]] < x < #[[2]]}, x] & /@ limits

(* {{250000., {x -> 500.}}, {1.*10^6, {x -> 1000.}}, {1.*10^6, {x ->
1000.}}, {1.*10^6, {x -> 1000.}}}*)

• I don't think this is what OP had in mind. They have a function of four variables, not a function of one variable over different ranges. Mar 26, 2021 at 2:43