1
$\begingroup$

The following code do what I needed, but it takes too long.

 f[a_, b_, c_, p_] = 
  ProbabilityDistribution[(
   a b x^(b - 1) (1 - p) (1 + c a x^b)^(-(1/c) - 1))/(1 - 
     p (1 + c a x^b)^(-(1/c)))^2, {x, 0, ∞}, 
   Assumptions -> 0 < p < 1 && a > 0 && b > 0 && c > 0];
data = RandomVariate[Evaluate@f[1.1, 2, 3, 0.5], 25];
pars = FindDistributionParameters[data, f[a, b, c, p]]
ll[a_, b_, c_, p_] = LogLikelihood[f[a, b, c, p], data] /. pars
h = DistributionFitTest[data, f[a, b, c, p], "HypothesisTestData"] /. pars;
h["TestDataTable", All]
Plot[{CDF[f[a, b, c, p], x] /. pars, 
  CDF[EmpiricalDistribution[data], x]}, {x, Min[data], Max[data]}, 
 PlotStyle -> {Dashed, DotDashed}, 
 PlotLegends -> {"Fitted", "Empirical"}, Exclusions -> None, 
 AxesOrigin -> {0, 0}]

Kindly help me to reduce the time of the code.

$\endgroup$
7
  • 4
    $\begingroup$ Have you timed segments to see where it is slow? Also, how long is "too long". Try AbsoluteTiming, the first step in speeding up any code is to identify where it is slowest. $\endgroup$ Feb 10, 2016 at 10:06
  • $\begingroup$ At DistributionFitTest and then at Plot. "too long" time is in hours I am using version 10 on i7 fourth edition $\endgroup$
    – SAAN
    Feb 10, 2016 at 10:14
  • 1
    $\begingroup$ You probably should not run EmpiricalDistribution[data] inside the Plot, because it has to be evaluated for every x again. Also, you could try to reduce the number of computations in Plot via the Mesh option. Further, you should reduce your example to a shorter computation time and then try to optimize it. $\endgroup$
    – Berg
    Feb 10, 2016 at 10:45
  • 1
    $\begingroup$ What do you want to do with ll[a_, b_, c_, p_] = LogLikelihood[f[a, b, c, p], data] /. pars ? It doesn't make much sense to me. $\endgroup$
    – rhermans
    Feb 10, 2016 at 11:11
  • $\begingroup$ I played around with your code a bit and sometimes I get an error that the algorithm FindDistributionParameters does not converge. Is this to be expected? Also those parameters vary wildly. Is this intended? $\endgroup$
    – Berg
    Feb 10, 2016 at 11:12

1 Answer 1

6
$\begingroup$

OK, a partial answer without considering h["TestDataTable",All]: In the plot it is much faster to move the pars inside CDF. (Computing CDF numerically vs. symbolically, I guess.)

AbsoluteTiming[d1 = CDF[f[a, b, c, p] /. pars, x];]
(* <1s *)
AbsoluteTiming[d2 = CDF[f[a, b, c, p], x] /. pars;]
(* 14s *)

And it is faster to first compute the functions that are to be plotted and then hand those to Plot.

AbsoluteTiming[Plot[d1,{x,0,10}]]
(* 0 *)
AbsoluteTiming[Plot[CDF[f[a,b,c,p]/.pars,x],{x,0,10}]]
(* 2.3 s *)

Combine both to get the plot in about one second:

fct = {CDF[f[a, b, c, p] /. pars, x], CDF[EmpiricalDistribution[data], x]}
Plot[fct, {x, Min[data], Max[data]}, 
          PlotStyle -> {Dashed, DotDashed},
          PlotLegends -> {"Fitted", "Empirical"},
          Exclusions -> None, 
          AxesOrigin -> {0, 0}]
$\endgroup$

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.