# Force symbolic usage in PDF or distribution

I want to create a custom distribution based on a SmoothKernelDistribution or KernelMixtureDistribution as so:

data1 = RandomVariate[NormalDistribution[5, 1.2], 1000];
skd1 = KernelMixtureDistribution[data1];
custom[a_] := ProbabilityDistribution[PDF[skd1, x+a], {x, 0, 10}, Assumptions -> a >= 0 && a < 2.5];


Then I want to fit the a parameter as so:

data3 = RandomVariate[NormalDistribution[6, 1.2], 1000];
FindDistributionParameters[data3, custom[a], ParameterEstimator -> {"MaximumLikelihood", Method -> {"FindMaximum"}}]


However, this will just grind away for hours with no result. I can do something like this in about 1 second:

custom[a_] := ProbabilityDistribution[a PDF[skd1, x], {x, 0, 10}, Assumptions -> a >= 0 && a < 2.5];


So this tells me that putting x+a in for the argument to the PDF is what's causing the bottleneck. Is there a better/faster way to force a parameter in this place?

• I may be thinking about this wrong but it seems the result for your example should be approx a=-1 i.e. outside your assumptions. – george2079 Sep 26 '17 at 20:44
• I thought to not use FindDistributionParameters and instead do something like NMaximize[LogLikelihood[custom[a], data3], a] This is not immediately working or is slow but something to think about. – george2079 Sep 26 '17 at 20:51
• george2079: Yep, you're right, I was getting confused about which way I was going with the distribution. It's grinding away right now with the parameter selection relaxed to -1.5 < a < 1.5 Also, I'm trying NMaximize now on another kernel, so we'll see what comes out... Thank you for the options to try. – Matt Stein Sep 26 '17 at 21:45

If you would describe the motivation for proceeding in the manner you've described, I might be able to help more (as what you describe is doable but not usual).

Here are two estimators: Method of moments (the quickest) and maximum likelihood for a shift from the distribution generated from a random sample in the form of a KernelMixtureDistribution:

(* Generate a distribution *)
data1 = RandomVariate[NormalDistribution[5, 1.2], 1000];
skd1 = KernelMixtureDistribution[data1];

(* Mean of distribution *)
μ = Expectation[x, x \[Distributed] skd1]
(* 4.929814990602076 *)

(* Take a random sample from that generated distribution but shifted by 1 *)
data3 = 1 + RandomVariate[skd1, 100];

(* Estimate a by method of moments *)
mom = Mean[data3] - μ
(* 1.0098336468866025 *)

(* Estimate a by maximum likelihood *)
logL = LogLikelihood[skd1, data3 - a];
mle = a /. FindMaximum[logL, {{a, mom}}, AccuracyGoal -> 20][[2]]
(* 1.0009715243841062 *)

Show[Plot[logL, {a, -5, 5}],
ListPlot[{{mle, logL /. a -> mle}}, PlotStyle -> Red]]


• Here's some additional info: The distribution I need to actually work with doesn't have a nice analytical formula. It's like an exponential decay, then goes flat, then cuts off quickly. It's like a slide that goes down, stays flat, then plummets to the X-axis. I hope that's clear... Anyway, with such a weird distribution, I'm not sure that finding a mean is useful (is it?). I have a set of experimental data, and I have a monte carlo generated set of data, but the MC data is shifted. I want to know the best shift parameter to make the simulation match the data. – Matt Stein Sep 27 '17 at 0:39
• No part of my answer assumes an analytical model (nice or not so nice). A distribution is created from data1. It is not created directly from a normal distribution. The estimate of the shift is created from data3 and the kernel distribution. Again, no nice distribution is assumed. If the only difference is a shift in location, then one doesn't need to know the analytical form to estimate the shift. Maybe you should be asking this at CrossValidated StackExchange? – JimB Sep 27 '17 at 1:55
• Ok I've been playing with your suggestion and it works perfectly! I especially love the visualization of the likelihood, though it takes longer than the MLE to plot... Still, very nice to have! Thank you again! – Matt Stein Sep 27 '17 at 13:09