1
$\begingroup$

I have the following code:

SampleDistanceHist[one_, two_] := Module[{},
  dst1 = HistogramDistribution[one];
  dst2 = HistogramDistribution[two];
  Plus @@ Table[(CDF[dst1, x] - CDF[dst2, x])^2, {x, -1,1, 0.001}]}]]

this is distance function(sum of squared difference of 2 CDFs) to solve the minimization problem.(Approximation of probability distribution)

but this is slow in operation. Is there any way to speed up this code?

$\endgroup$
5
  • $\begingroup$ Shouldn't that be a dist2 in the second CDF? $\endgroup$
    – Edmund
    Nov 26 '18 at 23:26
  • $\begingroup$ you're right. thanks! $\endgroup$
    – Xminer
    Nov 26 '18 at 23:27
  • $\begingroup$ Last line is full of syntax errors. $\endgroup$
    – Edmund
    Nov 26 '18 at 23:33
  • $\begingroup$ thank you for pointing out. but tell me what is wrong. the following code works correctly (of course,my code is not perfect.) f1 = Sin[x]; f2 = Cos[x]; Plus @@ Table[(f1 - f2)^2, {x, -1, 1, 0.0001}] $\endgroup$
    – Xminer
    Nov 26 '18 at 23:36
  • 1
    $\begingroup$ Wouldn't integration work? For example, NIntegrate[ (CDF[dist1, x] - CDF[dist2, x])^2, {x, -1, +1}] is faster than your Table. Of course, one has to work out the limits correctly or go from -infinity to +infinity. There are lots of options to "tweak" the speed of integration. $\endgroup$
    – gwr
    Nov 27 '18 at 19:09
3
$\begingroup$
ClearAll[sampleDistanceHist]
sampleDistanceHist[one_, two_] := Module[{table = Range[-1, 1, .001],
   dst1 = HistogramDistribution[one], dst2 = HistogramDistribution[two], b, p, f1, f2},
  b = Join[{-1 + Min@#}, #, {1 + Max@#}] & /@ (#["BinDelimiters"] & /@ {dst1, dst2});
  p = Normalize[Accumulate[Join[{0, 0}, #["PDFValues"], {0}]], Max] & /@ {dst1, dst2};
  {f1, f2} = Interpolation[Transpose[{b[[#]], p[[#]]}], InterpolationOrder -> 1]&/@{1, 2};
  Total[Subtract[f1@table, f2@table]^2]]

Using the example data, one and two from Edmund's answer:

SeedRandom[1]
one = RandomVariate[NormalDistribution[], 200];
two = RandomVariate[ChiSquareDistribution[5], 200];

SampleDistanceHist[one, two] // RepeatedTiming

{0.20, 471.531}

sampleDistanceHist[one, two] // RepeatedTiming

{0.011, 471.531}

$\endgroup$
2
$\begingroup$

You may use TransformedDistribution.

With

one = RandomVariate[NormalDistribution[], 200];
two = RandomVariate[ChiSquareDistribution[5], 200];

then

t = TransformedDistribution[(x - y)^2, 
   Thread[{x, y} \[Distributed] HistogramDistribution /@ {one, two}]];

and

Histogram[RandomVariate[t, 500]]

Mathematica graphics

Hope this helps.

$\endgroup$
1
  • 1
    $\begingroup$ Thank you! but in your code,what we do is something like Method of Moments not measuring the distance of Distribution itself? $\endgroup$
    – Xminer
    Nov 27 '18 at 0:11

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.