# Both FindMinimum and NMinimize have trouble

I'm trying to minimize a function I wrote, in a not entirely elegant (but functional) way. As a side note, if you have advice on how to write this in a smarter way, that's also welcome.

In any case, the function is as follows:

LL = 1.74; CC = 300 10^-6; RR = 20000; CCJ = 30 10^-6; CCκ =
80 10^-6;
rules = {C1 -> CC - CCJ - CCκ, C2 -> CC - 2 CCJ,
C3 -> CC - CCJ, R1 -> RR, R2 -> RR, R3 -> RR, CJ1 -> CCJ,
CJ2 -> CCJ, CJ3 -> CCJ, Cκ -> CCκ, L1 -> LL,
L2 -> LL, L3 -> LL, ω -> 2 π ν,
Zc -> 50, ω0 -> 2 π 7.0};

GammaEq[ω_, rules_] :=
Module[{ain = 1., K,
Cκt, κ1, γ1, γ2, γ3, MC,
iC, ω1, ω2, ω3, J12, J23, J13, Dm,
r, Γ, Av},
K = 1 + (1/(Zc Cκ ω))^2;
Cκt = Cκ (1 - 1/K);

MC = ( {
{C1 + Cκt + CJ1 + CJ3, -CJ1, -CJ3},
{-CJ1, C2 + CJ1 + CJ2, -CJ2},
{-CJ3, -CJ2, C3 + CJ2 + CJ3}
} ) // FullSimplify;
iC = Inverse[MC];

κ1 = 1/(K Zc ) iC[[1, 1]]; γ1 =
1/R1  iC[[1, 1]]; γ2 = 1/R2  iC[[2, 2]]; γ3 =
1/R3  iC[[3, 3]];
ω1 = Sqrt[1/L1 iC[[1, 1]]]; ω2 = Sqrt[
1/L2 iC[[2, 2]]]; ω3 = Sqrt[1/L3 iC[[3, 3]]];
J12 = 1/2 iC[[1, 2]]/Sqrt[iC[[1, 1]] iC[[2, 2]]]
Sqrt[ω1 ω2];
J23 = 1/2 iC[[2, 3]]/Sqrt[iC[[2, 2]] iC[[3, 3]]]
Sqrt[ω2 ω3];
J13 = 1/2 iC[[1, 3]]/Sqrt[iC[[1, 1]] iC[[3, 3]]]
Sqrt[ω1 ω3];
Dm = {{ω1 - ω + (I γ1)/2 + (I κ1)/2, J12, J13},
{J12, ω2 - ω + (I γ2)/2, J23},
{J13, J23, ω3 - ω + (I γ3)/2}} /. rules // FullSimplify;
Av = I Sqrt[{κ1, 0, 0}] ain /. rules;
r = LinearSolve[Dm, Av];
Γ = 1 - Sqrt[{κ1, 0, 0}].r/ain /. rules;
Return[Γ]
]


What I then want is to plot the absolute value of the function

Plot[Abs[GammaEq[2*Pi*ω, rules]], {ω, 6, 8}]


which clearly has three minima: However, I'm having trouble finding the minima. I can approximately see them from the figure, but it would be nice to have a more exact number. Both FindMinimum and NMinimize complain about the numbers not being real (even though they are when you evaluate the function, as seen in the plot) which I suppose is due to the way the function is written. Could anyone recommend an approach?

• There's no need for an explicit Return[] at the end, if you remove the semicolon after the assignment on Γ. – J. M. is in limbo Jun 2 '15 at 21:17
• …why did you delete the code associated with your question? Unless you can give a good reason, I'll roll it back. – J. M. is in limbo Jun 3 '15 at 14:59
• Not on purpose actually, I think I pressed space at the end and took it all away. Thanks! – user129412 Jun 3 '15 at 15:50
• You had an unpleasant MatrixForm expression in your code. These very frequently cause problems: the documentation is not correct to say that "MatrixForm is a wrapper that affects display and not evaluation". I have removed it and substituted it with the standard form input. – Oleksandr R. Jun 3 '15 at 16:14

define GammaEq so that it takes only numeric arguments,

 Clear[GammaEQ]
GammaEq[ω_?NumericQ, rules_] := ...


and give FindMinimum a good starting point:

FindMinimum[Abs[GammaEq[2*π*ω, rules]], {ω, 6}]

{0.62902, {ω -> 6.39389}}


As for the code, since this is a purely numerical function, you can speed it up tremendously by applying your rules ASAP; e.g.:

 MC = ( {
{C1 + Cκt + CJ1 + CJ3, -CJ1, -CJ3},
{-CJ1, C2 + CJ1 + CJ2, -CJ2},
{-CJ3, -CJ2, C3 + CJ2 + CJ3}
} ) /. rules;
γ1 = 1/R1  iC[[1, 1]] /. rules;


etc. (no need for that FullSimplify now)

Just so you know, one of your rules : ω -> 2 π ν doesn't do anything, since ω already has a numeric value by the time you apply the rule.

• Very interesting, and helpful. Would you perhaps know what's going on for this to be needed? – user129412 Jun 2 '15 at 20:56
• NMinimize[{Abs[GammaEq[2*Pi*w, rules]], 6 < w < 8}, w, Method -> "NelderMead"] seems to give a better approximation – Dr. belisarius Jun 2 '15 at 21:01
• @george2079 Do you mean that for every expression that includes the numerical values, I should use the /. rules? I'm not entirely clear on what you meant by that, but the word tremendously definitely caught my attention. – user129412 Jun 2 '15 at 21:14
• The symbolic MC / FullSimplify was the big time waster.. but apply the rules to all the gamma's and omegas as well ( The plot renders in less than a second now, was over a minute ). The NumericQ issue is common to most functions that perform an "apparently" purely numeric task (NIntegrate, FindRoot, etc ). They initially do a symbolic evaluation, so in case where that makes no sense you force them to skip it essentially. – george2079 Jun 2 '15 at 21:23
• I see, yeah, the simplify was initially there to see if what I did made sense, suppose the evaluator doesn't care about that indeed. Thanks a lot for the help! – user129412 Jun 2 '15 at 21:28