def variation(x, ddof=1): """ The variation of x. The variation the ratio of the standard deviation to the mean: std(x, ddof) / mean(x) Note that, unlike `var` and `std`, the default value of `ddof` is 1. This is the more typical value used when computing the variation. (The implementation is simply std(x, ddof) / mean(x); no special handling is provided for `nan` values, a mean of 0, etc.) Examples -------- >>> from mpsci.stats import variation >>> variation([2, 3, 5, 8, 13, 21]) >>> mpf('0.83418102841390518') For comparison to `scipy.stats.variation`, use `ddof=0`: >>> variation([2, 3, 5, 8, 13, 21], ddof=0) >>> mpf('0.76149961050858964') """ with mpmath.extraprec(16): s = std(x, ddof=ddof) m = mean(x) return s / m
def var(x, ddof=0): """ Variance of the values in the sequence x. """ n = len(x) with mpmath.extraprec(16): sumx = mpmath.fsum(x) meanx = sumx / n varx = mpmath.fsum((mpmath.mpf(t) - meanx)**2 for t in x)/(n - ddof) return varx
def pmean(x, p): """ Power (or generalized) mean of the values in the sequence x. """ # Special cases if p == 0: return gmean(x) elif p == 1: return mean(x) elif p == -1: return hmean(x) elif mpmath.isinf(p): with mpmath.extraprec(16): if p > 0: return max(mpmath.mpf(t) for t in x) else: return min(mpmath.mpf(t) for t in x) with mpmath.extraprec(16): p = mpmath.mpf(p) return mpmath.power(mean([mpmath.mpf(t)**p for t in x]), 1/p)
def hyper1(As, Bs, N, M): with mpmath.extraprec(mpmath.mp.prec): s = t = 1 for j in range(1, N): t *= fprod(a + j - 1 for a in As) / fprod(b + j - 1 for b in Bs) s += t if M > 0: s2 = 0 g = sum(As) - sum(Bs) for (j, c) in enumerate(gammaprod_series(As, Bs, M)): s2 += c * mpmath.zeta(-(g - j), N) s += s2 * mpmath.gammaprod(Bs, As) return s
def mean(x, weights=None): """ Mean of the values in the sequence x. Negative values in weights are allowed. The only constraint is that sum(weights) is not zero. """ n = len(x) if weights is not None: if len(weights) != n: raise ValueError('x and weights must have the same length.') with mpmath.extraprec(16): if weights is None: return mpmath.fsum(x) / len(x) else: if mpmath.fsum(weights) == 0: raise ZeroDivisionError('sum(weights) must be nonzero.') return (mpmath.fsum(t*w for t, w in zip(x, weights)) / mpmath.fsum(weights))
def hyper1_auto(As, Bs, N, M): with mpmath.extraprec(mpmath.mp.prec): s = t = 1 good_ratio_hits = 0 for j in range(1, N): s_old = s t *= fprod(a + j - 1 for a in As) / fprod(b + j - 1 for b in Bs) s += t ratio = (s - s_old) / s if ratio < mpf(10**-18): good_ratio_hits += 1 if good_ratio_hits > 3: break print float(s) if M > 0: s2 = 0 g = sum(As) - sum(Bs) for (j, c) in enumerate(gammaprod_series(As, Bs, M)): s2 += c * mpmath.zeta(-(g - j), N) s += s2 * mpmath.gammaprod(Bs, As) return s
def hyper1_auto(As, Bs, N, M): with mpmath.extraprec(mpmath.mp.prec): s = t = 1 good_ratio_hits = 0 for j in range(1, N): s_old = s t *= fprod(a + j - 1 for a in As) / fprod(b + j - 1 for b in Bs) s += t ratio = (s - s_old) / s if ratio < mpf(10 ** -18): good_ratio_hits += 1 if good_ratio_hits > 3: break print float(s) if M > 0: s2 = 0 g = sum(As) - sum(Bs) for (j, c) in enumerate(gammaprod_series(As, Bs, M)): s2 += c * mpmath.zeta(-(g - j), N) s += s2 * mpmath.gammaprod(Bs, As) return s
def gmean(x, weights=None): """ Geometric mean of the values in the sequence x. All the values in x must be nonnegative. If weights is not None, it must be a sequence with the same length as x. The sum of weights must not be zero. """ if any(t < 0 for t in x): raise ValueError("all values in x must be nonnegative.") with mpmath.extraprec(16): if weights is None: if 0 in x: return mpmath.mp.zero return mpmath.exp(mean([mpmath.log(t) for t in x])) else: # Weighted geometric mean wsum = mpmath.fsum(weights) if wsum == 0: raise ValueError('sum of weights must not be 0.') wlogxsum = mpmath.fsum([_xlogy(wi, xi) for (xi, wi) in zip(x, weights)]) return mpmath.exp(wlogxsum / wsum)
# -*- coding: utf-8 -*- """ Created on Thu Jul 20 17:30:45 2017 @author: martin """ import numpy as np import scipy as sp import scipy.optimize from scipy.interpolate import interp1d import sympy import unittest import mpmath as mp mp.extraprec(50) class interp1d_mpmath(interp1d): def _prepare_x(self, x): """Reshape input x array to 1-D""" x = sp._lib._util._asarray_validated(x, check_finite=False, as_inexact=True, objects_ok=True) x_shape = x.shape return x.ravel(), x_shape class LinearCombinationUniformSpacings(): r"""
def std(x, ddof=0): """ Standard deviation of the values in the sequence x. """ with mpmath.extraprec(16): return mpmath.sqrt(var(x, ddof))
def hmean(x): """ Harmonic mean of the values in the sequence x. If any value in x is 0, the return value is 0. hmean accepts negative values. Usually the harmonic mean is defined for positive values only, but the formula is well-defined as long as 1/x[0] + 1/x[1] + ... + 1/x[-1] is not 0. If that expression is 0, and the signs of the x values are mixed, nan is returned. If the signs are not mixed, then either all the values are +inf or they are all -inf. For those cases, +inf and -inf are returned, respectively. Examples -------- >>> from mpsci.stats import hmean >>> import mpmath >>> mpmath.mp.dps = 25 >>> hmean([1, 3, 3]) mpf('1.8') >>> hmean([10, 3, -2]) mpf('-45.0') >>> hmean(range(1, 10)) mpf('3.181371861411137606957497545') >>> hmean([2, -2]) mpf('nan') >>> hmean([mpmath.inf, mpmath.inf, mpmath.inf]) mpf('+inf') >>> hmean([mpmath.inf, mpmath.inf, -mpmath.inf]) mpf('nan') >>> hmean([-mpmath.inf, -mpmath.inf, -mpmath.inf]) >>> mpf('-inf') """ npos = 0 nneg = 0 nzero = 0 for t in x: if t > 0: npos += 1 elif t < 0: nneg += 1 else: nzero += 1 if nzero > 0: return mpmath.mp.zero mixed_signs = npos > 0 and nneg > 0 with mpmath.extraprec(16): m = mean([1/mpmath.mpf(t) for t in x]) if m == 0: if mixed_signs: return mpmath.mp.nan elif npos > 0: return mpmath.mp.inf else: return -mpmath.mp.inf else: return 1 / m
def test_pmean(): with mpmath.extraprec(16): assert mpmath.almosteq(pmean([3, 4, 5], 3), 72**mpmath.mpf('1/3')) assert mpmath.almosteq(pmean([2, 2, 1], -2), mpmath.sqrt(2)) assert pmean([4, 2, 5, 3], mpmath.inf) == 5 assert pmean([4, 2, 5, 3], -mpmath.inf) == 2
def test_hmean(): with mpmath.extraprec(16): assert mpmath.almosteq(hmean([1, 2, 16]), mpmath.mpf('48/25'))
def test_std(): with mpmath.extraprec(16): assert mpmath.almosteq(std([2, 4, 6]), mpmath.sqrt(mpmath.mpf('8/3'))) assert mpmath.almosteq(std([2, 4, 6], ddof=1), 2)
def test_var(): with mpmath.extraprec(16): assert mpmath.almosteq(var([2, 4, 6]), mpmath.mpf('8/3')) assert mpmath.almosteq(var([2, 4, 6], ddof=1), 4)