def field_isomorphism_pslq(a, b): """Construct field isomorphism using PSLQ algorithm.""" if not all(_.domain.is_RationalField and _.ext.is_real for _ in (a, b)): raise NotImplementedError("PSLQ doesn't support complex coefficients") f = a.minpoly g = b.minpoly.replace(f.gen) m = b.minpoly.degree() for n in mpmath.libmp.libintmath.giant_steps(32, 256): # pragma: no branch with mpmath.workdps(n): A = lambdify((), a.ext, "mpmath")() B = lambdify((), b.ext, "mpmath")() basis = [B**i for i in range(m)] + [A] coeffs = mpmath.pslq(basis, maxcoeff=int(1e10), maxsteps=1000) if coeffs is None: break coeffs = [QQ(c, coeffs[-1]) for c in coeffs[:-1]] while not coeffs[-1]: coeffs.pop() coeffs.reverse() h = Poly(coeffs, f.gen, domain='QQ') if f.compose(h).rem(g).is_zero or f.compose(-h).rem(g).is_zero: return [-c for c in coeffs]
def test_d(): # Compare the d_{k, n} to the results in appendix F of [1]. # # Sources # ------- # [1] DiDonato and Morris, Computation of the Incomplete Gamma # Function Ratios and their Inverse, ACM Transactions on # Mathematical Software, 1986. with mp.workdps(50): dataset = [(0, 0, -mp.mpf('0.333333333333333333333333333333')), (0, 12, mp.mpf('0.102618097842403080425739573227e-7')), (1, 0, -mp.mpf('0.185185185185185185185185185185e-2')), (1, 12, mp.mpf('0.119516285997781473243076536700e-7')), (2, 0, mp.mpf('0.413359788359788359788359788360e-2')), (2, 12, -mp.mpf('0.140925299108675210532930244154e-7')), (3, 0, mp.mpf('0.649434156378600823045267489712e-3')), (3, 12, -mp.mpf('0.191111684859736540606728140873e-7')), (4, 0, -mp.mpf('0.861888290916711698604702719929e-3')), (4, 12, mp.mpf('0.288658297427087836297341274604e-7')), (5, 0, -mp.mpf('0.336798553366358150308767592718e-3')), (5, 12, mp.mpf('0.482409670378941807563762631739e-7')), (6, 0, mp.mpf('0.531307936463992223165748542978e-3')), (6, 12, -mp.mpf('0.882860074633048352505085243179e-7')), (7, 0, mp.mpf('0.344367606892377671254279625109e-3')), (7, 12, -mp.mpf('0.175629733590604619378669693914e-6')), (8, 0, -mp.mpf('0.652623918595309418922034919727e-3')), (8, 12, mp.mpf('0.377358774161109793380344937299e-6')), (9, 0, -mp.mpf('0.596761290192746250124390067179e-3')), (9, 12, mp.mpf('0.870823417786464116761231237189e-6'))] d = compute_d(10, 13) res = [d[k][n] for k, n, std in dataset] std = map(lambda x: x[2], dataset) mp_assert_allclose(res, std)
def test_gth_solve_high_prec(): n = 1e-100 with mp.workdps(100): P = mp.matrix([[-3*(mp.exp(n)-1), 3*(mp.exp(n)-1)], [mp.exp(n)-1 , -(mp.exp(n)-1) ]]) run_gth_solve(P, verbose=VERBOSE)
def test_stoch_eig_high_prec(): n = 1e-100 with mp.workdps(100): P = mp.matrix([[1-3*(mp.exp(n)-1), 3*(mp.exp(n)-1)], [mp.exp(n)-1 , 1-(mp.exp(n)-1)]]) run_stoch_eig(P, verbose=VERBOSE)
def test_g(): # Test data for the g_k. See DLMF 5.11.4. with mp.workdps(30): g = [mp.mpf(1), mp.mpf(1)/12, mp.mpf(1)/288, -mp.mpf(139)/51840, -mp.mpf(571)/2488320, mp.mpf(163879)/209018880, mp.mpf(5246819)/75246796800] mp_assert_allclose(compute_g(7), g)
def _noncentral_chi_cdf(x, df, nc, dps=None): if dps is None: dps = mpmath.mp.dps x, df, nc = mpmath.mpf(x), mpmath.mpf(df), mpmath.mpf(nc) with mpmath.workdps(dps): res = mpmath.quad(lambda t: _noncentral_chi_pdf(t, df, nc), [0, x]) return res
def test_alpha(): # Test data for the alpha_k. See DLMF 8.12.14. with mp.workdps(30): alpha = [mp.mpf(0), mp.mpf(1), mp.mpf(1)/3, mp.mpf(1)/36, -mp.mpf(1)/270, mp.mpf(1)/4320, mp.mpf(1)/17010, -mp.mpf(139)/5443200, mp.mpf(1)/204120] mp_assert_allclose(compute_alpha(9), alpha)
def runTest(self): import math from .math import cos as pcos, sin as psin from .types import polynomial, kronecker_monomial, double, real self.assertEqual(math.cos(3),pcos(3)) self.assertEqual(math.cos(3.1234),pcos(3.1234)) self.assertEqual(math.sin(3),psin(3)) self.assertEqual(math.sin(3.1234),psin(3.1234)) pt = polynomial(double,kronecker_monomial())() self.assertEqual(math.cos(3),pcos(pt(3))) self.assertEqual(math.cos(-2.456),pcos(pt(2.456))) self.assertEqual(math.sin(3),psin(pt(3))) self.assertEqual(math.sin(-2.456),-psin(pt(2.456))) self.assertRaises(TypeError,lambda : pcos("")) self.assertRaises(TypeError,lambda : psin("")) try: from mpmath import mpf, workdps from mpmath import cos as mpcos, sin as mpsin pt = polynomial(real,kronecker_monomial())() self.assertEqual(mpcos(mpf("1.2345")),pcos(mpf("1.2345"))) self.assertEqual(mpcos(mpf("3")),pcos(pt(mpf("3")))) self.assertEqual(mpcos(mpf("-2.456")),pcos(pt(mpf("-2.456")))) self.assertEqual(mpsin(mpf("1.2345")),psin(mpf("1.2345"))) self.assertEqual(mpsin(mpf("3")),psin(pt(mpf("3")))) self.assertEqual(mpsin(mpf("-2.456")),psin(pt(mpf("-2.456")))) with workdps(500): self.assertEqual(mpcos(mpf("1.2345")),pcos(mpf("1.2345"))) self.assertEqual(mpcos(mpf("3")),pcos(pt(mpf("3")))) self.assertEqual(mpcos(mpf("-2.456")),pcos(pt(mpf("-2.456")))) self.assertEqual(mpsin(mpf("1.2345")),psin(mpf("1.2345"))) self.assertEqual(mpsin(mpf("3")),psin(pt(mpf("3")))) self.assertEqual(mpsin(mpf("-2.456")),psin(pt(mpf("-2.456")))) except ImportError: pass
def taylor_series_at_1(N): coeffs = [] with mpmath.workdps(100): coeffs.append(-mpmath.euler) for n in range(2, N + 1): coeffs.append((-1)**n*mpmath.zeta(n)/n) return coeffs
def gammaincc(a, x, dps=50, maxterms=10**8): """Compute gammaincc exactly like mpmath does but allow for more terms in hypercomb. See mpmath/functions/expintegrals.py#L187 in the mpmath github repository. """ with mp.workdps(dps): z, a = a, x if mp.isint(z): try: # mpmath has a fast integer path return mpf2float(mp.gammainc(z, a=a, regularized=True)) except mp.libmp.NoConvergence: pass nega = mp.fneg(a, exact=True) G = [z] # Use 2F0 series when possible; fall back to lower gamma representation try: def h(z): r = z-1 return [([mp.exp(nega), a], [1, r], [], G, [1, -r], [], 1/nega)] return mpf2float(mp.hypercomb(h, [z], force_series=True)) except mp.libmp.NoConvergence: def h(z): T1 = [], [1, z-1], [z], G, [], [], 0 T2 = [-mp.exp(nega), a, z], [1, z, -1], [], G, [1], [1+z], a return T1, T2 return mpf2float(mp.hypercomb(h, [z], maxterms=maxterms))
def zetac_series(N): coeffs = [] with mpmath.workdps(100): coeffs.append(-1.5) for n in range(1, N): coeff = mpmath.diff(mpmath.zeta, 0, n)/mpmath.factorial(n) coeffs.append(coeff) return coeffs
def logReg_ObjectiveFunction(X,Y,W,u,s,coef_transfer,b): w=np.array([W[1:]]).T w_0=W[0] A=np.dot(X,w)+float(w_0) B=-np.multiply(Y,A) with mp.workdps(30): NLL=sum(log_one_plus_exp(B))+coef_transfer*0.5*GPriorWeightRegTerm(W,u,s)#+(1/float(np.shape(Y)[0]))*np.dot(b.T,np.array([W]).T)[0,0] return NLL
def test_logpdf(): with mpmath.workdps(50): x = mpmath.mpf('1.5') p = benktander1.logpdf(x, 2, 3) # Expected value computed with Wolfram Alpha: # log(PDF[BenktanderGibratDistribution[2, 3], 3/2]) valstr = '0.086726919062697113736142804022160705324241157062981346304' expected = mpmath.mpf(valstr) assert mpmath.almosteq(p, expected)
def _student_t_cdf(df, t, dps=None): if dps is None: dps = mpmath.mp.dps with mpmath.workdps(dps): df, t = mpmath.mpf(df), mpmath.mpf(t) fac = mpmath.hyp2f1(0.5, 0.5*(df + 1), 1.5, -t**2/df) fac *= t*mpmath.gamma(0.5*(df + 1)) fac /= mpmath.sqrt(mpmath.pi*df)*mpmath.gamma(0.5*df) return 0.5 + fac
def _student_t_cdf(df, t, dps=None): if dps is None: dps = mpmath.mp.dps with mpmath.workdps(dps): df, t = mpmath.mpf(df), mpmath.mpf(t) fac = mpmath.hyp2f1(0.5, 0.5 * (df + 1), 1.5, -t**2 / df) fac *= t * mpmath.gamma(0.5 * (df + 1)) fac /= mpmath.sqrt(mpmath.pi * df) * mpmath.gamma(0.5 * df) return 0.5 + fac
def test_specific_values_from_wolfram(): # The function is MarcumQ[m, a, b] in Wolfram. with mpmath.workdps(50): values = [ [(1, 1, 2), mpmath.mpf( '0.269012060035909996678516959220271087421337500744873384155') ], [(4, 2, 2), mpmath.mpf( '0.961002639616864002974959310625974743642314730388958932865') ], [(10, 2, 7), mpmath.mpf( '0.003419880268711142942584170929968429599523954396941827739') ], [(10, 2, 20), mpmath.mpf( '1.1463968305097683198312254572377449552982286967700350e-63') ], [(25, 3, 1), mpmath.mpf( '0.999999999999999999999999999999999985610186498600062604510') ], [(100, 5, 25), mpmath.mpf( '6.3182094741234192918553754494227940871375208133861094e-36') ], ] for (m, a, b), expected in values: q = marcumq(m, a, b) assert mpmath.almosteq(q, expected) values = [ [(0.5, 1, 2), mpmath.mpf( '0.839994848036912854058580730864442945100083598568223741623') ], [(0.5, 5, 13), mpmath.mpf( '0.99999999999999937790394257282158764840048274118115775113') ], [(0.5, 5, mpmath.mpf('1/13')), mpmath.mpf( '2.3417168332795098320214996797055274037932802604709459e-7')], [(0.75, 5, mpmath.mpf('0.001')), mpmath.mpf( '7.6243509472783061143887290663443105556790864676878435e-11') ], [(51 / 2, 5, mpmath.mpf('0.1')), mpmath.mpf( '9.9527768099307883918427141035705197017192239618506806e-91')] ] for (m, a, b), expected in values: c = cmarcumq(m, a, b) assert mpmath.almosteq(c, expected)
def test_skewness(): with mpmath.workdps(50): k = mpmath.mpf(2) theta = mpmath.mpf(7) skew = loggamma.skewness(k, theta) # Expected value computed with Wolfram Alpha: # Skewness[ExpGammaDistribution[2, 7, 0]] valstr = '-0.780244491437787061530103769675602605070996940757461555988' expected = mpmath.mpf(valstr) assert mpmath.almosteq(skew, expected)
def decompose(x, gamma_pow, precision=40): with mp.workdps(2048): tail = x compressed = np.zeros(precision + 1) for i in xrange(precision + 1): if tail == 0: break tail, compressed[i] = mp.frac(tail), mp.floor(tail) tail = mp.ldexp(tail, gamma_pow) return compressed
def test_mean(): with mpmath.workdps(50): k = mpmath.mpf(2) theta = mpmath.mpf(7) mean = loggamma.mean(k, theta) # Expected value computed with Wolfram Alpha: # Mean[ExpGammaDistribution[2, 7, 0]] valstr = '2.9594903456892699757544153694231829827048846484205348083596' expected = mpmath.mpf(valstr) assert mpmath.almosteq(mean, expected)
def idmap(self, *args): if self.spfunc_first: res = self.spfunc(*args) if np.isnan(res): return np.nan args = list(args) args[self.index] = res with mpmath.workdps(self.dps): res = self.mpfunc(*tuple(args)) # Imaginary parts are spurious res = mpf2float(res.real) else: with mpmath.workdps(self.dps): res = self.mpfunc(*args) res = mpf2float(res.real) args = list(args) args[self.index] = res res = self.spfunc(*tuple(args)) return res
def cauchy_eigen(mu, dps): mu = np.atleast_1d(mu) n = len(mu) with mp.workdps(dps): mu = mp.matrix(mu) M = mp.zeros(n, n) for i, j in product(range(n), range(n)): M[i, j] = (mu[i] + mu[j].conjugate())**(-1) ewL, QL = mp.eighe(M) return ewL, QL
def test_var(): with mpmath.workdps(50): a = 2 b = 3 m = benktander1.var(a, b) # Expected value computed with Wolfram Alpha: # Var[BenktanderGibratDistribution[2, 3]] valstr = '0.129886916731278610514259475545032373691162070980680465530' expected = mpmath.mpf(valstr) assert mpmath.almosteq(m, expected)
def u_binom(N): out = np.zeros((len(x),len(t))) out = out + 0.5*W(0)[...,None]*np.ones(len(t)) with mpmath.workdps(workdps): for n in range(1,N): coeff = np.zeros(len(x)) for m in range(n): coeff = coeff + (-1)**((n-1)-m)*mpmath.binomial(n-1,m)*W(m+1) out = out + coeff[...,None]*((t/(2*tau))**n)/mpmath.factorial(n) return out
def test_kurtosis(): with mpmath.workdps(50): k = mpmath.mpf(2) theta = mpmath.mpf(7) kurt = loggamma.kurtosis(k, theta) # Expected value computed with Wolfram Alpha: # ExcessKurtosis[ExpGammaDistribution[2, 7, 0]] valstr = '1.1875257511965620472368652875718220772212082979314426565409' expected = mpmath.mpf(valstr) assert mpmath.almosteq(kurt, expected)
def test_var(): with mpmath.workdps(50): k = mpmath.mpf(2) theta = mpmath.mpf(7) var = loggamma.var(k, theta) # Expected value computed with Wolfram Alpha: # Variance[ExpGammaDistribution[2, 7, 0]] valstr = '31.601769275563095387148343165655234271728545159133123449042' expected = mpmath.mpf(valstr) assert mpmath.almosteq(var, expected)
def test_bounds_for_Q1(): """ These bounds are from: Jiangping Wang and Dapeng Wu, "Tight bounds for the first order Marcum Q-function" Wireless Communications and Mobile Computing, Volume 12, Issue 4, March 2012, Pages 293-301. """ with mpmath.workdps(50): sqrt2 = mpmath.sqrt(2) sqrthalfpi = mpmath.sqrt(mpmath.pi / 2) for b in [mpmath.mp.mpf(1), mpmath.mp.mpf(10)]: for a in [b / 16, 0.5 * b, 0.875 * b, b]: q1 = marcumq(1, a, b) sinhab = mpmath.sinh(a * b) i0ab = mpmath.besseli(0, a * b) # lower bound when 0 <= a <= b lb = (mpmath.sqrt(mpmath.pi / 8) * b * i0ab / sinhab * (mpmath.erfc((b - a) / sqrt2) - mpmath.erfc( (b + a) / sqrt2))) assert lb < q1 # upper bound when 0 <= a <= b ub = ((i0ab + 3) / (mpmath.exp(a * b) + 3) * ( mpmath.exp(-(b - a)**2 / 2) + a * sqrthalfpi * mpmath.erfc( (b - a) / sqrt2) + 3 * mpmath.exp(-(a**2 + b**2) / 2))) assert q1 < ub, ("marcumq(1, a, b) < ub for a = %s, b = %s" % (a, b)) for a in [mpmath.mp.mpf(1), mpmath.mp.mpf(10)]: for b in [b / 16, 0.5 * b, 0.875 * b, b]: q1 = marcumq(1, a, b) sinhab = mpmath.sinh(a * b) i0ab = mpmath.besseli(0, a * b) # lower bound when 0 <= b <= a lb = (1 - sqrthalfpi * b * i0ab / sinhab * (mpmath.erf(a / sqrt2) - mpmath.erf( (a - b) / sqrt2) / 2 - mpmath.erf( (a + b) / sqrt2) / 2)) assert lb < q1 # upper bound when 0 <= b <= a ub = ( 1 - i0ab / (mpmath.exp(a * b) + 3) * (4 * mpmath.exp(-a**2 / 2) - mpmath.exp(-(b - a)**2 / 2) - 3 * mpmath.exp(-(a**2 + b**2) / 2) + a * sqrthalfpi * (mpmath.erfc(-a / sqrt2) - mpmath.erfc((b - a) / sqrt2)))) assert q1 < ub, ("marcumq(1, a, b) < ub for a = %s, b = %s" % (a, b))
def test_sf(): with mpmath.workdps(50): x = mpmath.mpf(1.0) loc = mpmath.mp.zero scale = mpmath.mpf(3.0) p = gumbel_min.sf(x, loc, scale) # Expected value computed with Wolfram Alpha: # 1 - CDF[GumbelDistribution[0, 3], 1] valstr = '0.24768130366579455342390646303215371545090605136653835' expected = mpmath.mpf(valstr) assert mpmath.almosteq(p, expected)
def test_cdf(): with mpmath.workdps(50): x = mpmath.mpf(1.0) loc = mpmath.mp.zero scale = mpmath.mpf(3.0) p = gumbel_min.cdf(x, loc, scale) # Expected value computed with Wolfram Alpha: # CDF[GumbelDistribution[0, 3], 1] valstr = '0.75231869633420544657609353696784628454909394863346165' expected = mpmath.mpf(valstr) assert mpmath.almosteq(p, expected)
def test_pdf(): with mpmath.workdps(50): x = mpmath.mpf(1.0) loc = mpmath.mp.zero scale = mpmath.mpf('0.1') p = gumbel_min.pdf(x, loc, scale) # Expected value was computed with Wolfram Alpha: # PDF[GumbelDistribution[0, 1/10], 1] valstr = '2.3463581492019736117406984253693582114273335082428261e-9561' expected = mpmath.mpf(valstr) assert mpmath.almosteq(p, expected)
def logReg_ObjectiveFunction(X, Y, W, u, s, coef_transfer, b): w = np.array([W[1:]]).T w_0 = W[0] A = np.dot(X, w) + float(w_0) B = -np.multiply(Y, A) with mp.workdps(30): NLL = sum( log_one_plus_exp(B)) + coef_transfer * 0.5 * GPriorWeightRegTerm( W, u, s ) #+(1/float(np.shape(Y)[0]))*np.dot(b.T,np.array([W]).T)[0,0] return NLL
def test_skewness(dist, sign): with mpmath.workdps(50): k = 1.25 loc = 1 scale = 3 skew = dist.skewness(k, loc, scale) # Expected value computed with Wolfram Alpha: # Skewness[WeibullDistribution[5/4, 3, 1]] valstr = '1.429545236590974853525527387620583784997166374292021040338' expected = mpmath.mpf(valstr) assert mpmath.almosteq(skew, sign * expected)
def test_kurtosis(dist): with mpmath.workdps(50): k = 1.25 loc = 1 scale = 3 kurt = dist.kurtosis(k, loc, scale) # Expected value computed with Wolfram Alpha: # ExcessKurtosis[WeibullDistribution[5/4, 3, 1]] valstr = '2.8021519350984650074697694858304410798423229238041266467027' expected = mpmath.mpf(valstr) assert mpmath.almosteq(kurt, expected)
def test_g(): # Test data for the g_k. See DLMF 5.11.4. with mp.workdps(30): g = [ mp.mpf(1), mp.mpf(1) / 12, mp.mpf(1) / 288, -mp.mpf(139) / 51840, -mp.mpf(571) / 2488320, mp.mpf(163879) / 209018880, mp.mpf(5246819) / 75246796800 ] mp_assert_allclose(compute_g(7), g)
def test_sf_invsf(): with mpmath.workdps(50): x = mpmath.mpf('1.5') p = benktander1.sf(x, 2, 3) # Expected value computed with Wolfram Alpha: # SurvivalFunction[BenktanderGibratDistribution[2, 3], 3/2] valstr = '0.40103000157608789634710325190011195010750064239976147223' expected = mpmath.mpf(valstr) assert mpmath.almosteq(p, expected) x1 = benktander1.invsf(expected, 2, 3) assert mpmath.almosteq(x1, x)
def test_logpdf(): with mpmath.workdps(50): x = mpmath.mpf('1.5') a = 2 b = mpmath.mpf('0.75') p = benktander2.logpdf(x, a, b) # Expected value computed with Wolfram Alpha: # log(PDF[BenktanderWeibullDistribution[2, 3/4], 3/2]) valstr = '-0.369111200683201817345059066451331575064497370791420217397' expected = mpmath.mpf(valstr) assert mpmath.almosteq(p, expected)
def test_pdf(): with mpmath.workdps(50): x = mpmath.mpf('1.5') a = 2 b = mpmath.mpf('0.75') p = benktander2.pdf(x, a, b) # Expected value computed with Wolfram Alpha: # PDF[BenktanderWeibullDistribution[2, 3/4], 3/2] valstr = '0.6913485277470671248347955016586714957100372820095067311673' expected = mpmath.mpf(valstr) assert mpmath.almosteq(p, expected)
def test_cdf_invcdf(): with mpmath.workdps(50): x = mpmath.mpf('1.5') p = benktander1.cdf(x, 2, 3) # Expected value computed with Wolfram Alpha: # CDF[BenktanderGibratDistribution[2, 3], 3/2] valstr = '0.59896999842391210365289674809988804989249935760023852777' expected = mpmath.mpf(valstr) assert mpmath.almosteq(p, expected) x1 = benktander1.invcdf(expected, 2, 3) assert mpmath.almosteq(x1, x)
def check_support(x, shape, loc, scale, dx='1e-10', precision=100): """ Verify that passed parameters are valid. Returns np.nan in place of invalid inputs (if array, replaces invalid values with np.nan's). """ with mpmath.workdps(precision): if not np.isscalar(x): x = np.array(x) # Parameters constraint if scale <= 0: raise ValueError('Scale parameter must be larger than 0') # Support constraint if np.isscalar(x): # Shape > 0 if mpmath.mpf(shape) > mpmath.mpf(dx): condition = x >= loc - scale / shape # Shape < 0 elif mpmath.mpf(shape) < -mpmath.mpf(dx): condition = x <= loc - scale / shape # Shape == 0 else: condition = True else: # Shape > 0 if mpmath.mpf(shape) > mpmath.mpf(dx): condition = np.all(x >= loc - scale / shape) # Shape < 0 elif mpmath.mpf(shape) < -mpmath.mpf(dx): condition = np.all(x <= loc - scale / shape) # Shape == 0 else: condition = True # Test conditions - replace invalid x's with np.nan if condition: return x else: if np.isscalar(x): return np.nan else: truncated_x = x # Shape > 0 if mpmath.mpf(shape) > mpmath.mpf(dx): truncated_x[truncated_x < loc - scale / shape] = np.nan # Shape < 0 elif mpmath.mpf(shape) < -mpmath.mpf(dx): truncated_x[truncated_x > loc - scale / shape] = np.nan # Shape == 0 else: pass return truncated_x
def __call__(self, x): with workdps(self.dps): indices, qs_mask = self.cube_dispatcher.index_search(x) q_forbidden = np.where(qs_mask == False)[0] sum_for_q = mpf('0.0') for i, q in indices: sum_for_q += self.exact_on_cube(i, q) for q in q_forbidden: idx, mlt = self.cube_dispatcher.forbidden_index_search(x, q) sum_for_q += self.average_between_cubes(idx, mlt, q) return self.f(x) - sum_for_q
def __call__(self, x): with workdps(self.dps): bits = strong_decompose(math.fabs(x), self.gamma, self.max_precision) ps = self.representation(bits) gammas = [mpf(self.gamma)]*bits.size """print '-'*80 print np.sum([c * gamma **(-power) for (c, gamma, power) in zip(ps, gammas, self.betas[:bits.size])]), x print bits print ps print gammas""" return math.copysign(np.sum([c * gamma **(-power) for (c, gamma, power) in zip(ps, gammas, self.betas[:bits.size])]), x)
def __init__( self, sym_constants, lhs_search_limit, saved_hash, an_generator: SeriesGeneratorClass = CartesianProductAnGenerator(), bn_generator: SeriesGeneratorClass = CartesianProductBnGenerator()): """ initialize search engine. basically, this is a 3 step procedure: 1) load / initialize lhs hash table. 2) first enumeration - enumerate over all rhs combinations, find hits in lhs hash table. 3) refine results - take results from (2) and validate them to 100 decimal digits. :param sym_constants: sympy constants :param lhs_search_limit: range of coefficients for left hand side. :param saved_hash: path to saved hash. :param an_generator: generating function for {an} series :param bn_generator: generating function for {bn} series """ self.threshold = 1 * 10**(-g_N_initial_key_length) # key length self.enum_dps = g_N_initial_search_dps # working decimal precision for first enumeration self.verify_dps = g_N_verify_dps # working decimal precision for validating results. self.lhs_limit = lhs_search_limit self.const_sym = sym_constants self.constants_generator = [] for i in range(len(sym_constants)): try: self.constants_generator.append( lambdify((), sym_constants[i], modules="mpmath")) except AttributeError: # Hackish constant self.constants_generator.append(sym_constants[i].mpf_val) self.create_an_series = an_generator.get_function() self.get_an_length = an_generator.get_num_iterations self.get_an_iterator = an_generator.get_iterator self.create_bn_series = bn_generator.get_function() self.get_bn_length = bn_generator.get_num_iterations self.get_bn_iterator = bn_generator.get_iterator if not os.path.isfile(saved_hash): print('no previous hash table given, initializing hash table...') with mpmath.workdps(self.enum_dps): constants = [const() for const in self.constants_generator] start = time() self.hash_table = LHSHashTable( saved_hash, self.lhs_limit, constants, # constant self.threshold) # length of key end = time() print(f'that took {end - start}s') else: self.hash_table = LHSHashTable.load_from(saved_hash)
def test_mean(): mu = 2.0 sigma = 3.0 # Wolfram Alpha: # Mean[LogNormalDistribution[2, 3]] # returns # 665.141633044361840693961494242634383221132254094828803184906532... s = '665.141633044361840693961494242634383221132254094828803184906532' with mpmath.workdps(len(s) - 1): expected = mpmath.mpf(s) mean = lognormal.mean(mu, sigma) assert mpmath.almosteq(mean, expected)
def test_Q1_identities(): with mpmath.workdps(50): for a in [mpmath.mp.mpf(1), mpmath.mp.mpf(13)]: q1 = marcumq(1, a, a) expected = 0.5 * (1 + mpmath.exp(-a**2) * mpmath.besseli(0, a**2)) assert mpmath.almosteq(q1, expected) for a, b in [(1, 2), (10, 3.5)]: total = marcumq(1, a, b) + marcumq(1, b, a) expected = 1 + mpmath.exp(-(a**2 + b**2) / 2) * mpmath.besseli( 0, a * b) assert mpmath.almosteq(total, expected)
def runTest(self): try: from mpmath import workdps, mpf, pi except ImportError: return from .types import polynomial, real, short pt = polynomial(real,short)() self.assertEqual(pt(mpf("4.5667")),mpf("4.5667")) self.assertEqual(pt(mpf("4.5667")) ** mpf("1.234567"),mpf("4.5667") ** mpf("1.234567")) for n in [11,21,51,101,501]: with workdps(n): self.assertEqual(pt(mpf("4.5667")),mpf("4.5667")) self.assertEqual(pt(mpf("4.5667")) ** mpf("1.234567"),mpf("4.5667") ** mpf("1.234567")) self.assertEqual(pt(mpf(pi)),mpf(pi))
def main(): print(__doc__) with mpmath.workdps(50): p, q = lambertw_pade() p, q = p[::-1], q[::-1] print("p = {}".format(p)) print("q = {}".format(q)) x, y = np.linspace(-1.5, 1.5, 75), np.linspace(-1.5, 1.5, 75) x, y = np.meshgrid(x, y) z = x + 1j*y lambertw_std = [] for z0 in z.flatten(): lambertw_std.append(complex(mpmath.lambertw(z0))) lambertw_std = np.array(lambertw_std).reshape(x.shape) fig, axes = plt.subplots(nrows=3, ncols=1) # Compare Pade approximation to true result p = np.array([float(p0) for p0 in p]) q = np.array([float(q0) for q0 in q]) pade_approx = np.polyval(p, z)/np.polyval(q, z) pade_err = abs(pade_approx - lambertw_std) axes[0].pcolormesh(x, y, pade_err) # Compare two terms of asymptotic series to true result asy_approx = np.log(z) - np.log(np.log(z)) asy_err = abs(asy_approx - lambertw_std) axes[1].pcolormesh(x, y, asy_err) # Compare two terms of the series around the branch point to the # true result p = np.sqrt(2*(np.exp(1)*z + 1)) series_approx = -1 + p - p**2/3 series_err = abs(series_approx - lambertw_std) im = axes[2].pcolormesh(x, y, series_err) fig.colorbar(im, ax=axes.ravel().tolist()) plt.show() fig, ax = plt.subplots(nrows=1, ncols=1) pade_better = pade_err < asy_err im = ax.pcolormesh(x, y, pade_better) t = np.linspace(-0.3, 0.3) ax.plot(-2.5*abs(t) - 0.2, t, 'r') fig.colorbar(im, ax=ax) plt.show()
def multinomial(n,m,multiplePrecision=False,decimalPlaces=40): ''' n = int m = list of integers summing to n ''' mybinom = binom if multiplePrecision: #use multiple-precision arithmetics with mp.workdps(decimalPlaces): if sum(m) != n: return mp.mpf('0.0') else: return np.prod([mp.mpf(mybinom(sum(m[i:]),m[i])) for i in xrange(len(m)-1)]) else: #use floating-point arithmetics if sum(m) != n: return 0.0 else: # if len(m)==1: m = list(m)+[0] #else the reduce statement does not work # return reduce(lambda x,y:x*y,[mybinom(sum(m[i:]),m[i]) for i in xrange(len(m)-1)]) return np.prod([mybinom(sum(m[i:]),m[i]) for i in xrange(len(m)-1)])
def main(): print(__doc__) K = 25 N = 25 with mp.workdps(50): d = compute_d(K, N) fn = os.path.join(os.path.dirname(__file__), '..', 'cephes', 'igam.h') with open(fn + '.new', 'w') as f: f.write(header.format(K, N)) for k, row in enumerate(d): row = map(lambda x: mp.nstr(x, 17, min_fixed=0, max_fixed=0), row) f.write('{') f.write(", ".join(row)) if k < K - 1: f.write('},\n') else: f.write('}};\n') f.write(footer) os.rename(fn + '.new', fn)
def main(): print(__doc__) K = 25 N = 25 with mp.workdps(50): d = compute_d(K, N) fn = os.path.join(os.path.dirname(__file__), "..", "cephes", "igam.h") with open(fn + ".new", "w") as f: f.write(header.format(K, N)) for k, row in enumerate(d): row = map(lambda x: mp.nstr(x, 17, min_fixed=0, max_fixed=0), row) f.write("{") f.write(", ".join(row)) if k < K - 1: f.write("},\n") else: f.write("}};\n") f.write(footer) os.rename(fn + ".new", fn)
def runTest(self): import math from .math import cos as pcos, sin as psin from .types import polynomial, k_monomial, double, real # NOTE: according to # https://docs.python.org/3/library/math.html # the CPython math functions are wrappers around the corresponding # C functions. The results should thus be the same. self.assertEqual(math.cos(3.),pcos(3.)) self.assertEqual(math.cos(3.1234),pcos(3.1234)) self.assertEqual(math.sin(3.),psin(3.)) self.assertEqual(math.sin(3.1234),psin(3.1234)) pt = polynomial(double,k_monomial)() self.assertEqual(math.cos(3),pcos(pt(3))) self.assertEqual(math.cos(2.456),pcos(pt(2.456))) self.assertEqual(math.sin(3),psin(pt(3))) self.assertEqual(math.sin(-2.456),psin(pt(-2.456))) self.assertRaises(TypeError,lambda : pcos("")) self.assertRaises(TypeError,lambda : psin("")) try: from mpmath import mpf, workdps from mpmath import cos as mpcos, sin as mpsin pt = polynomial(real,k_monomial)() self.assertEqual(mpcos(mpf("1.2345")),pcos(mpf("1.2345"))) self.assertEqual(mpcos(mpf("3")),pcos(pt(mpf("3")))) self.assertEqual(mpcos(mpf("-2.456")),pcos(pt(mpf("-2.456")))) self.assertEqual(mpsin(mpf("1.2345")),psin(mpf("1.2345"))) self.assertEqual(mpsin(mpf("3")),psin(pt(mpf("3")))) self.assertEqual(mpsin(mpf("-2.456")),psin(pt(mpf("-2.456")))) with workdps(500): self.assertEqual(mpcos(mpf("1.2345")),pcos(mpf("1.2345"))) self.assertEqual(mpcos(mpf("3")),pcos(pt(mpf("3")))) self.assertEqual(mpcos(mpf("-2.456")),pcos(pt(mpf("-2.456")))) self.assertEqual(mpsin(mpf("1.2345")),psin(mpf("1.2345"))) self.assertEqual(mpsin(mpf("3")),psin(pt(mpf("3")))) self.assertEqual(mpsin(mpf("-2.456")),psin(pt(mpf("-2.456")))) except ImportError: pass self.binomialTest() self.sincosTest() self.evaluateTest() self.subsTest() self.invertTest()
def gammainc(a, x, dps=50, maxterms=10**8): """Compute gammainc exactly like mpmath does but allow for more summands in hypercomb. See mpmath/functions/expintegrals.py#L134 in the mpmath github repository. """ with mp.workdps(dps): z, a, b = mp.mpf(a), mp.mpf(x), mp.mpf(x) G = [z] negb = mp.fneg(b, exact=True) def h(z): T1 = [mp.exp(negb), b, z], [1, z, -1], [], G, [1], [1+z], b return (T1,) res = mp.hypercomb(h, [z], maxterms=maxterms) return mpf2float(res)
def mc_compute_stationary_mpmath(P, precision=17, irreducible=False, ltol=0, utol=None): """ Computes the stationary distributions of Markov matrix P. Parameters ---------- P : array_like(float, ndim=2) A discrete Markov transition matrix. precision : scalar(int), optional(default: 17) Decimal precision in float-point arithemetic with mpmath. mpmath.mp.dps is set to *precision*. irreducible : bool, optional(default: False) Set True if P is known a priori to be irreducible (for any i, j, (P^k)_{ij} > 0 for some k). If True, the eigenvector for the maximum eigenvalue is returned. ltol, utol: scalar(float), optional(default: ltol=0, utol=None) Lower and upper tolerance levels. Find eigenvectors for eigenvalues in [1-ltol, 1+utol] (where [1-ltol, 1+utol] = [1-ltol, +inf) when utol=None). Returns ------- vecs : list of numpy.arrays of mpmath.ctx_mp_python.mpf A list of the eigenvectors of whose eigenvalues in [1-ltol, 1+utol]. Notes ----- mpmath 0.18 or above is required. References ---------- http://mpmath.org/doc/current """ LTOL = ltol # Lower tolerance level if utol is None: # Upper tolerance level UTOL = 'inf' else: UTOL = utol with mp.workdps(precision): # Temporarily change the working precision E, EL = mp.eig(mp.matrix(P), left=True, right=False) # E : a list of length n containing the eigenvalues of A # EL : a matrix whose rows contain the left eigenvectors of A # See: github.com/fredrik-johansson/mpmath/blob/master/mpmath/matrices/eigen.py E, EL = mp.eig_sort(E, EL) # Sorted in a descending order if irreducible: num_eigval_one = 1 else: num_eigval_one = sum( mp.mpf(1) - mp.mpf(LTOL) <= val <= mp.mpf(1) + mp.mpf(UTOL) for val in E ) vecs = [np.array((EL[i, :]/sum(EL[i, :])).tolist()[0]) for i in range(EL.rows-num_eigval_one, EL.rows)] return vecs
a =mpm.mpf (9.999999999) b= mpm.mpf (0.0000000001) print (a, b) c=a+b print (c) deltam=1 with mpm.workdps(mpm.mp.dps+deltam): c=a+b print (c) print (c) #
def runTest(self): import sys from .types import polynomial, short, integer, rational, real, monomial from fractions import Fraction as F # Context for the temporary monkey-patching of type t to return bogus # string bad_str for representation via str. class patch_str(object): def __init__(self,t,bad_str): self.t = t self.bad_str = bad_str def __enter__(self): self.old_str = self.t.__str__ self.t.__str__ = lambda s: self.bad_str def __exit__(self, type, value, traceback): self.t.__str__ = self.old_str # Same for repr. class patch_repr(object): def __init__(self,t,bad_repr): self.t = t self.bad_repr = bad_repr def __enter__(self): self.old_repr = self.t.__repr__ self.t.__repr__ = lambda s: self.bad_repr def __exit__(self, type, value, traceback): self.t.__repr__ = self.old_repr # Start with plain integers. pt = polynomial(integer,monomial(short))() # Use small integers to make it work both on Python 2 and Python 3. self.assertEqual(int,type(pt(4).list[0][0])) self.assertEqual(pt(4).list[0][0],4) self.assertEqual(int,type(pt("x").evaluate({"x":5}))) self.assertEqual(pt("x").evaluate({"x":5}),5) # Specific for Python 2. if sys.version_info[0] == 2: self.assertEqual(int,type(pt(sys.maxint).list[0][0])) self.assertEqual(pt(sys.maxint).list[0][0],sys.maxint) self.assertEqual(long,type((pt(sys.maxint) + 1).list[0][0])) self.assertEqual((pt(sys.maxint) + 1).list[0][0],sys.maxint+1) self.assertEqual(int,type(pt("x").evaluate({"x":sys.maxint}))) self.assertEqual(pt("x").evaluate({"x":sys.maxint}),sys.maxint) self.assertEqual(long,type(pt("x").evaluate({"x":sys.maxint + 1}))) self.assertEqual(pt("x").evaluate({"x":sys.maxint + 1}),sys.maxint + 1) # Now rationals. pt = polynomial(rational,monomial(short))() self.assertEqual(F,type((pt(4)/3).list[0][0])) self.assertEqual((pt(4)/3).list[0][0],F(4,3)) self.assertEqual(F,type(pt("x").evaluate({"x":F(5,6)}))) self.assertEqual(pt("x").evaluate({"x":F(5,6)}),F(5,6)) # NOTE: if we don't go any more through str for the conversion, these types # of tests can go away. with patch_str(F,"boo"): self.assertRaises(ValueError,lambda: pt(F(5,6))) with patch_str(F,"5/0"): self.assertRaises(ZeroDivisionError,lambda: pt(F(5,6))) # Reals, if possible. try: from mpmath import mpf, mp, workdps, binomial as bin, fabs except ImportError: return pt = polynomial(real,monomial(short))() self.assertEqual(mpf,type(pt(4).list[0][0])) self.assertEqual(pt(4).list[0][0],mpf(4)) self.assertEqual(mpf,type(pt("x").evaluate({"x":mpf(5)}))) self.assertEqual(pt("x").evaluate({"x":mpf(5)}),mpf(5)) # Test various types of bad repr. with patch_repr(mpf,"foo"): self.assertRaises(RuntimeError,lambda: pt(mpf(5))) with patch_repr(mpf,"'1.23445"): self.assertRaises(RuntimeError,lambda: pt(mpf(5))) with patch_repr(mpf,"'foobar'"): self.assertRaises(ValueError,lambda: pt(mpf(5))) # Check the handling of the precision. from .math import binomial # Original number of decimal digits. orig_dps = mp.dps tmp = binomial(mpf(5.1),mpf(3.2)) self.assertEqual(tmp.context.dps,orig_dps) with workdps(100): # Check that the precision is maintained on output # and that the values computed with our implementation and # mpmath are close. tmp = binomial(mpf(5.1),mpf(3.2)) self.assertEqual(tmp.context.dps,100) self.assert_(fabs(tmp - bin(mpf(5.1),mpf(3.2))) < mpf('5e-100')) # This will create a coefficient with dps equal to the current value. tmp = 3*pt('x') self.assertEqual(tmp.evaluate({'x':mpf(1)}).context.dps,orig_dps) self.assertEqual(tmp.list[0][0].context.dps,orig_dps) with workdps(100): # When we extract the coefficient with increased temporary precision, we get # an object with increased precision. self.assertEqual(tmp.list[0][0].context.dps,100)
def test_sin(self): with mp.workdps(30): sincoeffs = mp.taylor(mp.sin, 0, 10) asincoeffs = mp.taylor(mp.asin, 0, 10) invsincoeffs = lagrange_inversion(sincoeffs) mp_assert_allclose(invsincoeffs, asincoeffs, atol=1e-30)
def test_log(self): with mp.workdps(30): logcoeffs = mp.taylor(lambda x: mp.log(1 + x), 0, 10) expcoeffs = mp.taylor(lambda x: mp.exp(x) - 1, 0, 10) invlogcoeffs = lagrange_inversion(logcoeffs) mp_assert_allclose(invlogcoeffs, expcoeffs)
def stirling_series(N): with mpmath.workdps(100): coeffs = [mpmath.bernoulli(2*n)/(2*n*(2*n - 1)) for n in range(1, N + 1)] return coeffs
def stirling_series(N): coeffs = [] with mpmath.workdps(100): for n in range(1, N + 1): coeffs.append(mpmath.bernoulli(2 * n) / (2 * n * (2 * n - 1))) return coeffs
def extraction_Diode_In_mpmath(): """ пробуем экстрагировать коэффициенты из модели диода коэффициенты модели: Ток утечки Is, коэффициент неидеальности N, омическое сопротивление, параллельное диоду R входные параметры: напряжение, приложенное источником к системе резистор-диод +-----------|||||---------->|--------- - Резистор подключен до диода :return: """ btrue=[mpm.mpf('1.238e-14'), mpm.mpf('1.3'), mpm.mpf('10')] c=None global FT funcf=solver_Diode_In_mpmath jacf = jac_Diode_In_mpmath #теперь попробуем сделать эксперимент. Ve=np.array([ [1e-7] ] ) bstart=[mpm.mpf('1.0e-14'), mpm.mpf('1.0'), mpm.mpf('9')] bend=[mpm.mpf('1.5e-14'), mpm.mpf('1.5'), mpm.mpf('14')] #binit=[mpm.mpf('1.1e-14'), mpm.mpf('1.1'), mpm.mpf('11')] binit=mpm.matrix([['1.1e-14', '1.1', '11.1']]).T xstart=[mpm.mpf('0.0001')] xend=[mpm.mpf('2')] N=100 NAprior=20 unifplan = o_pmpm.makeUniformExpPlan(xstart, xend, N) unifmeasdata = o_pmpm.makeMeasAccToPlan_lognorm(funcf, unifplan, btrue, c, Ve) #print (unifmeasdata[0]['y'][0]) import Fianora.Fianora_static_functions as f_sf for dps in [20,10,7]: with f_sf.Profiler(): print() print ('mantissa', dps) gknux = o_empm.grandCountGN_UltraX1_mpmath_mantissa(funcf, jacf, unifmeasdata, binit,c, NSIG=dps,implicit=True, verbose=False, mantissa=[dps]) with mpm.workdps(dps): print ('b', gknux[0]) print ('numiter', gknux[1]) print ('log', gknux[2]) print ('Sk', gknux[4]) for f**k in range (10): with f_sf.Profiler(): print() print ('mantissa', 'variable') gknux = o_empm.grandCountGN_UltraX1_mpmath_mantissa(funcf, jacf, unifmeasdata, binit,c, NSIG=7,implicit=True, verbose=False, mantissa=[4,5,6,7]) with mpm.workdps(dps): print ('b', gknux[0]) print ('numiter', gknux[1]) print ('log', gknux[2]) print ('Sk', gknux[4])
def grandCountGN_UltraX1_mpmath (funcf, jacf, measdata:list, binit:list, c, NSIG=3, implicit=False, verbose=False): """ Производит оценку коэффициентов по методу Гаусса-Ньютона с переменным шагом В стандартный поток вывода выводит отладочную информацию по каждой итерации :param funcf callable функция, параметры по формату x,b,c, на выходе вектор (pure Python) :param jacf callable функция, параметры по формату x,b,c,y, на выходе матрица mpmath.matrix :param measdata:list список словарей экспериментальных данных [{'x': [] 'y':[])},{'x': [] 'y':[])}] :param binit:list начальное приближение b :param c словарь дополнительных постоянных :param NSIG=3 точность (кол-во знаков после запятой) :param sign - если 1, то b=b+deltab*mu, иначе b=b-deltab*mu. При неявной функции надо ставить sign=0 :returns b, numiter, log - вектор оценки коэффициентов, число итераций, сообщения РАБОЧАЯ GEPRUFT! """ Sklist=list() b=binit log="" numiter=0 condition=True def throwError (msg): #global b, numiter, log, Sklist, Sk log+=msg return b, numiter, log, Sklist, Sk while (condition): m=len(b) #число коэффициентов #G=np.zeros((m,m)) G=mpm.matrix(m) #B5=mpm.matrix(1,m) B5=None bpriv=copy.copy(b) Sk=mpm.mpf(0) for point in measdata: jac=jacf(point['x'],b,c,point['y']) if jac is None: throwError ("Jac is None") #G+=np.dot(jac.T,jac) G+=jac.T*jac #dif=np.array(point['y'])-np.array(funcf(point['x'],b,c)) fxbc=funcf(point['x'],b,c) if fxbc is None: throwError ("Funcf is None") dif=point['y']-fxbc if B5 is None: #if B5==mpm.matrix(1,m): B5=dif*jac else: B5+=dif*jac Sk+=(dif.T*dif)[0] try: with mpm.workdps(30): deltab=(G**-1)*B5.T except BaseException as e: print('G=',G) print('B5=',B5) throwError('Error in G:'+e.__str__()) #mu counting mu=mpm.mpf(4) cond2=True it=0 while (cond2): Skmu=mpm.mpf(0) mu/=mpm.mpf(2) for point in measdata: dif=point['y']-funcf(point['x'],b-deltab*mu,c) if implicit else point['y']-funcf(point['x'],b+deltab*mu,c) Skmu+=(dif.T*dif)[0] it+=1 if (it>100): log+="Mu counting: break due to max number of iteration exceed" break cond2=Skmu>Sk b=b-deltab*mu if implicit else b+deltab*mu Sklist.append(Sk) if verbose: print ("Sk:",Sk) print ("Iteration {0} mu={1} delta={2} deltamu={3} resb={4}".format(numiter, mu, deltab, deltab*mu, b)) numiter+=1 condition=False for i in range (len(b)): if mpm.fabs ((b[i]-bpriv[i])/bpriv[i])>math.pow(10,-1*NSIG): condition=True if numiter>500: #max number of iterations throwError("Break due to max number of iteration exceed") return b, numiter, log, Sklist, Sk