Saving the truncated distribution's properties would allow for this calculation to proceed much more quickly.
However, asking Mathematica to directly calculate the standard deviation of the truncated distribution in the general case takes a distressingly long time itself. Doing some of this by hand results in a much faster solution, so:
Let us grab the PDF of the interior distribution and manually truncate it ourselves:
fpdf[mu_, sig_, x_] = PDF[NormalDistribution[mu, sig], x];
And then calculate three related integrals where the limits are based on the truncation:
ex0 = Integrate[fpdf[mu, sig, x], {x, 35/100, 70/100}];
ex1 = Integrate[x fpdf[mu, sig, x], {x, 35/100, 70/100}]/ex0;
ex2 = Integrate[x^2 fpdf[mu, sig, x], {x, 35/100, 70/100}]/ex0;
ex0
captures the amount of normal distribution within the truncated region, ex1
captures the expected value of a variable sampled from the normal distribution, and ex2
capture $E(X^2)$. These three integrals take about 6 seconds total to evaluate on my machine.
From an answer over on math.SE, we can see that with this information we can calculate the mean and variance directly:
distMean[mu_, sig_] = ex1;
distVariance[mu_, sig_] = ex2 - ex1^2;
And relatedly, the standard deviation:
distStdDev[mu_, sig_] = Sqrt[ex2 - ex1^2];
If we plug in these distMean
and distStdDev
functions into the original FindRoot
, we find that the solution is quite fast:
FindRoot[{distMean[mu, sig] == 0.4582,
distStdDev[mu, sig] == Sqrt[0.0052]}, {{mu, 0.5}, {sig, 0.1}}] // AbsoluteTiming
{0.002852, {mu -> 0.412198, sig -> 0.102817}}
This approach can potentially be generalized to other types of distributions, but it is somewhat dependent on being able to get a nice closed form for the 3 integrals involved for maximum speedup.