# NMinimize too slow with non-linear constraints. Help to speed it up

First, let me introduce some parameters:

x = 0.07421875;
qB = 0.40625;
\[Delta]B = 0.25;
\[Delta]G = 0.5;
PB = 0.75;
PG = 0.5;
u = 4.0;
uG = 2.0;
uB = 1.0;
qG = 1 - qB;
wg = PG*uB + (1 - PG)*uG;
\[Beta] = 0.98;


I need to solve numerically optimization problems given by the function fun:

zeroV[\[Mu]B_, \[Mu]G_, wB_, wG_] := 0*\[Mu]B + 0*\[Mu]G + 0*wB + 0*wG;

cpobjective =  Compile[{s1, s2, s3, s4, \[Mu]B, \[Mu]G, wB, wG},
Evaluate[\[Mu]B + s1 \[Delta]B*PB ((u - s3)/(u - wg)) + s2*\[Delta]G*PG ((u - s4)/(u - wg)) + \[Beta]*
zeroV[\[Mu]B, \[Mu]G, wB, wG]],
CompilationTarget -> "C",
"RuntimeOptions" -> {"EvaluateSymbolically" -> False},
CompilationOptions -> {{"InlineExternalDefinitions" -> True}}];

fun[s_] :=
NMinimize[{cpobjective[s[[1]], s[[2]], s[[3]],    s[[4]], \[Mu]B, \[Mu]G, wB, wG],
{\[Mu]B >= 0, \[Mu]B <= qB, \[Mu]G >= 0, \[Mu]G <= qG, wB >= wg, wB <= u, wg - wG <= 0, wG <= u, \[Mu]B*(2*u - uG - \[Delta]G*wB)* qG >= \[Mu]G*(2*u - uG - \[Delta]G*wG)* qB, (1 - \[Mu]B - \[Mu]G) (u - wg) <=  x (u - wg) - s[[1]]*\[Delta]B*((s[[3]] - wg)) -  s[[2]]*\[Delta]G*((s[[4]] - wg)),  x (u - wg) >= \[Mu]B*\[Delta]B*((wB -  wg)) + \[Mu]G*\[Delta]G*((wG - wg))}}, {\[Mu]B, \[Mu]G, wB,    wG},
Method -> {"NelderMead", "InitialPoints" -> {{qB, qG, wg, wg}}}]


Many many many times. (It is the most inner loop in a dynamic programming problem); The function zeroV is just an example. In my machine (Core i5, @ 2.40GHz), it takes 0.6 seconds in Mathematica v.12.2. to evaluate fun

fun[{0, 0, 3.2, 3.2}] // AbsoluteTiming
(*{0.629229, {0.361741, {\[Mu]B -> 0.361741, \[Mu]G -> 0.56404, wB -> 1.5, wG -> 2.15792}}}  *)


I have done everything that I can within my limited knowledge of Mathematica to speed it up. I come to you guys to see if you have any ideas on how to speed up this. I think that the big problem comes from the non-linear constraints in the minimization, but I am not sure.

Your help will be very much appreciated.

Thanks!

• It looks like Compile makes your code slow. Nov 4, 2021 at 4:55
• 0*\[Mu]B + 0*\[Mu]G + 0*wB + 0*wG is 0. Nov 4, 2021 at 6:30
• @user64494, indeed, it is a toy example ;) Nov 4, 2021 at 7:49