2

I have a behavior with 3D plots I really don't understand and I would like to correct it.

I have a 2D function to plot, here is its graph with Plot3D :

enter image description here

We can see that on the top boundary of $\Delta I$ ($\Delta I=Log[2]-SiQ[Theta]-0.001$) I have some weird negative picks. These picks shouldn't exist, indeed they don't exist on my orignal function.

To prove it, here is the 1D plot in function of $Theta$ on this boundary, we see that the function is positive (and constant) in this area. So here we see that the negative peaks on the boundary are not due do the function I plot in itself, because when I plot this same function in 1D graph on this boundary, I don't have those negative peaks

enter image description here

What is my Plot3D doing ? Is it just an artefact of visualisation ? How to get rid of this ?

Even more weird : I see that my peaks in this specific example are negative (and I know that my function is positive). So I can modify my plot3D to only display positive values. But it still shows me some non asked negative values :

enter image description here

I want to get rid of these artefact peaks in a general way, I don't want to use the fact I know my function is positive to do it

Also, I took a look at : Artefacts in 3d plots but I don't think it helps me because in my case I don't have the problem on a 1D graph. E

My code (I tried to reduce it at the maximum, the example is slightly different from the one I had before my edit) :

H2[x_] := If[x != 0, If[x != 1, (-x)*Log[x] - (1 - x)*Log[1 - x], 0], 0]



InvH2BrancheDroite[x_] := 1 - InverseFunction[H2][x]; 

TableauValeursReciproque = Union[Table[{x, InvH2BrancheDroite[x]}, {x, 0.00001, Log[2], 0.005}], Table[{x, InvH2BrancheDroite[x]}, {x, Log[2] - 0.01, Log[2], 0.0001}]]; 

InvH2BrancheDroitePol[y_] = Interpolation[TableauValeursReciproque, Method -> "Spline"][y]; 

SiQ[Theta_] := H2[Cos[Theta/2]^2]; 

WextMaxNonDegenBruitQ[Theta_, \[CapitalDelta]I_] := 2*InvH2BrancheDroitePol[\[CapitalDelta]I + SiQ[Theta]] - 1; 

Compteur = 0; 

NbPlotPoints = 100; 


Monitor[Plot3D[{WextMaxNonDegenBruitQ[Theta, \[CapitalDelta]I], 0}, {Theta, 0, Pi}, {\[CapitalDelta]I, -Log[2], Log[2]}, AxesLabel -> {\[CapitalTheta], \[CapitalDelta]I, WextMaxNonDegenBruitQ}, TicksStyle -> Large, 
   BaseStyle -> {FontSize -> 18}, RegionFunction -> Function[{Theta, \[CapitalDelta]I}, -SiQ[Theta] + 0.001 <= \[CapitalDelta]I <= Log[2] - SiQ[Theta] - 0.001], 
   ScalingFunctions -> {"Reverse", None, None}, PlotPoints -> NbPlotPoints, BoundaryStyle -> None, MaxRecursion -> 0, EvaluationMonitor :> (Compteur = Compteur + 1)], 
  ProgressIndicator[Compteur, {0, (2*NbPlotPoints)^2}]]

Plot[WextMaxNonDegenBruitQ[Theta, Log[2] - SiQ[Theta] - 0.001], {Theta, 0, Pi}]

Compteur = 0;

Monitor[Plot3D[{WextMaxNonDegenBruitQ[Theta, \[CapitalDelta]I], 0}, {Theta, 0, Pi}, {\[CapitalDelta]I, -Log[2], Log[2]}, AxesLabel -> {\[CapitalTheta], \[CapitalDelta]I, WextMaxNonDegenBruitQ}, TicksStyle -> Large, 
   BaseStyle -> {FontSize -> 18}, RegionFunction -> Function[{Theta, \[CapitalDelta]I, z}, -SiQ[Theta] + 0.001 <= \[CapitalDelta]I <= Log[2] - SiQ[Theta] - 0.001 && z >= 0], 
   ScalingFunctions -> {"Reverse", None, None}, PlotPoints -> NbPlotPoints, BoundaryStyle -> None, MaxRecursion -> 0, EvaluationMonitor :> (Compteur = Compteur + 1)], 
  ProgressIndicator[Compteur, {0, (2*NbPlotPoints)^2}]]

Some comments on the code : in the beginning I try to find the reciprocal function on the right branch of the binary shannon entropy. This is the main function used for my plot that gives weird results.

Again I insist on the fact that these weird peaks are not due to numerical bad accuracy in the approximation of my inverse function to the shannon entropy because on my 1D plot I don't have the presence of the peaks. So, it is the Plot3D that is somehow reponsible for it. But I don't know why...

murray
  • 11,888
  • 2
  • 26
  • 50
StarBucK
  • 2,164
  • 1
  • 10
  • 33
  • I guess the function WextMaxNonDegenBruitQ is the issue here. Is it defined beyond the boundary of the PlotRegion? Is it continuous there? Or does it have jumps? – Henrik Schumacher Jun 07 '18 at 14:19
  • @HenrikSchumacher no it is well defined on this boundary. You can see it with the 1D plot that represent the value of this function on the boundary where I have my jumps on my 3D plots. This is why I find the behavior strange – StarBucK Jun 07 '18 at 14:21
  • @HenrikSchumacher and the second "weird" thing is that even if I force my 3Dplot to plot on a $z>0$ region, it will show me some points with $z<0$ (see the edit) – StarBucK Jun 07 '18 at 14:21
  • 2
    The point that I tried to make is that nobody can say anything without precise definition of the functions that involved there. And please, post them as copyable code. – Henrik Schumacher Jun 07 '18 at 14:24
  • This problem looks indeed quite interesting and I'm certain that Henrik, myself or others can help, but we really need code for this. – halirutan Jun 07 '18 at 15:37
  • @HenrikSchumacher I edited with minimal code included – StarBucK Jun 07 '18 at 16:32
  • @halirutan I edited with minimal code included – StarBucK Jun 07 '18 at 16:32
  • I recommend that you use MaxRecursion -> 5 or higher depending on how clean an image that you want. It will however be slower. You might want to also break up the axis label, e.g., "WextMax\nNonDegen\nBruitQ" – Bob Hanlon Jun 07 '18 at 17:25
  • @BobHanlon yes my calculation is still quite long. I would prefer to avoid using it. – StarBucK Jun 07 '18 at 17:27

1 Answers1

3
Plot3D[{WextMaxNonDegenBruitQ[Theta, ΔI], 0},
 {Theta, 0, Pi}, {ΔI, -SiQ[Theta] + 0.001, Log[2] - SiQ[Theta] - 0.001}, 
 ScalingFunctions -> {"Reverse", None, None}, 
 PlotPoints -> NbPlotPoints, BoundaryStyle -> None, MaxRecursion -> 1,
  EvaluationMonitor :> (Compteur = Compteur + 1)]

enter image description here

You can close the gap by using the iterator {ΔI, -SiQ[Theta], Log[2] - SiQ[Theta]}. With the standard number of plot points and no recursion, it's pretty fast:

Plot3D[{WextMaxNonDegenBruitQ[Theta, ΔI], 0},
 {Theta, 0, Pi}, {ΔI, -SiQ[Theta], Log[2] - SiQ[Theta]}, 
  ScalingFunctions -> {"Reverse", None, None}, BoundaryStyle -> None, 
  MaxRecursion -> 0] // AbsoluteTiming

enter image description here

(The problem with RegionFunction, as inferred from my experience, is that it approximates the region. The points used for evaluation can lie outside the desired domain. With MaxRecursion -> 0, the error can be significant.)

Cheap, kludgy fix:

plot /. {x_Real, y_Real, z_Real /; z < 0} :> {x, y, 0.}

enter image description here

Michael E2
  • 235,386
  • 17
  • 334
  • 747
  • How many PlotPoints did you use here ? Because as soon as I put a maxRecursion non 0 it takes a very long time – StarBucK Jun 07 '18 at 19:16
  • @StarBucK I used NbPlotPoints. MaxRecursion -> 0 takes 3+ sec, and at 1 it takes 6+ sec. (I meant to post the 0 code, but going back and forth, I made a mistake.) – Michael E2 Jun 07 '18 at 19:21
  • What I mean is that in the code you posted you didn't showed what is the value for NbPlotPoints you used :) – StarBucK Jun 07 '18 at 19:22
  • 2
    @StarBucK I didn't change it. (I used your code, or 100.) – Michael E2 Jun 07 '18 at 19:24
  • You solved my problem but I have few extra questions : So here, you think that it is probably because of an interpolation with a point further than the boundary that causes me these weird behaviors. It is possible because indeed outside of my boundary my function has probably a non physical diverging behavior. But why when I forced $z>0$ it still showed me negative peaks ? Do you have an idea ? – StarBucK Jun 08 '18 at 12:18
  • @StarBucK You can explore the effect of extrapolation with things like Plot[InvH2BrancheDroitePol[y], {y, 0, Log[2](*+10^-2*)}]. As for whether you "forced $z>0$," I'd say that the effect of the forcing depends on how the inequality is translated into code/computation. Clear (I would say clearly), it's done via an approximate numerical algorithm, maybe linear interpolation.... – Michael E2 Jun 08 '18 at 14:05
  • ...You can see the same effect here: Plot[InvH2BrancheDroitePol[1-y],{y,0,1},RegionFunction->Function[{y,z},z>0.5]]. I had to reverse the direction of the graph to find an estimate outside the domain implied by z > 0.5. In your case, it's more complicated because of the 2D region. Along the boundary of the region, a point in the domain is determined where approximately $z = 0$. Then the function value at the point is used. The new value is not checked to see if $z > 0$. – Michael E2 Jun 08 '18 at 14:05