1function sample = me_sample(ME, n, xs)
2% SAMPLE = ME_SAMPLE(ME, N, XS) - Generate random samples from ME distribution
4% Generate samples from a Matrix Exponential (ME) distribution
using
5% inverse CDF interpolation method.
8% ME: ME distribution as either:
10% - Process cell array {D0, D1}
11% N: Number of samples to generate (
default: 1)
12% XS: Optional pre-computed grid for CDF evaluation
13% If not provided, auto-generates grid based on mean and variance
16% SAMPLE: Column vector of N samples from the ME distribution
19% Uses inverse CDF interpolation with binary search:
20% 1. Compute CDF on a fine grid (default: 1000 points)
21% 2. For each sample, generate u ~ Uniform(0,1)
22% 3. Use interpolation to find x such that CDF(x) = u
25% me = ME([0.3, 0.7], [-2, 1; 0.5, -1.5]);
26% samples = me_sample(me, 10000);
28% % Or use process representation directly
29% ME_proc = {[-2, 1; 0.5, -1.5], [0.4, 0.6; 0.3, 0.7]};
30% samples = me_sample(ME_proc, 10000);
32% Copyright (c) 2012-2026, Imperial College London
35% Handle input arguments
40% Extract process representation
42 ME_proc = ME.getProcess();
46 error('ME must be either an ME
object or a cell array {D0, D1}
');
49% Auto-generate grid if not provided
50if nargin < 3 || isempty(xs)
51 mean_val = map_mean(ME_proc);
52 var_val = map_var(ME_proc);
53 std_val = sqrt(var_val);
55 % Create grid from 0 to mean + 10*sigma with 1000 points
56 xs = linspace(0, mean_val + 10*std_val, 1000);
59% Compute CDF at grid points
60Fxs = map_cdf(ME_proc, xs);
62% Ensure CDF is strictly increasing for interpolation
63% (handle numerical precision issues)
66 Fxs(i) = Fxs(i-1) + eps;
70% Generate samples via inverse CDF interpolation
79 % Extrapolate beyond grid if needed
80 % Use exponential tail approximation
81 sample(i) = xs(end) + log(1 / (1 - u + eps));
83 % Linear interpolation between grid points
84 sample(i) = interp1(Fxs, xs, u, 'linear
');