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$
5
  • $\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, 2015 at 6:16
  • 1
    $\begingroup$ Based on algohi's and a.g.'s answers I have tagged this with the bugs tag. $\endgroup$ Jan 2, 2015 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, 2015 at 17:24
  • 1
    $\begingroup$ @ben : from Mathematica menus : Help -- Give feedback $\endgroup$
    – A.G.
    Jan 2, 2015 at 18:00
  • $\begingroup$ [email protected] should work. $\endgroup$ Jan 3, 2015 at 0:39

5 Answers 5

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$
7
  • $\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, 2015 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, 2015 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, 2015 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, 2015 at 23:50
  • $\begingroup$ @ben, please see the update... $\endgroup$
    – kglr
    Jan 3, 2015 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$
3
  • $\begingroup$ Yes, you are right. How to fix it? Thanks. $\endgroup$
    – ben
    Jan 2, 2015 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, 2015 at 7:27
  • $\begingroup$ I have no idea. Maybe you are right. I will report it to Wolfram. Thanks! $\endgroup$
    – ben
    Jan 2, 2015 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$
1
  • $\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, 2015 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$
1
  • $\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, 2015 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$
3
  • $\begingroup$ You could try increasing MaxRecursion instead of this huge number of points, might help a bit. $\endgroup$ Jan 2, 2015 at 10:12
  • $\begingroup$ LOL so many plot points. $\endgroup$ Jan 2, 2015 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, 2015 at 17:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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