Fitting PDFs with constraints

Occasionally, data are published in the limiting form of a few values and corresponding cumulative percentiles. For example, grain size data are frequently published in terms of the 10th, 50th, and 90th cumulative percentiles. However, sometimes it’s nice to have an approximation of what a model distribution would look like if constrained to fit these points.┬áBased on the solution given by Matt Tearle, here’s a short function below that gives an approximation of the mean and standard deviation of a log-normal distribution given at least two value-percentile pairs:

function m = prc2dist(p,q,guess)
%fit a log normal distribution to given p (percentiles), q (value) pairs,
%and a guess vector where guess=[guessMean guessStd].
%Output: m is a vector with elements, m(1) = mean,
%                                 and m(2) = standard deviation,
%                                 of the fitted distribution.
% see: help logninv for more information.
% Example:
% p = [0.1, 0.8]; %percentiles (cumulative probability)
% q = [1, 100]; %values
% guess = [1, 1]; %initial guess of mean and stdev, respectively.
% m = prc2dist(p,q,guess) % returns mean and standard dev of log-normal distribution

%regularize input
p = p(:);
q = q(:);
guess = guess(:)';
%validate input
if length(p) ~= length(q)
      fprintf('value and percentile vectors must be the same length.\n');
      m = nan(1,2);
elseif length(p) < 2
     fprintf('value and percentile vectors must be > 2 elements in length.\n');
     m = nan(1,2);
     g = @(p,b,q) logninv(p,b(1),b(2))-q;%distance between guess and input
     f = @(b) norm(g(p,b,q));%calculate l2 norm of distance vector
     m = fminsearch(f,guess);

download a zipped archive containing prc2dist.m