LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
Pareto.m
1classdef Pareto < ContinuousDistribution
2 % The Pareto statistical distribution
3 %
4 % Copyright (c) 2012-2026, Imperial College London
5 % All rights reserved.
6
7 methods
8 function self = Pareto(shape, scale)
9 % SELF = PARETO(SHAPE, SCALE)
10
11 % Constructs a Pareto distribution with given shape and scale
12 % parameters
13 self@ContinuousDistribution('Pareto',2,[0,Inf]);
14 if shape < 2
15 line_error(mfilename,'shape parameter must be >= 2.0');
16 end
17 setParam(self, 1, 'alpha', shape);
18 setParam(self, 2, 'k', scale);
19 end
20
21 function ex = getMean(self)
22 % EX = GETMEAN()
23
24 % Get distribution mean
25 shape = self.getParam(1).paramValue;
26 scale = self.getParam(2).paramValue;
27 ex = shape * scale / (shape - 1);
28 end
29
30 function SCV = getSCV(self)
31 % SCV = GETSCV()
32
33 % Get distribution squared coefficient of variation (SCV = variance / mean^2)
34 shape = self.getParam(1).paramValue;
35 scale = self.getParam(2).paramValue;
36 VAR = scale^2 * shape / (shape - 1)^2 / (shape - 2);
37 ex = shape * scale / (shape - 1);
38 SCV = VAR / ex^2;
39 end
40
41 function X = sample(self, n)
42 % X = SAMPLE(N)
43
44 % Get n samples from the distribution
45 if nargin<2 %~exist('n','var'),
46 n = 1;
47 end
48 shape = self.getParam(1).paramValue;
49 scale = self.getParam(2).paramValue;
50 k = 1/shape;
51 sigma = scale * k;
52 X = gprnd(k, sigma, sigma/k, n, 1);
53 end
54
55 function Ft = evalCDF(self,t)
56 % FT = EVALCDF(SELF,T)
57
58 % Evaluate the cumulative distribution function at t
59 % AT T
60
61 shape = self.getParam(1).paramValue;
62 scale = self.getParam(2).paramValue;
63 k = 1/shape;
64 sigma = scale * k;
65 Ft = gpcdf(t, k, sigma, sigma/k);
66 end
67
68 function L = evalLST(self, s)
69 % L = EVALST(S)
70 % Evaluate the Laplace-Stieltjes transform of the distribution function at s
71 %
72 % A*(s) = E[e^{-sX}] = int_k^Inf e^{-sx} alpha k^alpha x^{-(alpha+1)} dx.
73 % Substituting x = k/u maps the infinite tail onto a unit interval and
74 % cancels the scale exactly:
75 %
76 % A*(s) = alpha * int_0^1 u^(alpha-1) exp(-s*k/u) du
77 %
78 % This is the same transform as the closed form of Nadarajah & Kotz,
79 % A*(s) = alpha*(s*k)^alpha*Gamma(-alpha, s*k) = alpha*E_{alpha+1}(s*k)
80 % (Queueing Syst (2006) 54:243-244, DOI 10.1007/s11134-006-0299-1),
81 % but in a form that stays accurate as s -> 0, where the incomplete-gamma
82 % product underflows to 0/Inf. Here s = 0 gives alpha*int_0^1 u^(alpha-1)
83 % du = 1 exactly, and the integrand is bounded and C^Inf on a FINITE
84 % interval for alpha >= 2 (the shape floor the constructor enforces).
85 %
86 % Accuracy: adaptive Gauss-Kronrod at RelTol 1e-12, i.e. ~1e-12 relative,
87 % verified against mpmath to 1e-15. The previous implementation was a
88 % 1000-point right-endpoint rectangle sum truncated at k*1000^(1/alpha);
89 % it lost the mass beyond the truncation point and biased the transform
90 % low by ~3.1% at alpha=2.0078 (it returned A*(0)=0.96914, not 1).
91
92 alpha = self.getParam(1).paramValue; % shape parameter
93 k = self.getParam(2).paramValue; % scale parameter
94
95 L = zeros(size(s));
96 for i = 1:numel(s)
97 si = s(i);
98 if si == 0
99 L(i) = 1; % A*(0) = 1 exactly; skip the quadrature
100 else
101 % u=0 is an essential zero of the integrand (exp(-s*k/u) and all
102 % its derivatives vanish there), so the guard only avoids 0/0.
103 % AbsTol is set at the underflow floor rather than a "small"
104 % value on purpose: A*(s) spans hundreds of decades (9.3e-220
105 % at alpha=50, k=0.5, s=1000), so any meaningful absolute floor
106 % lets the quadrature stop before doing real work and return a
107 % value with no correct digits.
108 g = @(u) (u > 0) .* u.^(alpha-1) .* exp(-si .* k ./ max(u, realmin));
109 L(i) = alpha * integral(g, 0, 1, 'RelTol', 1e-12, 'AbsTol', realmin);
110 end
111 end
112 end
113
114 function proc = getProcess(self)
115 % PROC = GETPROCESS()
116
117 % Get process representation with actual distribution parameters
118 % Returns {shape (alpha), scale (k)} for Pareto distribution
119 proc = {self.getParam(1).paramValue, self.getParam(2).paramValue};
120 end
121 end
122
123 methods (Static)
124 function pa = fitMeanAndSCV(MEAN, SCV)
125 % PA = FITMEANANDSCV(MEAN, SCV)
126
127 % Fit distribution with given mean and squared coefficient of variation (SCV=variance/mean^2)
128 % For Pareto distribution with shape alpha and scale k:
129 % Mean = alpha*k / (alpha-1)
130 % SCV = 1 / (alpha*(alpha-2))
131 %
132 % Solving for alpha from SCV:
133 % alpha*(alpha-2) = 1/SCV
134 % alpha^2 - 2*alpha - 1/SCV = 0
135 % alpha = 1 + sqrt(1 + 1/SCV) (taking positive root, need alpha > 2)
136 %
137 % Then scale k from mean:
138 % k = MEAN * (alpha-1) / alpha
139
140 shape = 1 + sqrt(1 + 1/SCV);
141 scale = MEAN * (shape - 1) / shape;
142 pa = Pareto(shape, scale);
143 end
144 end
145
146end