13
$\begingroup$

Why do I get a gap in the plot below and how can I fix it? (If you are interested in it, you can see a new related question: How to plot an implicit value funtion, which is also a little chanlenging)

Code:

Plot[InverseFunction[
   1 - 0.6*CDF[NormalDistribution[1, 0.3], #] - 
     0.4*CDF[NormalDistribution[3, 0.3], #] &][x], {x, 0, 1}, 
 PlotRange -> All, Exclusions -> None]

Result

$\endgroup$
  • $\begingroup$ Welcome to Mathematica.SE! I suggest that: 1) You take the introductory Tour now! 2) When you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge. Also, please remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign! 3) As you receive help, try to give it too, by answering questions in your area of expertise. $\endgroup$ – bbgodfrey Jan 2 '15 at 6:16
  • 1
    $\begingroup$ Based on algohi's and a.g.'s answers I have tagged this with the bugs tag. $\endgroup$ – Sjoerd C. de Vries Jan 2 '15 at 10:15
  • $\begingroup$ @SjoerdC.deVries,Hi Sjoerd, do you know how to report this bug to Wolfram? Thanks a lot. $\endgroup$ – ben Jan 2 '15 at 17:24
  • 1
    $\begingroup$ @ben : from Mathematica menus : Help -- Give feedback $\endgroup$ – A.G. Jan 2 '15 at 18:00
  • $\begingroup$ Support@wolfram.com should work. $\endgroup$ – Sjoerd C. de Vries Jan 3 '15 at 0:39
9
$\begingroup$

The function you wish to plot happens to be the InverseSurvivalFunction of a MixtureDistribution with component distributions NormalDistribution[1, 0.3] and NormalDistribution[3, 0.3], and weights .6 and .4, respectively.

Using the built-in functions MixtureDistribution and InverseSurvivalFunction we get the desired result without an issue:

dist = MixtureDistribution[{6, 4}, {NormalDistribution[1, 0.3], NormalDistribution[3, 0.3]}]; 
Plot[InverseSurvivalFunction[dist, x], {x, 0, 1}]

enter image description here

You can also use InverseCDF to get the same output:

Plot[InverseCDF[dist, 1 - x], {x, 0, 1}]
(* same picture *)

Update: Addressing the question in the comments:

I do need to characterize D[x*InverseSurvivalFunction[dist, x], x]

Using the product rule and the inverse function theorem, you can define

derivative[x_] := (InverseSurvivalFunction[dist, y] +
     (x/(D[1 - CDF[dist, y], y] /. y -> InverseSurvivalFunction[dist, y]))) /. y -> x;

Column[Plot[#, {x, 0, 1}, ImageSize -> 400] & /@
  {x InverseSurvivalFunction[dist, x], Evaluate@derivative[x]}]

enter image description here

$\endgroup$
  • $\begingroup$ It's very helpful. Btw, can we do operations on InverseSurvialFunction, like D[x*InverseSurvivalFunction[dist, x], x]? It seems it doesn't work. Thanks! $\endgroup$ – ben Jan 2 '15 at 22:24
  • $\begingroup$ @ben, for the mixture distribution dist, D[x*InverseSurvivalFunction[dist, x], x] and D[x*InverseCDF[dist, 1-x], x] do not work; but they do work for "simpler" distributions: for example, D[InverseCDF[NormalDistribution[0, 1], x], x] and D[InverseSurvivalFunction[NormalDistribution[0, 1], x], x]. $\endgroup$ – kglr Jan 2 '15 at 23:07
  • $\begingroup$ I do need to characterize D[x*InverseSurvivalFunction[dist, x], x]. Do you have any suggestions which can remove the gap and also keep doing the derivation? Thanks. $\endgroup$ – ben Jan 2 '15 at 23:14
  • $\begingroup$ @ben, since we do get a closed form solution for D[1 - CDF[dist, x], x], maybe you can use Inverse Function Theorem? For example, (1/(D[1 - CDF[dist, x], x] /. x -> InverseSurvivalFunction[dist, x])) /. x -> .5 gives -2.00119. $\endgroup$ – kglr Jan 2 '15 at 23:50
  • $\begingroup$ @ben, please see the update... $\endgroup$ – kglr Jan 3 '15 at 0:32
7
$\begingroup$

You have complex numbers as a result in these ranges.

Check this:

Table[{i,
  InverseFunction[
    1 - 0.6*CDF[NormalDistribution[1, 0.3], #] -
      0.4*CDF[NormalDistribution[3, 0.3], #] &][i]}, {i, 0, 1, 0.01}]

The problem seems to be generated internally because of the real number in the function and also because of the fact that the plot uses a real number when sampling points for the plot. To see this behavior, look at these evolutions:

N[InverseFunction[
   1 - 6/10*CDF[NormalDistribution[1, 3/10], #] -
     4/10*CDF[NormalDistribution[3, 3/10], #] &][3/10]]

(*2.79765*)

InverseFunction[
  1 - 6/10*CDF[NormalDistribution[1, 3/10], #] -
    4/10*CDF[NormalDistribution[3, 3/10], #] &][0.3]

(*1.47655 + 0.475155 I*)
$\endgroup$
  • $\begingroup$ Yes, you are right. How to fix it? Thanks. $\endgroup$ – ben Jan 2 '15 at 6:33
  • $\begingroup$ ... complex roots are surprising, there are clearly real inverses. Could it be an issue with InverseFunction? $\endgroup$ – A.G. Jan 2 '15 at 7:27
  • $\begingroup$ I have no idea. Maybe you are right. I will report it to Wolfram. Thanks! $\endgroup$ – ben Jan 2 '15 at 17:28
7
$\begingroup$

We get a little insight to the "bug" by writing the CDF in terms of Erfc:

 InverseFunction[
       1 - 0.6*CDF[NormalDistribution[1, 0.3], #] - 
           0.4*CDF[NormalDistribution[3, 0.3], #] &][.3]
 InverseFunction[
       1 - 0.6 1/2 Erfc[2.3570226039551585` (1 - #)] - 
           0.4 1/2 Erfc[2.3570226039551585` (3 - #)] &][.3]

1.47655 + 0.475155 I

1.47655 + 0.475155 I

(1 - 0.6*1/2 Erfc[2.3570226039551585` (1 - #)] - 
   0.4*1/2 Erfc[2.3570226039551585` (3 - #)]) &@%

0.3 - 4.85056*10^-16 I

we see that while CDF can not take an imaginary argument, Erfc can and the erroneous result is indeed a complex valued inverse of the function.

Edit -- a fix

it turns out we can use ConditionalExpression to force selection of a real inverse:

 Plot[ InverseFunction[
         ConditionalExpression[ 
           1 - 0.6*CDF[NormalDistribution[1, 0.3], #] - 
               0.4*CDF[NormalDistribution[3, 0.3], #], Element[#, Reals] ] &] @
              x , {x, 0, 1}]

enter image description here

$\endgroup$
  • $\begingroup$ Thanks a lot. Btw, can we do operations it, like Plot[D[x*InverseFunction[ ConditionalExpression[ 1 - 0.6*CDF[NormalDistribution[1, 0.3], #] - 0.4*CDF[NormalDistribution[3, 0.3], #], Element[#, Reals]] &]@ x, x], {x, 0, 1}] It seems it doesn't work. Thanks! $\endgroup$ – ben Jan 2 '15 at 22:42
6
$\begingroup$
f[x_] = 1 -
   0.6*CDF[NormalDistribution[1, 0.3], x] -
   0.4*CDF[NormalDistribution[3, 0.3], x];

ParametricPlot[{f[x], x}, {x, -1, 3},
 AspectRatio -> 1/GoldenRatio]

enter image description here

$\endgroup$
  • $\begingroup$ Hi Bob, Thanks for your help. I will frequently use this function in the later analysis and same problem occurs in more complex functions. $\endgroup$ – ben Jan 2 '15 at 17:26
5
$\begingroup$

To start with, this should not be a problem for Mathematica. The non-inverse function is reasonably well-behaved:

f[u_] := 1-0.6 CDF[NormalDistribution[1, 0.3], u] - 0.4 CDF[NormalDistribution[3, 0.3], u];
Plot[f[u], {u, -1, 5}]

Mathematica graphics

(and one can verify, plotting or otherwise, that f' remains $<0$ so that f is 1-to-1). All I can suggest is to increase PlotPoints:

g = InverseFunction[f];
Plot[g[x], {x, 0, 1}, PlotRange -> {0, 4}, PlotPoints -> 30000]

nearly fills the gap around .3 but does nothing below .2, and takes over 400 sec here :(.

Mathematica graphics

You may want to report it to Wolfram.

$\endgroup$
  • $\begingroup$ You could try increasing MaxRecursion instead of this huge number of points, might help a bit. $\endgroup$ – Sjoerd C. de Vries Jan 2 '15 at 10:12
  • $\begingroup$ LOL so many plot points. $\endgroup$ – DumpsterDoofus Jan 2 '15 at 15:01
  • $\begingroup$ @SjoerdC.deVries The plot starts getting a bit better at 10000 points, there is a definite improvement between 20k and 30k. MaxRecursion->5 did not help. $\endgroup$ – A.G. Jan 2 '15 at 17:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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