# How to improve speed of the following code

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, \[Infinity]},
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.

=================

3

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.
– Quantum_Oli
Feb 10 at 10:06

At DistributionFitTest and then at Plot. “too long” time is in hours I am using version 10 on i7 fourth edition
– SAAN
Feb 10 at 10:14

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.
– Berg
Feb 10 at 10:45

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.
– rhermans
Feb 10 at 11:11

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?
– Berg
Feb 10 at 11:12

=================

1

=================

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}]