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$
  • $\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
    $\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.