Coverage for /home/martinb/.local/share/virtualenvs/camcops/lib/python3.6/site-packages/statsmodels/stats/moment_helpers.py : 12%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""helper functions conversion between moments
3contains:
5* conversion between central and non-central moments, skew, kurtosis and
6 cummulants
7* cov2corr : convert covariance matrix to correlation matrix
10Author: Josef Perktold
11License: BSD-3
13"""
15import numpy as np
16from scipy.special import comb
19def _convert_to_multidim(x):
20 if any([isinstance(x, list), isinstance(x, tuple)]):
21 return np.array(x)
22 elif isinstance(x, np.ndarray):
23 return x
24 else:
25 # something strange was passed and the function probably
26 # will fall, maybe insert an exception?
27 return x
30def _convert_from_multidim(x, totype=list):
31 if len(x.shape) < 2:
32 return totype(x)
33 return x.T
36def mc2mnc(mc):
37 """convert central to non-central moments, uses recursive formula
38 optionally adjusts first moment to return mean
39 """
40 x = _convert_to_multidim(mc)
42 def _local_counts(mc):
43 mean = mc[0]
44 mc = [1] + list(mc) # add zero moment = 1
45 mc[1] = 0 # define central mean as zero for formula
46 mnc = [1, mean] # zero and first raw moments
47 for nn, m in enumerate(mc[2:]):
48 n = nn + 2
49 mnc.append(0)
50 for k in range(n + 1):
51 mnc[n] += comb(n, k, exact=True) * mc[k] * mean ** (n - k)
52 return mnc[1:]
54 res = np.apply_along_axis(_local_counts, 0, x)
55 # for backward compatibility convert 1-dim output to list/tuple
56 return _convert_from_multidim(res)
59def mnc2mc(mnc, wmean=True):
60 """convert non-central to central moments, uses recursive formula
61 optionally adjusts first moment to return mean
62 """
63 X = _convert_to_multidim(mnc)
65 def _local_counts(mnc):
66 mean = mnc[0]
67 mnc = [1] + list(mnc) # add zero moment = 1
68 mu = []
69 for n, m in enumerate(mnc):
70 mu.append(0)
71 for k in range(n + 1):
72 sgn_comb = (-1) ** (n - k) * comb(n, k, exact=True)
73 mu[n] += sgn_comb * mnc[k] * mean ** (n - k)
74 if wmean:
75 mu[1] = mean
76 return mu[1:]
78 res = np.apply_along_axis(_local_counts, 0, X)
79 # for backward compatibility convert 1-dim output to list/tuple
80 return _convert_from_multidim(res)
83def cum2mc(kappa):
84 """convert non-central moments to cumulants
85 recursive formula produces as many cumulants as moments
87 References
88 ----------
89 Kenneth Lange: Numerical Analysis for Statisticians, page 40
90 """
91 X = _convert_to_multidim(kappa)
93 def _local_counts(kappa):
94 mc = [1, 0.0] # _kappa[0]] #insert 0-moment and mean
95 kappa0 = kappa[0]
96 kappa = [1] + list(kappa)
97 for nn, m in enumerate(kappa[2:]):
98 n = nn + 2
99 mc.append(0)
100 for k in range(n - 1):
101 mc[n] += comb(n - 1, k, exact=True) * kappa[n - k] * mc[k]
102 mc[1] = kappa0 # insert mean as first moments by convention
103 return mc[1:]
105 res = np.apply_along_axis(_local_counts, 0, X)
106 # for backward compatibility convert 1-dim output to list/tuple
107 return _convert_from_multidim(res)
110def mnc2cum(mnc):
111 """convert non-central moments to cumulants
112 recursive formula produces as many cumulants as moments
114 https://en.wikipedia.org/wiki/Cumulant#Cumulants_and_moments
115 """
116 X = _convert_to_multidim(mnc)
118 def _local_counts(mnc):
119 mnc = [1] + list(mnc)
120 kappa = [1]
121 for nn, m in enumerate(mnc[1:]):
122 n = nn + 1
123 kappa.append(m)
124 for k in range(1, n):
125 num_ways = comb(n - 1, k - 1, exact=True)
126 kappa[n] -= num_ways * kappa[k] * mnc[n - k]
127 return kappa[1:]
129 res = np.apply_along_axis(_local_counts, 0, X)
130 # for backward compatibility convert 1-dim output to list/tuple
131 return _convert_from_multidim(res)
134def mc2cum(mc):
135 """
136 just chained because I have still the test case
137 """
138 first_step = mc2mnc(mc)
139 if isinstance(first_step, np.ndarray):
140 first_step = first_step.T
141 return mnc2cum(first_step)
142 # return np.apply_along_axis(lambda x: mnc2cum(mc2mnc(x)), 0, mc)
145def mvsk2mc(args):
146 """convert mean, variance, skew, kurtosis to central moments"""
147 X = _convert_to_multidim(args)
149 def _local_counts(args):
150 mu, sig2, sk, kur = args
151 cnt = [None] * 4
152 cnt[0] = mu
153 cnt[1] = sig2
154 cnt[2] = sk * sig2 ** 1.5
155 cnt[3] = (kur + 3.0) * sig2 ** 2.0
156 return tuple(cnt)
158 res = np.apply_along_axis(_local_counts, 0, X)
159 # for backward compatibility convert 1-dim output to list/tuple
160 return _convert_from_multidim(res, tuple)
163def mvsk2mnc(args):
164 """convert mean, variance, skew, kurtosis to non-central moments"""
165 X = _convert_to_multidim(args)
167 def _local_counts(args):
168 mc, mc2, skew, kurt = args
169 mnc = mc
170 mnc2 = mc2 + mc * mc
171 mc3 = skew * (mc2 ** 1.5) # 3rd central moment
172 mnc3 = mc3 + 3 * mc * mc2 + mc ** 3 # 3rd non-central moment
173 mc4 = (kurt + 3.0) * (mc2 ** 2.0) # 4th central moment
174 mnc4 = mc4 + 4 * mc * mc3 + 6 * mc * mc * mc2 + mc ** 4
175 return (mnc, mnc2, mnc3, mnc4)
177 res = np.apply_along_axis(_local_counts, 0, X)
178 # for backward compatibility convert 1-dim output to list/tuple
179 return _convert_from_multidim(res, tuple)
182def mc2mvsk(args):
183 """convert central moments to mean, variance, skew, kurtosis"""
184 X = _convert_to_multidim(args)
186 def _local_counts(args):
187 mc, mc2, mc3, mc4 = args
188 skew = np.divide(mc3, mc2 ** 1.5)
189 kurt = np.divide(mc4, mc2 ** 2.0) - 3.0
190 return (mc, mc2, skew, kurt)
192 res = np.apply_along_axis(_local_counts, 0, X)
193 # for backward compatibility convert 1-dim output to list/tuple
194 return _convert_from_multidim(res, tuple)
197def mnc2mvsk(args):
198 """convert central moments to mean, variance, skew, kurtosis
199 """
200 X = _convert_to_multidim(args)
202 def _local_counts(args):
203 # convert four non-central moments to central moments
204 mnc, mnc2, mnc3, mnc4 = args
205 mc = mnc
206 mc2 = mnc2 - mnc * mnc
207 mc3 = mnc3 - (3 * mc * mc2 + mc ** 3) # 3rd central moment
208 mc4 = mnc4 - (4 * mc * mc3 + 6 * mc * mc * mc2 + mc ** 4)
209 return mc2mvsk((mc, mc2, mc3, mc4))
211 res = np.apply_along_axis(_local_counts, 0, X)
212 # for backward compatibility convert 1-dim output to list/tuple
213 return _convert_from_multidim(res, tuple)
215# def mnc2mc(args):
216# """convert four non-central moments to central moments
217# """
218# mnc, mnc2, mnc3, mnc4 = args
219# mc = mnc
220# mc2 = mnc2 - mnc*mnc
221# mc3 = mnc3 - (3*mc*mc2+mc**3) # 3rd central moment
222# mc4 = mnc4 - (4*mc*mc3+6*mc*mc*mc2+mc**4)
223# return mc, mc2, mc
225# TODO: no return, did it get lost in cut-paste?
228def cov2corr(cov, return_std=False):
229 """
230 convert covariance matrix to correlation matrix
232 Parameters
233 ----------
234 cov : array_like, 2d
235 covariance matrix, see Notes
237 Returns
238 -------
239 corr : ndarray (subclass)
240 correlation matrix
241 return_std : bool
242 If this is true then the standard deviation is also returned.
243 By default only the correlation matrix is returned.
245 Notes
246 -----
247 This function does not convert subclasses of ndarrays. This requires that
248 division is defined elementwise. np.ma.array and np.matrix are allowed.
249 """
250 cov = np.asanyarray(cov)
251 std_ = np.sqrt(np.diag(cov))
252 corr = cov / np.outer(std_, std_)
253 if return_std:
254 return corr, std_
255 else:
256 return corr
259def corr2cov(corr, std):
260 """
261 convert correlation matrix to covariance matrix given standard deviation
263 Parameters
264 ----------
265 corr : array_like, 2d
266 correlation matrix, see Notes
267 std : array_like, 1d
268 standard deviation
270 Returns
271 -------
272 cov : ndarray (subclass)
273 covariance matrix
275 Notes
276 -----
277 This function does not convert subclasses of ndarrays. This requires
278 that multiplication is defined elementwise. np.ma.array are allowed, but
279 not matrices.
280 """
281 corr = np.asanyarray(corr)
282 std_ = np.asanyarray(std)
283 cov = corr * np.outer(std_, std_)
284 return cov
287def se_cov(cov):
288 """
289 get standard deviation from covariance matrix
291 just a shorthand function np.sqrt(np.diag(cov))
293 Parameters
294 ----------
295 cov : array_like, square
296 covariance matrix
298 Returns
299 -------
300 std : ndarray
301 standard deviation from diagonal of cov
302 """
303 return np.sqrt(np.diag(cov))