# NMaxValue - function is not a real number

I'm trying to use NMaxValue to numerically find maximal values of the function F[z]. The problematic part of my code is as follows:

p = 2/3;

λ[t_] := Exp[-t];
H2[x_] := -x Log2[x] - (1 - x) Log2[1 - x];
hp[z_] := (1 + z)/4 (1 - λ[t]^2) (1 - p);
hm[z_] := (1 - z)/4 (1 - λ[t]^2) (1 - p);
Δp[z_] :=
1/4 (1 + λ[t]^2 + z*p (1 - λ[t]^2) + Sqrt[4 (λ[t]^2 +
z*p (1 - λ[t]^2)) + (1 - λ[t]^2)^2 (p + z)^2]);
Δm[z_] :=
1/4 (1 + λ[t]^2 + z*p (1 - λ[t]^2) + Sqrt[4 (λ[t]^2 + z*p (1 - λ[t]^2)) + (1 - λ[t]^2)^2 (p - z)^2]);

F[z_] := H2[(1 + z)/2] + H2[(1 + p + λ[t]^2 (1 - p))/2] - hp[z] Log2[hp[z]] -
hm[z] Log2[hm[z]] - Δp[z] Log2[Δp[z]] - Δm [z] Log2[Δm[z]];

t = 61/100;

CE = NMaximize[{F[z], -1 <= z <= 1}, z];


When calculating CE, Mathematica returns:

"NMaximize::nrnum: The function value -2.36092-0.101127 I is not a real number at {z} = {-0.868794}.".

How do I force maximization over real F[z] only?

• NMaximize[Re@F[z], -1 <= z <= 1, z] Feb 18, 2023 at 9:37
• Thanks, but this seems to maximize over the real part of the function, not over real functions... Feb 18, 2023 at 11:55
• When all of the variables are real and all of the intermediate results are real, F[z] just equal to Re@F[z]. Feb 19, 2023 at 0:12

If you plot your function F[z]

Plot[F[z], {z, -0.7, 1}]


you can see that the max is somewhere near -0.25. Since your function becomes complex valued at around -0.6, you need to restrict the search. Hence

NMaximize[{F[z], -0.6 < z < 1}, z]

{2.91233, {z -> -0.225441}}


gives the max value.

• Thank you! I've tried NMaximize, too, but it behaved just like NMaxValue. It's so strange that limiting the range of the variable fixes the problem! Feb 20, 2023 at 9:46
• The solver is expecting to see real numbers since it doesn't mean anything to try and "maximize" a complex number. Another way to fix the problem is to use NMaximize[{Abs[F[z]], -1 <= z <= 1}, z]. This returns the same result. Feb 20, 2023 at 18:04

t = 61/100;


For your interval of interest (-1 <= z <= 1), the function F[z] is real when

fd = FunctionDomain[{F[z], -1 <= z <= 1}, z] // Simplify

(* 3 E^(61/50) (2 + z) >= 2 + 2 E^(61/100) Sqrt[-13 + 8 E^(61/50)] +
3 z && z < 1 *)


or approximately

fd // N // Simplify

(* -0.628735 <= z < 1. *)


The maximum is

CE = NMaximize[{F[z], fd}, z]

(* {2.91233, {z -> -0.225441}} *)

• Thank you! This helps a lot. I'll definitely implement FunctionDomain into my code. Feb 20, 2023 at 9:48