def phi2(x0, *, dps): # (exp(x) - 1 - x) / (x * x), |x| > 1e-32 -> dps > 40 with mp.workdps(dps): y = mp.matrix([ mp.fdiv(mp.fsub(mp.expm1(x), x), mp.fmul(x, x)) if x != 0.0 else mpf(1) / mpf(2) for x in x0 ]) return np.array(y.tolist(), dtype=x0.dtype)[:, 0]
def transform_domains(points, from_domain, to_domain, use_mp=False, dps=None): r"""Linearly transform a set of points between two intervals. The points are transformed bijectively, linearly, and orientation preserving. The values are guaranteed to lie in the target domain, i.e. any numerical noise will not lead to points lying slightly outside after the transformation. @param points Iterable of all points to transform. Points must be plain values, i.e. no vectors. @param from_domain 2-tuple/list indicating the interval the points are currently living in. @param to_domain 2-tuple/list indicating the target interval the returned points should live in. @param use_mp Whether to use arbitrary precision math operations (`True`) or faster floating point precision operations (`False`, default). @param dps Number of decimal places to use in case of `use_mp==True`. @return A `list` of the transformed points. """ with mp.workdps(dps or mp.dps): fl = mp.mpf if use_mp else float a, b = map(fl, to_domain) c, d = map(fl, from_domain) scale = (b - a) / (d - c) trans = a - (b - a) * c / (d - c) return [min(b, max(a, scale * p + trans)) for p in points]
def test_mpmath(self): with mp.workdps(30): a = mp.mpf('1e7') + mp.mpf('1e-20') b = mp.mpf('1e7') self.assertTrue(isclose(a, a, rel_tol=0, abs_tol=0, use_mp=True)) self.assertFalse(isclose(a, b, use_mp=True)) with mp.workdps(26): self.assertTrue(isclose(a, b, use_mp=True)) self.assertTrue( isclose(a, b, rel_tol=1e-26, abs_tol=0, use_mp=True)) self.assertFalse( isclose(a, b, rel_tol=1e-28, abs_tol=0, use_mp=True)) self.assertTrue( isclose(a, b, rel_tol=0, abs_tol=1e-19, use_mp=True)) self.assertFalse( isclose(a, b, rel_tol=0, abs_tol=1e-21, use_mp=True))
def test_complex(self): cheby = Cheby([0]*4, domain=(10, 20)) ev = cheby.evaluator(use_mp=True) with mp.workdps(20): self.assertIsNot(type(ev.diff(10, 1)), mp.mpc) self.assertIsNot(type(ev.diff(20, 1)), mp.mpc) self.assertIsNot(type(ev.diff(10, 2)), mp.mpc) self.assertIsNot(type(ev.diff(20, 2)), mp.mpc)
def phi3(x0, *, dps): # (epx(x)-1-x-0.5*x*x)/(x*x*x) , |x| > 1e-32 -> dps > 100 with mp.workdps(dps): y = mp.matrix([ mp.fdiv( mp.fsub(mp.fsub(mp.expm1(x), x), mp.fmul('0.5', mp.fmul( x, x))), mp.power(x, '3')) if x != 0.0 else mpf(1) / mpf(6) for x in x0 ]) return np.array(y.tolist(), dtype=x0.dtype)[:, 0]
def test_division(self): expr = DivisionExpression( SimpleSinExpression(), OffsetExpression(SimpleCoshExpression(), 2), ) with mp.workdps(30): f = expr.evaluator(use_mp=True) space = mp.linspace(0, mp.pi, 10) for n in range(1, 5): self.assertListAlmostEqual( [f.diff(x, n) for x in space], [mp.diff(f, x, n) for x in space], delta=1e-28, )
def test_planar_y_decoder_coset_probability(prob_dist, pauli, expected_probability_text): with mp.workdps(50): expected_probability = mp.mpf(expected_probability_text) # calculate coset probabilities y_stabilizers = PlanarYDecoder._y_stabilizers(pauli.code) coset = y_stabilizers ^ pauli.to_bsf( ) # numpy broadcasting applies recovery to all stabilizers coset_probability = PlanarYDecoder._coset_probability(prob_dist, coset) print(repr(coset_probability), repr(expected_probability)) assert _is_close(expected_probability, coset_probability, rtol=1e-50, atol=0), ('Coset probability not as expected')
def _ode1(self, num, atol, use_mp=False, dps=None, mat_solver='scipy.solve', eq_generator=False): # Solve the ODE # f'' - a b sin(b x) f' = a b^2 cos(b x) f # with an exact solution # f(x) = exp(-a cos(b x)). # The domain is chosen to avoid symmetries and to test non-trivial # boundary conditions. This test is designed to be able to perform # fast tests with floating point precision or slow tests with mpmath # arbitrary precision arithmetics. All constants are coded such that # arbitrary precision tests can succeed with an accuracy of up to (for # example): # atol = 2e-39 with num=160, dps=50 fl = mp.mpf if use_mp else float ctx = mp if use_mp else np sin, cos, exp = ctx.sin, ctx.cos, ctx.exp with mp.workdps(dps or mp.dps): a, b = map(fl, (2, 6)) domain = lmap(fl, (0.5, 2)) exact = lambda x: exp(-a * cos(b * x)) v1 = fl( mp.mpf('7.2426342955875784959555289115078253477587230131548')) v2 = fl( mp.mpf('0.18494294304163188136560483509304192452611801175781')) if eq_generator: eq = lambda pts: ((-a * b**2 * np.cos(b * pts), -a * b * np. sin(b * pts), 1), 0) else: eq = ((lambda x: -a * b**2 * cos(b * x), lambda x: -a * b * sin(b * x), 1), 0) sol = ndsolve(eq=eq, basis=ChebyBasis(domain=domain, num=num), boundary_conditions=( DirichletCondition(x=domain[0], value=v1), DirichletCondition(x=domain[1], value=v2), ), use_mp=use_mp, mat_solver=mat_solver) f = sol.evaluator(use_mp) pts = np.linspace(float(sol.domain[0]), float(sol.domain[1]), 50) max_err = max(map(lambda x: abs(exact(x) - f(x)), pts)) self.assertLessEqual(max_err, atol)
def test_planar_y_decoder_coset_probability_performance(): print() with mp.workdps(50): n_run = 20 code = PlanarCode(16, 16) # 16, 16 prob_dist = (0.9, 0.0, 0.1, 0.0) # preload stabilizer cache PlanarYDecoder._y_stabilizers(code) # time runs start_time = time.time() for _ in range(n_run): coset = PlanarYDecoder._y_stabilizers(code) coset_probability = PlanarYDecoder._coset_probability( prob_dist, coset) print(repr(coset_probability)) run_time = time.time() - start_time print('run_time = {}'.format(run_time)) # test to avoid regression assert run_time < 7 # 5.423123121261597
def _test_accuracy(self, use_mp): ctx = mp if use_mp else math convert = mp.mpf if use_mp else float pi = ctx.pi sin, cos, exp = ctx.sin, ctx.cos, ctx.exp with mp.workdps(50): five = convert(5) # 2pi periodic, antisym w.r.t. 0, not sym w.r.t. pi/2 f = lambda x: exp(cos(x)) * sin(x)**2 * sin(five * x) f.domain = (0, pi) tol = 1e-30 if use_mp else 4e-15 self._check_convergence(f, num=30, lobatto=True, use_mp=use_mp, tol=tol) self._check_convergence(f, num=30, lobatto=False, use_mp=use_mp, tol=tol)
def gauss(N, dps=15): '''Calculate 1D Gaussian quadrature points at arbitrary precision. Re-implementation of 'gauss.m', from Trefethen's Spectral Methods in MATLAB''' with mp.workdps(dps): beta = mpmath.matrix(N - 1, 1) for i in range(1, N): beta[i - 1] = 0.5 / (1 - (mpmath.mpf(2 * i)**-2))**0.5 T = mpmath.matrix(N, N) for i in range(N - 1): T[i + 1, i] = beta[i] T[i, i + 1] = beta[i] (eigval, eigvec) = mpmath.eig(T) # Sort eigenvalues zl = zip(eigval, range(len(eigval))) zl.sort() x = np.array([ee[0] for ee in zl]) w = np.array([2 * (eigvec[0, ee[1]]**2) for ee in zl]) if (dps <= 15): x = x.astype('double') w = w.astype('double') return (x, w)
def test_mat(self): self._mat(use_mp=False, tol=1e-12) with mp.workdps(30): self._mat(use_mp=True, tol=1e-25)
def phi0(x0, *, dps): # exp(x), |x| > 1e-32 -> dps > 16 with mp.workdps(dps): y = mp.matrix([mp.exp(x) for x in x0]) return np.array(y.tolist(), dtype=x0.dtype)[:, 0]
def phi1(x0, *, dps): # (exp(x) - 1)/x, |x| > 1e-32 -> dps > 16 with mp.workdps(dps): y = mp.matrix( [mp.fdiv(mp.expm1(x), x) if x != 0.0 else mpf('1') for x in x0]) return np.array(y.tolist(), dtype=x0.dtype)[:, 0]
from sympy import isprime from mpmath import mp decimalPlaces = 100 with mp.workdps(decimalPlaces): estring = str(mp.e).replace('.', '') for i in range(0, (decimalPlaces - 12)): t = int(estring[i:i + 12]) if (isprime(t)): print(t, 'at i =', i) break