4
$\begingroup$

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 "&&"} *) 
$\endgroup$
1
  • 2
    $\begingroup$ NMinimize[f, Array[t, Length@limits] \[Element] Cuboid @@ Transpose@limits]. $\endgroup$
    – Michael E2
    Mar 25, 2021 at 20:31

4 Answers 4

3
$\begingroup$
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]].

$\endgroup$
2
$\begingroup$

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.}}

$\endgroup$
1
  • $\begingroup$ Thread[Thread[limits][[1]] < variables < Thread[limits][[2]]] $\endgroup$
    – cvgmt
    Mar 25, 2021 at 23:51
1
$\begingroup$
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}
$\endgroup$
-1
$\begingroup$

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.}}}*)
$\endgroup$
1
  • 1
    $\begingroup$ 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. $\endgroup$
    – MarcoB
    Mar 26, 2021 at 2:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.