def __eq__(a, b): if a is b: return True try: if type(a) != alg: a = alg(a) if type(b) != alg: b = alg(b) except NotImplementedError: return NotImplemented if a._minpoly != b._minpoly: return False # rationals have a unique root if a._minpoly.degree() == 1: return True prec = ctx.prec ctx.prec = 64 try: while 1: ar = a.enclosure() br = b.enclosure() if not acb(ar).overlaps(br): return False z = acb(ar).union(br) z2 = alg._validate_root_enclosure(a._minpoly, z) if z2 is not None: return True ctx.prec *= 2 finally: ctx.prec = prec
def figure3(): global legends plt.clf() ax = plt.gca() legends = [] ax.grid(True) k = 1 R = -arb(-1).exp() ploterr(ax, lambda X: acb(R, X).lambertw(k).real, [-4, 4], [-5, 1], 0.5, color="lightblue", label="$h = 0.5$", alpha=0.7) ploterr(ax, lambda X: acb(R, X).lambertw(k).real, [-4, 4], [-5, 1], 0.1, color="blue", label="$h = 0.1$", alpha=0.5) ploterr(ax, lambda X: acb(R, X).lambertw(k).real, [-4, 4], [-5, 1], 0.01, color="black", label="$h = 0.01$", alpha=1.0) plt.xlabel("$y$") plt.ylabel("$\Re(W_{%ld}(-1/e+yi))$" % k) ax.legend(handles=legends, loc="upper right") import matplotlib fig = matplotlib.pyplot.gcf() fig.set_size_inches(8, 5) fig.savefig('test2.png', bbox_inches="tight") fig.savefig('branchplot2.pdf', bbox_inches="tight")
def schur_mp_to_arb( M): """Computes the Schur decomposition of the matrix M The result is computed twice at different precisions using mpmath's schur function. Then the radius of the error interval is estimated to be half the difference beetween the two results. """ # Conversion de la matrice en mpmath.matrix A = convert_mpmath_mat( M) # Calcul en précision actuelle Q1, R1 = mpmath.schur( A) # Calcul en précision double mpmath.mp.prec *=2 Q2, R2 = mpmath.schur( A) # Création de la matrice arb m, n = M.shape lq = [] lr = [] for i in range(m): for j in range(n): lq.append( acb( Q1[i,j].real, Q1[i,j].imag ) ) lr.append( acb( R1[i,j].real, R1[i,j].imag ) ) Q = acb_mat( m, n, lq) R = acb_mat( m, n, lr) mpmath.mp.prec /=2 return( Q, R)
def figure1(): global legends plt.clf() ax = plt.gca() legends = [] ax.grid(True) R = float(-arb(-1).exp()) k = 0 plotadaptive(ax, lambda X: acb(X).lambertw(k).real, [R, 3], [-3, 2], 0.5, color="lightblue", label="$W_{0}(x), \\varepsilon = 0.5$", alpha=0.6) plotadaptive(ax, lambda X: acb(X).lambertw(k).real, [R, 3], [-3, 2], 0.1, color="blue", label="$W_{0}(x), \\varepsilon = 0.1$", alpha=0.7) plotadaptive(ax, lambda X: acb(X).lambertw(k).real, [R, 3], [-3, 2], 0.01, color="black", label="$W_{0}(x), \\varepsilon = 0.01$", alpha=1.0) k = -1 plotadaptive(ax, lambda X: acb(X).lambertw(k).real, [R, 0], [-3, 2], 0.5, color="orange", label="$W_{-1}(x), \\varepsilon = 0.5$", alpha=0.4) plotadaptive(ax, lambda X: acb(X).lambertw(k).real, [R, 0], [-3, 2], 0.1, color="red", label="$W_{-1}(x), \\varepsilon = 0.1$", alpha=0.8) #plotadaptive(ax, lambda X: acb(X).lambertw(k).real, [R, 0], [-3,2], 0.01, color="black", label="$W_{-1}(x), \\varepsilon = 0.01$", alpha=1.0) ax.set_xlim([-1, 3]) ax.set_ylim([-4, 2]) ax.axhline(y=-1, color="gray") ax.axvline(x=R, color="gray") plt.xticks([-1, R, 0, 1, 2, 3], ["$-1$", "$-1/e$", "$0$", "$1$", "$2$", "$3$"]) plt.xlabel("$x$") plt.ylabel("$W_k(x)$") ax.legend(handles=legends, loc="best") import matplotlib fig = matplotlib.pyplot.gcf() fig.set_size_inches(8, 5) fig.savefig('test1aa.png', bbox_inches="tight") fig.savefig('branchplot1.pdf', bbox_inches="tight")
def root(self, n): assert n >= 0 if n == 0: raise ZeroDivisionError if n == 1: return self F = self._minpoly d = F.degree() check_degree_limit(d * n) H = [0] * (d * n + 1) H[::n] = list(F) H = fmpz_poly(H) c, factors = H.factor() prec = 64 orig_prec = ctx.prec try: while 1: ctx.prec = prec x = self.enclosure(pretty=True) z = acb(x).root(n) #if not z.imag == 0: # eps = arb(0, z.rad()) # z += acb(eps,eps) maybe_root = [ fac for fac, mult in factors if fac(z).contains(0) ] if len(maybe_root) == 1: fac = maybe_root[0] z2 = alg._validate_root_enclosure(fac, z) if z2 is not None: return alg(_minpoly=fac, _enclosure=z2) prec *= 2 finally: ctx.prec = orig_prec
def neval(expr, digits=20, **kwargs): from flint import ctx, acb assert digits >= 1 orig = ctx.prec target = digits * 3.33 + 5 wp = digits * 3.33 + 30 maxprec = wp * 10 + 4000 evaluator = ArbNumericalEvaluation() try: while 1: ctx.prec = wp try: v = evaluator.eval(expr) except ArbFiniteError: v = acb("nan") if v.rel_accuracy_bits() >= target: break wp *= 2 if wp > maxprec: #raise ValueError("failed to converge") break finally: ctx.prec = orig if not v.is_finite(): raise ValueError("failed to converge to a finite value") if isinstance(v, acb) and v.imag == 0: v = v.real if kwargs.get("as_arb"): return v else: return arb_as_fungrim(v, digits)
def _validate_root_enclosure(poly, x): """ Given x known to be an enclosure of *at least one root of poly*, certifies that the enclosure contains a unique root, and in that case returns a new (possibly improved) enclosure for the same root. Returns None if uniqueness cannot be certified. """ if x.is_exact() or poly.degree() == 1: return x orig = ctx.prec try: acc = x.rel_accuracy_bits() ctx.prec = max(acc, 32) * 2 + 10 pure_real = x.imag == 0 # slightly inflate enclosure - needed e.g. in case of # complex interval with one very narrow real/imaginary part eps = x.rad() * (1 / 16.) if pure_real: x += arb(0, eps) else: x += acb(arb(0, eps), arb(0, eps)) # interval Newton steps xmid = x.mid() y = xmid - poly(xmid) / poly.derivative()(x) if pure_real: x = x.real y = y.real if x.contains_interior(y): return y return None finally: ctx.prec = orig
def test_guess(self): assert alg.guess(arb(123) / 3789, 1) == alg(123) / 3789 assert alg.guess(arb(5) + acb(2).sqrt() * 1j, 2) == alg(5) + alg(2).sqrt() * alg.i() assert alg.guess(arb(5) / 64 + acb(0, 37) / 256, 2) == alg(5) / 64 + (alg(37) / 256) * alg.i() orig = ctx.prec try: ctx.dps = 200 assert alg.guess(arb(2).root(6) + arb(3).root(5), 30) == alg(2).root(6) + alg(3).root(5) finally: ctx.prec = orig assert alg.guess(arb("3.1415926535897932 +/- 1e-5"), 1, check=False) == alg(22) / 7 assert alg.guess(arb("3.1415926535897932 +/- 1e-8"), 1, check=False) == alg(355) / 113
def pow(self, n): if self.is_rational(): c0 = self._minpoly[0] c1 = self._minpoly[1] if abs(n) > 2: check_bits_limit(c0.height_bits() * abs(n)) check_bits_limit(c1.height_bits() * abs(n)) if n >= 0: return alg(fmpq(c0**n) / (-c1)**n) else: return alg((-c1)**(-n) / fmpq(c0**(-n))) if n == 0: return alg(1) if n == 1: return self if n < 0: return (1 / self).pow(-n) # fast detection of perfect powers pol, d = self.minpoly().deflation() if d % n == 0: # todo: is factoring needed here? H = list(self.minpoly()) H = H[::n] H = fmpz_poly(H) c, factors = H.factor() prec = 64 orig_prec = ctx.prec try: while 1: ctx.prec = prec x = self.enclosure(pretty=True) z = acb(x)**n maybe_root = [ fac for fac, mult in factors if fac(z).contains(0) ] if len(maybe_root) == 1: fac = maybe_root[0] z2 = alg._validate_root_enclosure(fac, z) if z2 is not None: return alg(_minpoly=fac, _enclosure=z2) prec *= 2 finally: ctx.prec = orig_prec if n == 2: return self * self v = self.pow(n // 2) v = v * v if n % 2: v *= self return v
def gaussian_integer(a, b): if b == 0: return alg(a) a = fmpz(a) b = fmpz(b) orig = ctx.prec ctx.prec = 64 try: z = acb(a, b) finally: ctx.prec = orig res = alg(_minpoly=fmpz_poly([a**2 + b**2, -2 * a, 1]), _enclosure=z) return res
def B(t): Z2 = (1.25 * 1.25) * acb(2 * t).exp_pi_i() Z = (Z2 - 2) / (2 * acb(1).exp()) t = float(t) print t if t < 0.25: W = Z.lambertw() elif t < 0.75: W = Z.lambertw(branch=0, flags=2) elif t < 0.9: W = Z.lambertw(branch=1) elif t < 1.1: W = Z.lambertw(branch=-1, flags=4) elif t < 1.25: W = Z.lambertw(branch=-1) elif t < 1.75: W = Z.lambertw(branch=-1, flags=2) else: W = Z.lambertw() res = 2 + W if not abs(res) < 2: return indet # raise ValueError return res
def exp_two_pi_i(x): x = fmpq(x) check_degree_limit(10 * x.q) poly = fmpz_poly.cyclotomic(x.q) prec = ctx.prec ctx.prec = 64 try: while 1: a = arb.cos_pi_fmpq(2 * x) b = arb.sin_pi_fmpq(2 * x) z = acb(a, b) z2 = alg._validate_root_enclosure(poly, z) if z2 is not None: return alg(_minpoly=poly, _enclosure=z2) ctx.prec *= 2 finally: ctx.prec = prec
def plot_elliptic(tau, filename): xrayplot( lambda z: complex(acb(z).elliptic_p(tau)), (-1.5, 1.5), (-1.5, 1.5), 400, filename, xout=0.1, yout=0.1, xtks=([-1, 0, 1], ), ytks=([-1, 0, 1], ), decorations=lambda: fill([0.0, 1.0, tau.real + 1.0, tau.real, 0.0], [0.0, 0.0, tau.imag, tau.imag, 0.0], facecolor=highlightcolor, edgecolor=highlightbordercolor, alpha=0.5, linewidth=0.5, zorder=2))
def test_fmpz_poly(): Z = flint.fmpz_poly assert Z() == Z([]) assert Z() == Z([0]) assert Z() == Z([0, flint.fmpz(0), 0]) assert Z() == Z([0, 0, 0]) assert Z() != Z([1]) assert Z([1]) == Z([1]) assert Z([1]) == Z([flint.fmpz(1)]) assert Z(Z([1, 2])) == Z([1, 2]) for ztype in [int, long, flint.fmpz]: assert Z([1, 2, 3]) + ztype(5) == Z([6, 2, 3]) assert ztype(5) + Z([1, 2, 3]) == Z([6, 2, 3]) assert Z([1, 2, 3]) - ztype(5) == Z([-4, 2, 3]) assert ztype(5) - Z([1, 2, 3]) == Z([4, -2, -3]) assert Z([1, 2, 3]) * ztype(5) == Z([5, 10, 15]) assert ztype(5) * Z([1, 2, 3]) == Z([5, 10, 15]) assert Z([11, 6, 2]) // ztype(5) == Z([2, 1]) assert ztype(5) // Z([-2]) == Z([-3]) assert ztype(5) // Z([1, 2]) == 0 assert Z([11, 6, 2]) % ztype(5) == Z([1, 1, 2]) assert ztype(5) % Z([-2]) == Z([-1]) assert ztype(5) % Z([1, 2]) == 5 assert Z([1, 2, 3])**ztype(0) == 1 assert Z([1, 2, 3])**ztype(1) == Z([1, 2, 3]) assert Z([1, 2, 3])**ztype(2) == Z([1, 4, 10, 12, 9]) assert +Z([1, 2]) == Z([1, 2]) assert -Z([1, 2]) == Z([-1, -2]) assert raises(lambda: Z([1, 2, 3])**-1, (OverflowError, ValueError)) assert raises(lambda: Z([1, 2, 3])**Z([1, 2]), TypeError) assert raises(lambda: Z([1, 2]) // Z([]), ZeroDivisionError) assert raises(lambda: Z([]) // Z([]), ZeroDivisionError) assert raises(lambda: Z([1, 2]) % Z([]), ZeroDivisionError) assert raises(lambda: divmod(Z([1, 2]), Z([])), ZeroDivisionError) assert Z([]).degree() == -1 assert Z([]).length() == 0 p = Z([1, 2]) assert p.length() == 2 assert p.degree() == 1 assert p[0] == 1 assert p[1] == 2 assert p[2] == 0 assert p[-1] == 0 assert raises(lambda: p.__setitem__(-1, 1), ValueError) p[0] = 3 assert p[0] == 3 p[4] = 7 assert p.degree() == 4 assert p[4] == 7 assert p[3] == 0 p[4] = 0 assert p.degree() == 1 assert p.coeffs() == [3, 2] assert Z([]).coeffs() == [] assert bool(Z([])) == False assert bool(Z([1])) == True ctx.pretty = False assert repr(Z([1, 2])) == "fmpz_poly([1, 2])" ctx.pretty = True assert str(Z([1, 2])) == "2*x + 1" p = Z([3, 4, 5]) assert p(2) == 31 assert p(flint.fmpq(2, 3)) == flint.fmpq(71, 9) assert p(Z([1, -1])) == Z([12, -14, 5]) assert p(flint.fmpq_poly([2, 3], 5)) == flint.fmpq_poly([27, 24, 9], 5) assert p(flint.arb("1.1")).overlaps(flint.arb("13.45")) assert p(flint.acb("1.1", "1.2")).overlaps(flint.acb("6.25", "18.00"))
def modj(z): if z.imag < 0.03: return 0.0 return complex(acb(z).modular_j()) / 1728.0
def modlambda(tau): if tau.imag < 0.01: return 0.0 return complex(acb(tau).modular_lambda())
def ellzeta(z, tau): return complex(acb(z).elliptic_zeta(tau))
def enclosure(self, pretty=False): if self.degree() == 1: c0 = self._minpoly[0] c1 = self._minpoly[1] return arb(c0) / (-c1) elif pretty: z = self.enclosure() re = z.real im = z.imag # detect zero real/imag part if z.real.contains(0): if self.real_sgn() == 0: re = arb(0) if z.imag.contains(0): if self.imag_sgn() == 0: im = arb(0) # detect exact (dyadic) real/imag parts # fixme: extracting real and imag parts and checking if # they are exact can be slow at high degree; this is a workaround # until that operation can be improved scale = fmpz(2)**max(10, ctx.prec - 20) if not re.is_exact() and (re * scale).unique_fmpz() is not None: n = (re * scale).unique_fmpz() b = self - fmpq(n, scale) if b.real_sgn() == 0: re = arb(fmpq(n, scale)) if not im.is_exact() and (im * scale).unique_fmpz() is not None: n = (im * scale).unique_fmpz() b = self - fmpq(n, scale) * alg.i() if b.imag_sgn() == 0: im = arb(fmpq(n, scale)) if im == 0: return arb(re) else: return acb(re, im) else: orig_prec = ctx.prec x = self._enclosure if x.rel_accuracy_bits() >= orig_prec - 2: return x # Try interval newton refinement f = self._minpoly g = self._minpoly.derivative() try: ctx.prec = max(x.rel_accuracy_bits(), 32) + 10 for step in range(40): ctx.prec *= 2 if ctx.prec > 1000000: raise ValueError("excessive precision") # print("root-refinement prec", ctx.prec) # print(x.mid().str(10), x.rad().str(10)) xmid = x.mid() y = xmid - f(xmid) / g(x) if y.rel_accuracy_bits() >= 1.1 * orig_prec: self._enclosure = y return y if y.rel_accuracy_bits() < 1.5 * x.rel_accuracy_bits() + 1: # print("refinement failed -- recomputing roots") roots = self._minpoly.roots() near = [r for (r, mult) in roots if acb(r).overlaps(x)] if len(near) == 1: y = near[0] if y.rel_accuracy_bits() >= 1.1 * orig_prec: self._enclosure = y return y x = y raise ValueError("root refinement did not converge") finally: ctx.prec = orig_prec
for j, each_ka in enumerate(ka_values): k_value = each_ka / a parameters = {'k': k_value, 'a': a} _, piston_infbaf_D[:, j] = piston_infbaf.piston_in_infinite_baffle_directivity( angles, parameters) #%% # Now calculate the piston in sphere # Remember this particular example uses the python-FLINT implementation to speed # things up. Check the other examples to see how to generate the piston in a sphere # using the mpmath implementation. pistonsphere_directivity = piston_sphere.piston_in_sphere_directivity angles_as_acb = [acb(each) for each in angles] R = acb(0.1) # radius of a sphere alpha = acb.pi() / acb(6) a_value = R * acb.sin(alpha) piston_in_sphere_D = np.zeros(piston_infbaf_D.shape) for j, each_ka in enumerate(ka_values): k_value = acb(each_ka) / a_value parameters = {'k': k_value, 'a': a_value, 'R': R, 'alpha': alpha} A_n, piston_in_sphere_D[:, j] = pistonsphere_directivity( angles_as_acb, parameters) #%% # Now calculate oscillating cap of a sphere
def eval_inner(self, expr, **kwargs): flint = self.flint arb = self.flint.arb acb = self.flint.acb if expr.is_atom(): if expr.is_integer(): return arb(expr._integer) if expr.is_symbol(): if expr == ConstPi: return arb.pi() if expr == ConstE: return arb.const_e() if expr == ConstGamma: return arb.const_euler() if expr == ConstI: return acb(0, 1) if expr == GoldenRatio: return (1 + arb(5).sqrt()) / 2 if expr == ConstCatalan: return arb.const_catalan() stack = kwargs.get("symbol_stack") if stack is not None: for (sym, val) in reversed(stack): if sym == expr: return val raise NotImplementedError head = expr.head() args = expr.args() if head == Mul: if len(args) == 0: return arb(1) x = self.eval(args[0], **kwargs) for y in args[1:]: y = self.eval(y, **kwargs) x *= y return x if head == Add: if len(args) == 0: return arb(0) x = self.eval(args[0], **kwargs) for y in args[1:]: y = self.eval(y, **kwargs) x += y return x if head == Neg: assert len(args) == 1 x = self.eval(args[0], **kwargs) return (-x) if head == Sub: assert len(args) == 2 x = self.eval(args[0], **kwargs) y = self.eval(args[1], **kwargs) return x - y if head == Div: assert len(args) == 2 x = self.eval(args[0], **kwargs) y = self.eval(args[1], **kwargs) if y != 0: return x / y raise ArbFiniteError if head == Pow: assert len(args) == 2 x = self.eval(args[0], **kwargs) y = self.eval(args[1], **kwargs) v = x**y if v.is_finite(): return v else: if isinstance(x, arb) and isinstance(y, arb): v = acb(x)**acb(y) if v.is_finite(): return v raise ArbFiniteError if head == Abs: assert len(args) == 1 x = self.eval(args[0], **kwargs) return abs(x) if head == Re: assert len(args) == 1 v = self.eval(args[0], **kwargs) if v.is_finite(): if isinstance(v, arb): return v else: return v.real raise ArbFiniteError if head == Im: assert len(args) == 1 v = self.eval(args[0], **kwargs) if v.is_finite(): if isinstance(v, arb): return arb(0) else: return v.imag raise ArbFiniteError if head in (Parentheses, Brackets, Braces): assert len(args) == 1 return self.eval(args[0], **kwargs) if head in function_arb_method_table: method = function_arb_method_table[head] assert len(args) == 1 x = self.eval(args[0], **kwargs) v = getattr(x, method)() if v.is_finite(): return v # possible complex extension if isinstance(x, arb): x = acb(x) v = getattr(x, method)() if v.is_finite(): return v raise ArbFiniteError if head in function_acb_method_table: method = function_acb_method_table[head] assert len(args) == 1 x = self.eval(args[0], **kwargs) v = getattr(x, method)() if v.is_finite(): return v x = acb(x) v = getattr(x, method)() if v.is_finite(): return v raise ArbFiniteError if head in (Hypergeometric1F1, Hypergeometric1F1Regularized): assert len(args) == 3 a, b, z = [self.eval(arg, **kwargs) for arg in args] z = acb(z) v = z.hypgeom_1f1( a, b, regularized=(head == Hypergeometric1F1Regularized)) if v.is_finite(): return v raise ArbFiniteError if head in (Hypergeometric2F1, Hypergeometric2F1Regularized): assert len(args) == 4 a, b, c, z = [self.eval(arg, **kwargs) for arg in args] z = acb(z) v = z.hypgeom_2f1( a, b, c, regularized=(head == Hypergeometric2F1Regularized)) if v.is_finite(): return v raise ArbFiniteError if head == JacobiTheta: if len(args) == 3: j, z, tau = args r = 0 else: j, z, tau, r = args if not (r.is_integer() and r._integer >= 0): raise ValueError r = r._integer if not (j.is_integer() and j._integer in (1, 2, 3, 4)): raise ValueError j = j._integer z = self.eval(z, **kwargs) tau = self.eval(tau, **kwargs) z = acb(z) v = z.modular_theta(tau, r)[j - 1] if v.is_finite(): return v raise ArbFiniteError if head == Decimal: assert len(args) == 1 x = arb(args[0]._text) return x if head == DirichletCharacter: if len(args) == 3: q, l, n = args if q.is_integer() and l.is_integer() and n.is_integer(): q = q._integer l = l._integer n = n._integer try: chi = self.flint.dirichlet_char(q, l) return chi(n) except (AssertionError, ValueError): pass if head == DirichletL: if len(args) == 2: s, chi = args if chi.head() == DirichletCharacter and len(chi.args()) == 2: q, l = chi.args() if q.is_integer() and l.is_integer(): chi = self.flint.dirichlet_char(q._integer, l._integer) s = self.eval(s, **kwargs) v = chi.l(s) if v.is_finite(): return v raise ArbFiniteError if head == LambertW: if len(args) == 2: k, x = args if k.is_integer(): k = k._integer x = self.eval(x, **kwargs) x = acb(x) v = x.lambertw(k) if v.is_finite(): return v raise ArbFiniteError if head in (AiryAi, AiryBi): if head == AiryAi: fname = "airy_ai" else: fname = "airy_bi" if len(args) == 1: x = args[0] x = self.eval(x, **kwargs) v = getattr(x, fname)() if v.is_finite(): return v elif len(args) == 2: x, r = args x = self.eval(x, **kwargs) if r.is_integer(): r = r._integer # todo: handle more directly in python-flint? if 0 <= r <= 1000: orig = flint.ctx.cap try: flint.ctx.cap = r + 1 if isinstance(x, arb): v = getattr(flint.arb_series([x, 1]), fname)()[r] * arb.fac_ui(r) else: v = getattr(flint.acb_series([x, 1]), fname)()[r] * arb.fac_ui(r) finally: flint.ctx.cap = orig if v.is_finite(): return v if head in (EisensteinG, EisensteinE): # todo: wrap eisenstein series in python-flint if len(args) == 2: n, tau = args if n.is_integer(): n = n._integer if n >= 2 and n % 2 == 0 and n <= 8: tau = self.eval(tau, **kwargs) if n == 2: v = 2 * acb(0.5).elliptic_zeta(tau) if head == EisensteinE: v /= (2 * arb(n).zeta()) else: _, a, b, c = acb(0).modular_theta(tau) if n == 4: v = 0.5 * (a**8 + b**8 + c**8) elif n == 6: v = 0.5 * (b**12 + c**12 - 3 * a**8 * (b**4 + c**4)) else: v = 0.5 * (a**16 + b**16 + c**16) if head == EisensteinG: v *= (2 * arb(n).zeta()) if v.is_finite(): return v if head == HurwitzZeta: if len(args) == 2: s, a = args s = self.eval(s, **kwargs) a = self.eval(a, **kwargs) s = acb(s) v = s.zeta(a) if v.is_finite(): return v raise ArbFiniteError if head == DigammaFunction: if len(args) == 1: z, = args z = self.eval(z, **kwargs) z = acb(z) v = z.digamma() if v.is_finite(): return v raise ArbFiniteError if len(args) == 2: z, n = args if n.is_integer() and int(n) >= 0: return self.eval(PolyGamma(n, z), **kwargs) if head in (PolyGamma, PolyLog): if len(args) == 2: s, z = args s = self.eval(s, **kwargs) z = self.eval(z, **kwargs) z = acb(z) if head == PolyGamma: v = z.polygamma(s) else: v = z.polylog(s) if v.is_finite(): return v raise ArbFiniteError if head == StieltjesGamma: if len(args) == 1: n = args[0] if n.is_integer() and int(n) >= 0: v = acb.stieltjes(int(n)) if v.is_finite(): return v if len(args) == 2: n, a = args a = self.eval(a, **kwargs) if n.is_integer() and int(n) >= 0: v = acb.stieltjes(int(n), a) if v.is_finite(): return v if head == Where: symbol_stack = kwargs.get("symbol_stack", [])[:] nv = len(args) - 1 assert nv >= 0 for arg in args[1:]: if arg.head() == Equal and len(arg.args()) == 2: var = arg.args()[0] if var.is_symbol(): val = arg.args()[1] val = self.eval(val, **kwargs) symbol_stack += [(var, val)] kwargs["symbol_stack"] = symbol_stack else: raise NotImplementedError v = self.eval(args[0], **kwargs) # note: **kwargs is a new copy, so we don't have to restore the stack return v # todo: delete if kwargs.get("full_traversal"): for arg in expr.args(): try: self.eval(arg, **kwargs) except (NotImplementedError, ValueError, ArbFiniteError): continue raise ValueError
def plots(outdir): directory[0] = outdir def elliprf_decor(): branchcutline(0, -4, offset=0.07) xrayplot(lambda z: complex(acb.elliptic_rf(z, 1, 2)), (-4, 4), (-4, 4), 400, "carlson_rf", xout=0.1, yout=0.1, decorations=elliprf_decor) rcParams["legend.borderaxespad"] = 1.2 curveplot([ lambda x: elliprg(x, 0.1, 1).real, lambda x: elliprg(x, 1.0, 1.0).real, lambda x: elliprg(x, 10, 1.0).real ], (0, 4), N=400, filename="carlson_rg", xout=0.1, yout=0.1, legend_loc='lower right', legends=["$R_G(x,0.1,1)$", "$R_G(x,1,1)$", "$R_G(x,10,1)$", " "]) rcParams["legend.borderaxespad"] = 0.5 curveplot([ lambda x: elliprf(x, 0.1, 1).real, lambda x: elliprf(x, 1.0, 1.0).real, lambda x: elliprf(x, 10, 1.0).real ], (0, 4), N=400, filename="carlson_rf", xout=0.1, yout=0.1, legends=["$R_F(x,0.1,1)$", "$R_F(x,1,1)$", "$R_F(x,10,1)$"]) curveplot([ lambda x: ellipf(x, 0.5), lambda x: ellipf(x, 0.8), lambda x: ellipf(x, 0.99) ], (-2 * pi, 2 * pi), yayb=(-10, 10), N=400, filename="incomplete_elliptic_f", xout=0.1, yout=0.1, legends=["$F(\\phi,0.5)$", "$F(\\phi,0.8)$", "$F(\\phi,0.99)$"], legend_loc='lower right', xtks=([-2 * pi, -pi, 0, pi, 2 * pi], ), ytks=([-2 * pi, -0, 2 * pi], )) curveplot([ lambda x: ellipe(x, 0.5), lambda x: ellipe(x, 0.8), lambda x: ellipe(x, 0.99) ], (-2 * pi, 2 * pi), yayb=(-10, 10), N=400, filename="incomplete_elliptic_e", xout=0.1, yout=0.1, legends=["$E(\\phi,0.5)$", "$E(\\phi,0.8)$", "$E(\\phi,0.99)$"], legend_loc='lower right', xtks=([-2 * pi, -pi, 0, pi, 2 * pi], ), ytks=([-2 * pi, -0, 2 * pi], )) curveplot([lambda x: fp.re(mp.ellipk(x)), lambda x: fp.im(mp.ellipk(x))], (-2, 2), yayb=(-2, 4), N=400, filename="elliptic_k", xout=0.1, yout=0.1, xtks=([-2, 0, 1, 2], ), singularities=[1]) curveplot([lambda x: fp.re(mp.ellipe(x)), lambda x: fp.im(mp.ellipe(x))], (-2, 2), yayb=(-2, 4), N=400, filename="elliptic_e", xout=0.1, yout=0.1, xtks=([-2, 0, 1, 2], ), singularities=[1]) _agm = lambda x: complex(acb(x).agm()) def agm_decor(): branchcutline(0, -1, offset=0.07) branchcutline(-1, -4, offset=0.07) curveplot([lambda x: fp.re(_agm(x)), lambda x: fp.im(_agm(x))], (-2, 2), yayb=(-0.6, 2.1), N=400, filename="agm", xout=0.1, yout=0.1, ytks=([0, 1, 2], ), xtks=([-2, -1, 0, 1, 2], ), singularities=[-1, 0]) xrayplot(lambda z: complex(acb(z).agm()), (-4, 4), (-4, 4), 400, "agm", xout=0.1, yout=0.1, decorations=agm_decor) curveplot([lambda x: acb(x * 1j).modular_lambda().real], (0, 4), yayb=(-0.1, 1.1), N=400, filename="modular_lambda", xout=0.1, yout=0.1, ytks=([0, 0.5, 1], ), xtks=([0, 2, 4], )) curveplot([lambda x: fp.exp(x)], (-4, 4), yayb=(-1, 7), N=400, filename="exp", xout=0.1, yout=0.1, ytks=([0, 2, 4, 6], ), xtks=([-4, -2, 0, 2, 4], )) curveplot([lambda x: fp.gamma(x)], (-4, 4), yayb=(-6, 6), N=400, filename="gamma", xout=0.1, yout=0.1, singularities=[-4, -3, -2, -1, 0], xtks=([-4, -2, 0, 2, 4], ), ytks=([-6, -4, -2, 0, 2, 4, 6], )) curveplot( [lambda x: fp.re(fp.loggamma(x)), lambda x: fp.im(fp.loggamma(x))], (-4, 4), yayb=(-7, 4), N=2000, filename="log_gamma", xout=0.1, yout=0.1, singularities=[-4, -3, -2, -1, 0], #legends=["$\\operatorname{Re}(\\log \\Gamma(x))$", "$\\operatorname{Im}(\\log \\Gamma(x))$"], legends=["$\\operatorname{Re}$", "$\\operatorname{Im}$"], legend_loc="lower right", xtks=([-4, -2, 0, 2, 4], ), ytks=([-6, -4, -2, 0, 2, 4], )) curveplot( [ lambda s: good(lambda: acb(s).zeta(0.6).real, prec=20), lambda s: good(lambda: acb(s).zeta(0.8).real, prec=20), lambda s: good(lambda: acb(s).zeta(1.4).real, prec=20) ], (-25, 11), yayb=[-6.5, 6.5], N=400, filename="hurwitz_zeta", xout=0.1, yout=0.1, singularities=[1], legends=["$\\zeta(s,0.6)$", "$\\zeta(s,0.8)$", "$\\zeta(s,1.4)$"], legend_loc='upper center', xtks=([-20, -10, 0, 10], ), ytks=([-5, 0, 5], ), ) def lgamma_decor(): branchcutline(0, -1, offset=0.07) branchcutline(-1, -2, offset=0.07) branchcutline(-2, -3, offset=0.07) branchcutline(-3, -4, offset=0.07) branchcutline(-4, -5, offset=0.07) xrayplot(lambda z: complex( good(lambda: acb(2 + 3j).zeta(z), prec=20, parts=False)), (-5, 5), (-5, 5), 400, "hurwitz_zeta_param", decorations=lgamma_decor, xout=0.1, yout=0.1) xrayplot(lambda z: complex( good(lambda: acb(z).zeta(1 + 0.5j), prec=20, parts=False)), (-20, 20), (-20, 20), 400, "hurwitz_zeta", xout=0.1, yout=0.1, xtks=([-20, -10, 0, 10, 20], ), ytks=([-20, -10, 0, 10, 20], )) curveplot( [lambda x: fp.barnesg(x)], (-4, 6), yayb=[-0.5, 2.5], N=400, filename="barnes_g", xout=0.1, yout=0.1, xtks=([-4, -2, 0, 2, 4, 6], ), ytks=([0, 1, 2], ), ) curveplot( [lambda x: fp.sinc(x), lambda x: fp.sinc(pi * x)], (-3 * pi, 3 * pi), yayb=[-0.4, 1.22], N=400, filename="sinc", xout=0.1, yout=0.1, legends=["$\\mathrm{sinc}(x)$", "$\\mathrm{sinc}(\\pi x)$"], xtks=([-2 * pi, -pi, 0, pi, 2 * pi], ), ytks=([0, 0.5, 1], ), ) def coverup_rectangle(xy, w, h): gca().add_patch( patches.Rectangle(xy, w, h, linewidth=0, facecolor=realcolor, zorder=2)) def elltheta(z, tau): return tuple(complex(c) for c in acb(z).modular_theta(tau)) theta1 = lambda z, tau: elltheta(z, tau)[0] theta2 = lambda z, tau: elltheta(z, tau)[1] theta3 = lambda z, tau: elltheta(z, tau)[2] theta4 = lambda z, tau: elltheta(z, tau)[3] def ellzeta(z, tau): return complex(acb(z).elliptic_zeta(tau)) def modlambda(tau): if tau.imag < 0.01: return 0.0 return complex(acb(tau).modular_lambda()) def eisene(k, tau): if tau.imag < 0.01: return 0.0 if k == 2: return ellzeta(0.5, tau) / fp.zeta(2) _, a, b, c = elltheta(0, tau) E4 = 0.5 * (a**8 + b**8 + c**8) E6 = 0.5 * (-3 * a**8 * (b**4 + c**4) + b**12 + c**12) E8 = 0.5 * (a**16 + b**16 + c**16) if k == 4: return E4 if k == 6: return E6 if k == 8: return E8 if k == 10: return E4 * E6 if k == 12: return (441 * E4**3 + 250 * E6**2) / 691 if k == 14: return E4**2 * E6 if k == 16: return (1617 * E4**4 + 2000 * E4 * E6**2) / 3617 raise ValueError #xrayplot(lambda z: complex(acb(z).sinc()), (-8,8), (-8,8), 400, "sinc", xout=0.1, yout=0.1, xtks=([-6,-3,0,3,6],), ytks=([-6,-3,0,3,6],),) xrayplot( lambda z: complex(acb(z).sinc()), (-8, 8), (-8, 8), 400, "sinc", xout=0.1, yout=0.1, xtks=([-2 * pi, -pi, 0, pi, 2 * pi], ), ytks=([-2 * pi, -pi, 0, pi, 2 * pi], ), ) xrayplot( lambda z: complex(acb(z).barnes_g()), (-4, 6), (-5, 5), 400, "barnes_g", xout=0.1, yout=0.1, xtks=([-4, -2, 0, 2, 4, 6], ), ) xrayplot( lambda z: complex(acb(z).log_barnes_g()), (-4, 6), (-5, 5), 400, "log_barnes_g", xout=0.1, yout=0.1, decorations=lgamma_decor, xtks=([-4, -2, 0, 2, 4, 6], ), ) xrayplot(lambda z: complex(acb(z).lgamma()), (-5, 5), (-5, 5), 400, "log_gamma", xout=0.1, yout=0.1, decorations=lgamma_decor) xrayplot(lambda z: complex(acb(z).digamma()), (-5, 5), (-5, 5), 400, "digamma", xout=0.1, yout=0.1) xrayplot(lambda z: complex(acb(z).polygamma(1)), (-5, 5), (-5, 5), 400, "trigamma", xout=0.1, yout=0.1) xrayplot(lambda tau: 0.0 if tau.imag < 0.13 else theta1(1 / 3. + 0.75j, tau), (-2.5, 2.5), (0, 2), 600, "jacobi_theta_1_tau_b", decorations=lambda: coverup_rectangle((-2.5, 0), 5, 0.14), xout=0.1, yout=0.0, xtks=([-2, -1, 0, 1, 2], ), ytks=([0, 1, 2], )) xrayplot(lambda tau: 0.0 if tau.imag < 0.13 else theta2(1 / 3. + 0.75j, tau), (-2.5, 2.5), (0, 2), 600, "jacobi_theta_2_tau_b", decorations=lambda: coverup_rectangle((-2.5, 0), 5, 0.14), xout=0.1, yout=0.0, xtks=([-2, -1, 0, 1, 2], ), ytks=([0, 1, 2], )) xrayplot(lambda tau: 0.0 if tau.imag < 0.13 else theta3(1 / 3. + 0.75j, tau), (-2.5, 2.5), (0, 2), 600, "jacobi_theta_3_tau_b", decorations=lambda: coverup_rectangle((-2.5, 0), 5, 0.14), xout=0.1, yout=0.0, xtks=([-2, -1, 0, 1, 2], ), ytks=([0, 1, 2], )) xrayplot(lambda tau: 0.0 if tau.imag < 0.13 else theta4(1 / 3. + 0.75j, tau), (-2.5, 2.5), (0, 2), 600, "jacobi_theta_4_tau_b", decorations=lambda: coverup_rectangle((-2.5, 0), 5, 0.14), xout=0.1, yout=0.0, xtks=([-2, -1, 0, 1, 2], ), ytks=([0, 1, 2], )) xrayplot(lambda tau: theta2(0, tau), (-2.5, 2.5), (0, 2), 600, "jacobi_theta_2_tau", xout=0.1, yout=0.0, xtks=([-2, -1, 0, 1, 2], ), ytks=([0, 1, 2], )) xrayplot(lambda tau: theta3(0, tau), (-2.5, 2.5), (0, 2), 600, "jacobi_theta_3_tau", xout=0.1, yout=0.0, xtks=([-2, -1, 0, 1, 2], ), ytks=([0, 1, 2], )) xrayplot(lambda tau: theta4(0, tau), (-2.5, 2.5), (0, 2), 600, "jacobi_theta_4_tau", xout=0.1, yout=0.0, xtks=([-2, -1, 0, 1, 2], ), ytks=([0, 1, 2], )) w3 = 0.25 + 0.75j xrayplot(lambda z: theta1(z, w3), (-2, 2), (-2, 2), 400, "jacobi_theta_1_z_c", xout=0.1, yout=0.1) xrayplot(lambda z: theta2(z, w3), (-2, 2), (-2, 2), 400, "jacobi_theta_2_z_c", xout=0.1, yout=0.1) xrayplot(lambda z: theta3(z, w3), (-2, 2), (-2, 2), 400, "jacobi_theta_3_z_c", xout=0.1, yout=0.1) xrayplot(lambda z: theta4(z, w3), (-2, 2), (-2, 2), 400, "jacobi_theta_4_z_c", xout=0.1, yout=0.1) xrayplot(lambda z: theta1(z, 1j), (-2, 2), (-2, 2), 400, "jacobi_theta_1_z", xout=0.1, yout=0.1) xrayplot(lambda z: theta2(z, 1j), (-2, 2), (-2, 2), 400, "jacobi_theta_2_z", xout=0.1, yout=0.1) xrayplot(lambda z: theta3(z, 1j), (-2, 2), (-2, 2), 400, "jacobi_theta_3_z", xout=0.1, yout=0.1) xrayplot(lambda z: theta4(z, 1j), (-2, 2), (-2, 2), 400, "jacobi_theta_4_z", xout=0.1, yout=0.1) xrayplot(lambda z: theta1(z, 0.5j), (-2, 2), (-2, 2), 400, "jacobi_theta_1_z_b", xout=0.1, yout=0.1) xrayplot(lambda z: theta2(z, 0.5j), (-2, 2), (-2, 2), 400, "jacobi_theta_2_z_b", xout=0.1, yout=0.1) xrayplot(lambda z: theta3(z, 0.5j), (-2, 2), (-2, 2), 400, "jacobi_theta_3_z_b", xout=0.1, yout=0.1) xrayplot(lambda z: theta4(z, 0.5j), (-2, 2), (-2, 2), 400, "jacobi_theta_4_z_b", xout=0.1, yout=0.1) fundament_lambda_x = list(linspace(-1, 0, 80)) fundament_lambda_y = [ 0.5 * sqrt(1 - (2 * x + 1)**2) for x in fundament_lambda_x ] x2 = [x + 1.0 for x in fundament_lambda_x] y2 = fundament_lambda_y[:] fundament_lambda_x = fundament_lambda_x + x2 fundament_lambda_y = fundament_lambda_y + y2 fundament_lambda_x = [-1.0] + fundament_lambda_x + [1.0] fundament_lambda_y = [2.0] + fundament_lambda_y + [2.0] def lambda_decorations(): coverup_rectangle((-1.5, 0), 3, 0.015) coverup_rectangle((-0.05, 0), 0.1, 0.1) fill(fundament_lambda_x, fundament_lambda_y, facecolor=highlightcolor, edgecolor=highlightbordercolor, alpha=0.5, linewidth=0.5, zorder=2) xrayplot(lambda tau: modlambda(tau), (-1.5, 1.5), (0, 2), 600, "modular_lambda", xtks=([-1.5, -1, -0.5, 0, 0.5, 1, 1.5], ), ytks=([0, 0.5, 1, 1.5, 2], ), decorations=lambda_decorations, xout=0.1, yout=0.0) fundament_x = list(linspace(-0.5, 0.5, 100)) fundament_y = [sqrt(1 - x**2) for x in fundament_x] fundament_x = [-0.5] + fundament_x + [0.5] fundament_y = [2.0] + fundament_y + [2.0] def eisenstein_decorations(): coverup_rectangle((-1, 0), 2, 0.015) fill(fundament_x, fundament_y, facecolor=highlightcolor, edgecolor=highlightbordercolor, alpha=0.5, linewidth=0.5, zorder=2) xrayplot(lambda tau: eisene(2, tau), (-1, 1), (0, 2), 600, "eisenstein_e2", xtks=([-1, -0.5, 0, 0.5, 1], ), ytks=([0, 0.5, 1, 1.5, 2], ), decorations=eisenstein_decorations, xout=0.1, yout=0.0) xrayplot(lambda tau: eisene(4, tau), (-1, 1), (0, 2), 600, "eisenstein_e4", xtks=([-1, -0.5, 0, 0.5, 1], ), ytks=([0, 0.5, 1, 1.5, 2], ), decorations=eisenstein_decorations, xout=0.1, yout=0.0) xrayplot(lambda tau: eisene(6, tau), (-1, 1), (0, 2), 600, "eisenstein_e6", xtks=([-1, -0.5, 0, 0.5, 1], ), ytks=([0, 0.5, 1, 1.5, 2], ), decorations=eisenstein_decorations, xout=0.1, yout=0.0) xrayplot(lambda tau: eisene(8, tau), (-1, 1), (0, 2), 600, "eisenstein_e8", xtks=([-1, -0.5, 0, 0.5, 1], ), ytks=([0, 0.5, 1, 1.5, 2], ), decorations=eisenstein_decorations, xout=0.1, yout=0.0) xrayplot(lambda tau: eisene(10, tau), (-1, 1), (0, 2), 600, "eisenstein_e10", xtks=([-1, -0.5, 0, 0.5, 1], ), ytks=([0, 0.5, 1, 1.5, 2], ), decorations=eisenstein_decorations, xout=0.1, yout=0.0) xrayplot(lambda tau: eisene(12, tau), (-1, 1), (0, 2), 600, "eisenstein_e12", xtks=([-1, -0.5, 0, 0.5, 1], ), ytks=([0, 0.5, 1, 1.5, 2], ), decorations=eisenstein_decorations, xout=0.1, yout=0.0) def zeta_decorations(): axvspan(0, 1, alpha=0.5, color=highlightcolor) axvline(0, alpha=0.5, color=highlightbordercolor, linewidth=0.5) axvline(1, alpha=0.5, color=highlightbordercolor, linewidth=0.5) xrayplot(lambda z: complex(acb(z).zeta()), (-22, 22), (-27, 27), 400, "zeta", zeta_decorations, xout=0.1, yout=0.1) def plot_elliptic(tau, filename): xrayplot( lambda z: complex(acb(z).elliptic_p(tau)), (-1.5, 1.5), (-1.5, 1.5), 400, filename, xout=0.1, yout=0.1, xtks=([-1, 0, 1], ), ytks=([-1, 0, 1], ), decorations=lambda: fill([0.0, 1.0, tau.real + 1.0, tau.real, 0.0], [0.0, 0.0, tau.imag, tau.imag, 0.0], facecolor=highlightcolor, edgecolor=highlightbordercolor, alpha=0.5, linewidth=0.5, zorder=2)) plot_elliptic(1j, "elliptic_p") plot_elliptic(0.5 + 0.75**0.5 * 1j, "elliptic_p_2") plot_elliptic(-0.8 + 0.7j, "elliptic_p_3") xrayplot(lambda z: complex(acb(z).airy_ai()), (-6, 6), (-6, 6), 400, "airy_ai", xout=0.1, yout=0.1) xrayplot(lambda z: complex(acb(z).airy_bi()), (-6, 6), (-6, 6), 400, "airy_bi", xout=0.1, yout=0.1) xrayplot(lambda z: complex(acb(z).erf()), (-4, 4), (-4, 4), 400, "erf", xout=0.1, yout=0.1) def atan_decor(): branchcutline(1j, 10j) branchcutline(-1j, -10j) xrayplot(lambda z: complex(acb(z).log()), (-3, 3), (-3, 3), 400, "log", xout=0.1, yout=0.1, decorations=lambda: branchcutline(0, -10, offset=0.05)) xrayplot(lambda z: complex(acb(z).sqrt()), (-3, 3), (-3, 3), 400, "sqrt", xout=0.1, yout=0.1, decorations=lambda: branchcutline(0, -10, offset=0.05)) xrayplot(lambda z: complex(acb(z).atan()), (-2, 2), (-2, 2), 400, "atan", xout=0.1, yout=0.1, decorations=atan_decor) xrayplot(lambda z: complex(acb(z).lambertw()), (-3, 3), (-3, 3), 400, "lambertw", xout=0.1, yout=0.1, decorations=lambda: branchcutline(-exp(-1), -10, offset=0.05)) xrayplot(lambda z: complex(acb(z).exp()), (-5, 5), (-5, 5), 400, "exp", xout=0.1, yout=0.1) xrayplot(lambda z: complex(acb(z).sin()), (-5, 5), (-5, 5), 400, "sin", xout=0.1, yout=0.1) xrayplot(lambda z: complex(acb(z).gamma()), (-5, 5), (-5, 5), 400, "gamma", xout=0.1, yout=0.1) def coverup_rectangle(xy, w, h): gca().add_patch( patches.Rectangle(xy, w, h, linewidth=0, facecolor=realcolor, zorder=2)) def modj(z): if z.imag < 0.03: return 0.0 return complex(acb(z).modular_j()) / 1728.0 fundament_x = list(linspace(-0.5, 0.5, 100)) fundament_y = [sqrt(1 - x**2) for x in fundament_x] fundament_x = [-0.5] + fundament_x + [0.5] fundament_y = [2.0] + fundament_y + [2.0] def modular_j_decorations(): coverup_rectangle((-1, 0), 2, 0.04) coverup_rectangle((-1, 0), 0.1, 0.1) coverup_rectangle((-0.1, 0), 0.2, 0.1) coverup_rectangle((0.9, 0), 0.1, 0.1) fill(fundament_x, fundament_y, facecolor=highlightcolor, edgecolor=highlightbordercolor, alpha=0.5, linewidth=0.5, zorder=2) xrayplot(modj, (-1, 1), (0, 2), 600, "modular_j", xtks=([-1, -0.5, 0, 0.5, 1], ), ytks=([0, 0.5, 1, 1.5, 2], ), decorations=modular_j_decorations, xout=0.1, yout=0.0)
def i(): return alg(_minpoly=fmpz_poly([1, 0, 1]), _enclosure=acb(0, 1))
def spiral(): global legends plt.clf() ax = plt.gca() legends = [] ax.grid(True) R = -arb(-1).exp() yrange = [-5, 15] h = 1 / 13. if 1: ploterr(ax, lambda X: acb(X).exp_pi_i().lambertw(0).imag, [-0.5, 0.5], yrange, h, color="red", label="$h = 0.1$", alpha=0.5) ploterr(ax, lambda X: acb(X).exp_pi_i().lambertw(0, flags=2).imag, [0.5, 1.5], yrange, h, color="red", label="$h = 0.1$", alpha=0.5) ploterr(ax, lambda X: acb(X).exp_pi_i().lambertw(1).imag, [1.5, 2.5], yrange, h, color="red", label="$h = 0.1$", alpha=0.5) ploterr(ax, lambda X: acb(X).exp_pi_i().lambertw(1, flags=2).imag, [2.5, 3.5], yrange, h, color="red", label="$h = 0.1$", alpha=0.5) ploterr(ax, lambda X: acb(X).exp_pi_i().lambertw(2).imag, [3.5, 4.5], yrange, h, color="red", label="$h = 0.1$", alpha=0.5) ploterr(ax, lambda X: acb(X).exp_pi_i().lambertw(2, flags=2).imag, [4.5, 5.5], yrange, h, color="red", label="$h = 0.1$", alpha=0.5) ploterr(ax, lambda X: acb(X).exp_pi_i().lambertw(0).real, [-0.5, 0.5], yrange, h, color="blue", label="$h = 0.1$", alpha=0.5) ploterr(ax, lambda X: acb(X).exp_pi_i().lambertw(0, flags=2).real, [0.5, 1.5], yrange, h, color="blue", label="$h = 0.1$", alpha=0.5) ploterr(ax, lambda X: acb(X).exp_pi_i().lambertw(1).real, [1.5, 2.5], yrange, h, color="blue", label="$h = 0.1$", alpha=0.5) ploterr(ax, lambda X: acb(X).exp_pi_i().lambertw(1, flags=2).real, [2.5, 3.5], yrange, h, color="blue", label="$h = 0.1$", alpha=0.5) ploterr(ax, lambda X: acb(X).exp_pi_i().lambertw(2).real, [3.5, 4.5], yrange, h, color="blue", label="$h = 0.1$", alpha=0.5) ploterr(ax, lambda X: acb(X).exp_pi_i().lambertw(2, flags=2).real, [4.5, 5.5], yrange, h, color="blue", label="$h = 0.1$", alpha=0.5) ax.set_xlim([-0.5, 5.5]) else: print "zagurra" ploterr(ax, lambda X: (acb(X) + acb(1 - X**2).sqrt() * 1j).lambertw(0).imag, [0.0, 1.0], yrange, h, color="blue", label="$h = 0.1$", alpha=0.5) print "zagurra1" ploterr(ax, lambda X: (acb(X) + acb(1 - X**2).sqrt() * 1j).lambertw(0, flags=2).imag, [-1.0, 0.0], yrange, h, color="red", label="$h = 0.1$", alpha=0.5) print "zagurra2" ploterr(ax, lambda X: (acb(X) - acb(1 - X**2).sqrt() * 1j).lambertw(0, flags=2).imag, [-1.0, 0.0], yrange, h, color="red", label="$h = 0.1$", alpha=0.5) print "zagurra3" ploterr(ax, lambda X: (acb(X) - acb(1 - X**2).sqrt() * 1j).lambertw(1).imag, [0.0, 1.0], yrange, h, color="blue", label="$h = 0.1$", alpha=0.5) ax.set_xlim([-1.5, 1.5]) ax.set_ylim([-5, 5]) plt.xlabel("$\\theta$") plt.ylabel("$W(e^{\\pi i \\theta})$") #ax.legend(handles=legends, loc="upper right") import matplotlib fig = matplotlib.pyplot.gcf() fig.set_size_inches(8, 5) fig.savefig('tests.png', bbox_inches="tight") fig.savefig('branchplots.pdf', bbox_inches="tight")
def spiralb(): global legends plt.clf() ax = plt.gca() legends = [] ax.grid(True) R = -arb(-1).exp() yrange = [-2, 2] #def G(z, k): # return lambertw((z**2/(2*e))-1/e,k) #def H(x, k): # return abs(1+G(exp(pi*1j*x), k)) #plot([lambda x: H(x, 0), lambda x: H(x, 1), lambda x: H(x, -1)], [0, 2], [0,2]) #0 to 0.5 0 #0.5 to 1 1 #1 to 1.5 -1 #1.5 to 2.0 0 indet = acb("+/- inf", "+/- inf") def B(t): Z2 = (1.25 * 1.25) * acb(2 * t).exp_pi_i() Z = (Z2 - 2) / (2 * acb(1).exp()) t = float(t) print t if t < 0.25: W = Z.lambertw() elif t < 0.75: W = Z.lambertw(branch=0, flags=2) elif t < 0.9: W = Z.lambertw(branch=1) elif t < 1.1: W = Z.lambertw(branch=-1, flags=4) elif t < 1.25: W = Z.lambertw(branch=-1) elif t < 1.75: W = Z.lambertw(branch=-1, flags=2) else: W = Z.lambertw() res = 2 + W if not abs(res) < 2: return indet # raise ValueError return res plotadaptive(ax, lambda z: B(z).real, [0.0, 2.0], yrange, goal=0.1, color="blue", alpha=0.5) plotadaptive(ax, lambda z: B(z).imag, [0.0, 2.0], yrange, goal=0.1, color="red", alpha=0.5) plotadaptive(ax, lambda z: abs(B(z)), [0.0, 2.0], yrange, goal=0.1, color="black", alpha=0.5) """ h = 1 / 64. ploterr(ax, lambda z: B(z).real, [0.0, 0.75], yrange, h, color="blue", label="$h = 0.1$", alpha=0.5) ploterr(ax, lambda z: B(z).imag, [0.0, 0.75], yrange, h, color="red", label="$h = 0.1$", alpha=0.5) ploterr(ax, lambda z: abs(B(z)), [0.0, 0.75], yrange, h, color="black", label="$h = 0.1$", alpha=0.5) h = 1 / 512. ploterr(ax, lambda z: B(z).real, [0.75, 1.25], yrange, h, color="blue", label="$h = 0.1$", alpha=0.5) ploterr(ax, lambda z: B(z).imag, [0.75, 1.25], yrange, h, color="red", label="$h = 0.1$", alpha=0.5) ploterr(ax, lambda z: abs(B(z)), [0.75, 1.25], yrange, h, color="black", label="$h = 0.1$", alpha=0.5) h = 1 / 64. ploterr(ax, lambda z: B(z).real, [1.25, 2.0], yrange, h, color="blue", label="$h = 0.1$", alpha=0.5) ploterr(ax, lambda z: B(z).imag, [1.25, 2.0], yrange, h, color="red", label="$h = 0.1$", alpha=0.5) ploterr(ax, lambda z: abs(B(z)), [1.25, 2.0], yrange, h, color="black", label="$h = 0.1$", alpha=0.5) """ ax.set_xlim([0.0, 2.0]) ax.set_ylim([-2.0, 3.0]) plt.xlabel("$\\theta$") plt.ylabel("$W((z^2-2)/(2e)), z = 1.25 e^{\\pi i \\theta}$") #ax.legend(handles=legends, loc="upper right") import matplotlib fig = matplotlib.pyplot.gcf() fig.set_size_inches(8, 5) fig.savefig('testb.png', bbox_inches="tight") fig.savefig('branchplotb.pdf', bbox_inches="tight")
def eval_inner(self, expr, **kwargs): flint = self.flint arb = self.flint.arb acb = self.flint.acb if expr.is_atom(): if expr.is_integer(): return arb(expr._integer) if expr.is_symbol(): if expr == Pi: return arb.pi() if expr == ConstE: return arb.const_e() if expr == ConstGamma: return arb.const_euler() if expr == ConstI: return acb(0, 1) if expr == GoldenRatio: return (1 + arb(5).sqrt()) / 2 if expr == ConstCatalan: return arb.const_catalan() if expr == ConstGlaisher: return arb.const_glaisher() stack = kwargs.get("symbol_stack") if stack is not None: for (sym, val) in reversed(stack): if sym == expr: return val raise NotImplementedError head = expr.head() args = expr.args() if head == Mul: if len(args) == 0: return arb(1) x = self.eval(args[0], **kwargs) for y in args[1:]: y = self.eval(y, **kwargs) x *= y return x if head == Add: if len(args) == 0: return arb(0) x = self.eval(args[0], **kwargs) for y in args[1:]: y = self.eval(y, **kwargs) x += y return x if head == Neg: assert len(args) == 1 x = self.eval(args[0], **kwargs) return (-x) if head == Sub: assert len(args) == 2 x = self.eval(args[0], **kwargs) y = self.eval(args[1], **kwargs) return x - y if head == Div: assert len(args) == 2 x = self.eval(args[0], **kwargs) y = self.eval(args[1], **kwargs) if y != 0: return x / y raise ArbFiniteError if head == Pow: assert len(args) == 2 x = self.eval(args[0], **kwargs) y = self.eval(args[1], **kwargs) v = x**y if v.is_finite(): return v else: if isinstance(x, arb) and isinstance(y, arb): v = acb(x)**acb(y) if v.is_finite(): return v raise ArbFiniteError if head == Abs: assert len(args) == 1 x = self.eval(args[0], **kwargs) return abs(x) if head == Re: assert len(args) == 1 v = self.eval(args[0], **kwargs) if v.is_finite(): if isinstance(v, arb): return v else: return v.real raise ArbFiniteError if head == Im: assert len(args) == 1 v = self.eval(args[0], **kwargs) if v.is_finite(): if isinstance(v, arb): return arb(0) else: return v.imag raise ArbFiniteError if head == Conjugate: assert len(args) == 1 v = self.eval(args[0], **kwargs) if v.is_finite(): if isinstance(v, arb): return v else: return acb(v.real, -v.imag) raise ArbFiniteError if head == Arg: assert len(args) == 1 v = self.eval(args[0], **kwargs) if v.is_finite(): return acb(v).arg() raise ArbFiniteError if head == Sign: assert len(args) == 1 v = self.eval(args[0], **kwargs) if v.is_finite(): return acb(v).sgn() raise ArbFiniteError if head == Floor: assert len(args) == 1 v = self.eval(args[0], **kwargs) if v.is_finite(): if isinstance(v, arb): v = v.floor() else: v = v.real.floor() if v.is_finite(): return v raise ArbFiniteError if head == Ceil: assert len(args) == 1 v = self.eval(args[0], **kwargs) if v.is_finite(): if isinstance(v, arb): v = v.ceil() else: v = v.real.ceil() if v.is_finite(): return v raise ArbFiniteError if head in (Parentheses, Brackets, Braces): assert len(args) == 1 return self.eval(args[0], **kwargs) if head in function_arb_method_table: method = function_arb_method_table[head] assert len(args) == 1 x = self.eval(args[0], **kwargs) v = getattr(x, method)() if v.is_finite(): return v # possible complex extension if isinstance(x, arb): x = acb(x) v = getattr(x, method)() if v.is_finite(): return v raise ArbFiniteError if head in function_acb_method_table: method = function_acb_method_table[head] assert len(args) == 1 x = self.eval(args[0], **kwargs) x = acb(x) v = getattr(x, method)() if v.is_finite(): return v raise ArbFiniteError if head in (BesselJ, BesselI, BesselY, BesselK): if len(args) == 2: a, z = [self.eval(arg, **kwargs) for arg in args] z = acb(z) if head == BesselJ: v = z.bessel_j(a) elif head == BesselI: v = z.bessel_i(a) elif head == BesselY: v = z.bessel_y(a) else: v = z.bessel_k(a) if v.is_finite(): return v raise ArbFiniteError if head in (Hypergeometric0F1, Hypergeometric0F1Regularized): assert len(args) == 2 a, z = [self.eval(arg, **kwargs) for arg in args] z = acb(z) v = z.hypgeom_0f1( a, regularized=(head == Hypergeometric0F1Regularized)) if v.is_finite(): return v raise ArbFiniteError if head in (Hypergeometric1F1, Hypergeometric1F1Regularized): assert len(args) == 3 a, b, z = [self.eval(arg, **kwargs) for arg in args] z = acb(z) v = z.hypgeom_1f1( a, b, regularized=(head == Hypergeometric1F1Regularized)) if v.is_finite(): return v raise ArbFiniteError if head in (Hypergeometric2F1, Hypergeometric2F1Regularized): assert len(args) == 4 a, b, c, z = [self.eval(arg, **kwargs) for arg in args] z = acb(z) v = z.hypgeom_2f1( a, b, c, regularized=(head == Hypergeometric2F1Regularized)) if v.is_finite(): return v raise ArbFiniteError if head in (Hypergeometric1F2, Hypergeometric1F2Regularized): assert len(args) == 4 a, b, c, z = [self.eval(arg, **kwargs) for arg in args] z = acb(z) v = z.hypgeom([a], [b, c], regularized=(head == Hypergeometric1F2Regularized)) if v.is_finite(): return v raise ArbFiniteError if head in (Hypergeometric2F2, Hypergeometric2F2Regularized): assert len(args) == 5 a, b, c, d, z = [self.eval(arg, **kwargs) for arg in args] z = acb(z) v = z.hypgeom([a, b], [c, d], regularized=(head == Hypergeometric2F2Regularized)) if v.is_finite(): return v raise ArbFiniteError if head in (Hypergeometric3F2, Hypergeometric3F2Regularized): assert len(args) == 6 a, b, c, d, e, z = [self.eval(arg, **kwargs) for arg in args] z = acb(z) v = z.hypgeom([a, b, c], [d, e], regularized=(head == Hypergeometric3F2Regularized)) if v.is_finite(): return v raise ArbFiniteError if head == HypergeometricU: assert len(args) == 3 a, b, z = [self.eval(arg, **kwargs) for arg in args] z = acb(z) v = z.hypgeom_u(a, b) if v.is_finite(): return v raise ArbFiniteError if head == HypergeometricUStar: assert len(args) == 3 a, b, z = [self.eval(arg, **kwargs) for arg in args] # todo: implement in arb z = acb(z) v = z**a * z.hypgeom_u(a, b) if v.is_finite(): return v raise ArbFiniteError if head == Hypergeometric2F0: assert len(args) == 3 a, b, z = [self.eval(arg, **kwargs) for arg in args] # todo: implement in arb z = acb(z) z = -1 / z v = z**a * z.hypgeom_u(a, a - b + 1) if v.is_finite(): return v raise ArbFiniteError if head in (HypergeometricPFQ, HypergeometricPFQRegularized): assert len(args) == 3 a, b, z = args if a.head() in (List, Tuple): if b.head() in (List, Tuple): a = [self.eval(arg, **kwargs) for arg in a.args()] b = [self.eval(arg, **kwargs) for arg in b.args()] z = self.eval(z, **kwargs) z = acb(z) if head == HypergeometricPFQRegularized: v = z.hypgeom(a, b, regularized=True) else: v = z.hypgeom(a, b) if v.is_finite(): return v raise ArbFiniteError if head == CoulombF: assert len(args) == 3 a, b, z = [self.eval(arg, **kwargs) for arg in args] z = acb(z) v = z.coulomb_f(a, b) if v.is_finite(): return v raise ArbFiniteError if head == CoulombG: assert len(args) == 3 a, b, z = [self.eval(arg, **kwargs) for arg in args] z = acb(z) v = z.coulomb_g(a, b) if v.is_finite(): return v raise ArbFiniteError if head == CoulombG: assert len(args) == 3 a, b, z = [self.eval(arg, **kwargs) for arg in args] z = acb(z) v = z.coulomb_g(a, b) if v.is_finite(): return v raise ArbFiniteError if head == JacobiTheta: if len(args) == 3: j, z, tau = args r = 0 else: j, z, tau, r = args if not (r.is_integer() and r._integer >= 0): raise ValueError r = r._integer if r > 1000: raise NotImplementedError if not (j.is_integer() and j._integer in (1, 2, 3, 4)): raise ValueError j = j._integer z = self.eval(z, **kwargs) tau = self.eval(tau, **kwargs) z = acb(z) v = z.modular_theta(tau, r)[j - 1] if v.is_finite(): return v raise ArbFiniteError if head == CarlsonRF: assert len(args) == 3 x, y, z = [self.eval(arg, **kwargs) for arg in args] v = acb.elliptic_rf(x, y, z) if v.is_finite(): return v raise ArbFiniteError if head == CarlsonRG: assert len(args) == 3 x, y, z = [self.eval(arg, **kwargs) for arg in args] v = acb.elliptic_rg(x, y, z) if v.is_finite(): return v raise ArbFiniteError if head == CarlsonRD: assert len(args) == 3 x, y, z = [self.eval(arg, **kwargs) for arg in args] v = acb.elliptic_rd(x, y, z) if v.is_finite(): return v raise ArbFiniteError if head == CarlsonRJ: assert len(args) == 4 if flint.ctx.prec < 500: # can be slow x, y, z, p = [self.eval(arg, **kwargs) for arg in args] v = acb.elliptic_rj(x, y, z, p) if v.is_finite(): return v raise ArbFiniteError if head == CarlsonRC: assert len(args) == 2 x, y = [self.eval(arg, **kwargs) for arg in args] v = acb.elliptic_rc(x, y) if v.is_finite(): return v raise ArbFiniteError if head == Decimal: assert len(args) == 1 x = arb(args[0]._text) return x if head == DirichletCharacter: if len(args) == 3: q, l, n = args if q.is_integer() and l.is_integer() and n.is_integer(): q = q._integer l = l._integer n = n._integer if q <= 10**12: # arb limitation try: chi = self.flint.dirichlet_char(q, l) return chi(n) except (AssertionError, ValueError): pass if head == EllipticPi: assert len(args) == 2 if flint.ctx.prec < 350: # can be slow x, y = [self.eval(arg, **kwargs) for arg in args] v = acb.elliptic_pi(x, y) if v.is_finite(): return v raise ArbFiniteError if head == IncompleteEllipticF: assert len(args) == 2 phi, m = [self.eval(arg, **kwargs) for arg in args] v = acb.elliptic_f(phi, m) if v.is_finite(): return v raise ArbFiniteError if head == IncompleteEllipticE: assert len(args) == 2 phi, m = [self.eval(arg, **kwargs) for arg in args] v = acb.elliptic_e_inc(phi, m) if v.is_finite(): return v raise ArbFiniteError if head == IncompleteEllipticPi: assert len(args) == 3 if flint.ctx.prec < 350: # can be slow n, phi, m = [self.eval(arg, **kwargs) for arg in args] v = acb.elliptic_pi_inc(n, phi, m) if v.is_finite(): return v raise ArbFiniteError if head == DirichletL: if len(args) == 2: s, chi = args if chi.head() == DirichletCharacter and len(chi.args()) == 2: q, l = chi.args() if q.is_integer() and l.is_integer(): # todo: adjustable limit for this kind of thing? if int(q) <= 1000000: chi = self.flint.dirichlet_char( q._integer, l._integer) s = self.eval(s, **kwargs) v = chi.l(s) if v.is_finite(): return v raise ArbFiniteError if head == LambertW: if len(args) == 2: k, x = args if k.is_integer(): k = k._integer x = self.eval(x, **kwargs) x = acb(x) v = x.lambertw(k) if v.is_finite(): return v raise ArbFiniteError if head in (AiryAi, AiryBi): if head == AiryAi: fname = "airy_ai" else: fname = "airy_bi" if len(args) == 1: x = args[0] x = self.eval(x, **kwargs) v = getattr(x, fname)() if v.is_finite(): return v elif len(args) == 2: x, r = args x = self.eval(x, **kwargs) if r.is_integer(): r = r._integer # todo: handle more directly in python-flint? if 0 <= r <= 1000: orig = flint.ctx.cap try: flint.ctx.cap = r + 1 if isinstance(x, arb): v = getattr(flint.arb_series([x, 1]), fname)()[r] * arb.fac_ui(r) else: v = getattr(flint.acb_series([x, 1]), fname)()[r] * arb.fac_ui(r) finally: flint.ctx.cap = orig if v.is_finite(): return v if head in (EisensteinG, EisensteinE): # todo: wrap eisenstein series in python-flint if len(args) == 2: n, tau = args if n.is_integer(): n = n._integer if n >= 2 and n % 2 == 0 and n <= 8: tau = self.eval(tau, **kwargs) if n == 2: v = 2 * acb(0.5).elliptic_zeta(tau) if head == EisensteinE: v /= (2 * arb(n).zeta()) else: _, a, b, c = acb(0).modular_theta(tau) if n == 4: v = 0.5 * (a**8 + b**8 + c**8) elif n == 6: v = 0.5 * (b**12 + c**12 - 3 * a**8 * (b**4 + c**4)) else: v = 0.5 * (a**16 + b**16 + c**16) if head == EisensteinG: v *= (2 * arb(n).zeta()) if v.is_finite(): return v if head == HurwitzZeta: if len(args) == 2: if flint.ctx.prec < 1000: # can be slow s, a = args s = self.eval(s, **kwargs) a = self.eval(a, **kwargs) s = acb(s) v = s.zeta(a) if v.is_finite(): return v raise ArbFiniteError if head == DigammaFunction: if len(args) == 1: z, = args z = self.eval(z, **kwargs) z = acb(z) v = z.digamma() if v.is_finite(): return v raise ArbFiniteError if len(args) == 2: if flint.ctx.prec < 1000: # can be slow z, n = args if n.is_integer() and int(n) >= 0: return self.eval(PolyGamma(n, z), **kwargs) if head in (PolyGamma, PolyLog): if len(args) == 2: s, z = args s = self.eval(s, **kwargs) z = self.eval(z, **kwargs) z = acb(z) if head == PolyGamma: v = z.polygamma(s) else: v = z.polylog(s) if v.is_finite(): return v raise ArbFiniteError if head == StieltjesGamma: if flint.ctx.prec < 1000: # can be slow if len(args) == 1: n = args[0] if n.is_integer() and int(n) >= 0: v = acb.stieltjes(int(n)) if v.is_finite(): return v if len(args) == 2: n, a = args a = self.eval(a, **kwargs) if n.is_integer() and int(n) >= 0: v = acb.stieltjes(int(n), a) if v.is_finite(): return v if head == Where: symbol_stack = kwargs.get("symbol_stack", [])[:] nv = len(args) - 1 assert nv >= 0 for arg in args[1:]: if arg.head() == Equal and len(arg.args()) == 2: var = arg.args()[0] if var.is_symbol(): val = arg.args()[1] val = self.eval(val, **kwargs) symbol_stack += [(var, val)] kwargs["symbol_stack"] = symbol_stack else: raise NotImplementedError v = self.eval(args[0], **kwargs) # note: **kwargs is a new copy, so we don't have to restore the stack return v if head == Factorial: if len(args) == 1: z, = args z = self.eval(z, **kwargs) z = acb(z) v = (z + 1).gamma() if v.is_finite(): return v raise ArbFiniteError if head == Fibonacci: if len(args) == 1: z, = args z = z.simple() # XXX if z.is_integer(): n = int(z) v = arb.fib(n) if v.is_finite(): return v raise ArbFiniteError if head == BernoulliB: if len(args) == 1: n, = args n = n.simple() # XXX if n.is_integer() and int(n) >= 0: n = int(n) v = arb.bernoulli(n) if v.is_finite(): return v raise ArbFiniteError if head == Binomial: if len(args) == 2: z, n = args z = self.eval(z, **kwargs) n = n.simple() # XXX if n.is_integer() and int(n) >= 0 and int( n) <= 10**9 and isinstance(z, arb): # XXX n = int(n) v = z.bin(n) if v.is_finite(): return v raise ArbFiniteError if head == RisingFactorial: if len(args) == 2: z, n = args z = self.eval(z, **kwargs) n = n.simple() # XXX if n.is_integer() and int(n) >= 0: n = int(n) v = z.rising(n) if v.is_finite(): return v raise ArbFiniteError if head == RiemannZetaZero: if len(args) == 1: n, = args n = n.simple() # XXX if n.is_integer(): n = int(n) if 0 < abs(n) <= 10**8 or ( flint.ctx.prec < 200 and 0 < abs(n) <= 10**12 ): # XXX -- better with timeout? v = acb.zeta_zero(abs(n)) if n < 0: v = v.conjugate() if v.is_finite(): return v raise ArbFiniteError if head in (AiryAiZero, AiryBiZero): if len(args) == 1: n, = args d = Expr(0) elif len(args) == 2: n, d = args n = n.simple() # XXX d = d.simple() if n.is_integer() and d.is_integer(): n = int(n) d = int(d) if n >= 1 and d in (0, 1): if head == AiryAiZero: v = arb.airy_ai_zero(n, d) else: v = arb.airy_bi_zero(n, d) if v.is_finite(): return v raise ArbFiniteError if head == AGM: if len(args) == 1: a, = args a = self.eval(a, **kwargs) v = acb(a).agm() if v.is_finite(): return v raise ArbFiniteError if len(args) == 2: a, b = args a = self.eval(a, **kwargs) b = self.eval(b, **kwargs) v = acb(a).agm(b) if v.is_finite(): return v raise ArbFiniteError # todo: delete if kwargs.get("full_traversal"): for arg in expr.args(): try: self.eval(arg, **kwargs) except (NotImplementedError, ValueError, ArbFiniteError): continue raise ValueError
def plots(outdir): directory[0] = outdir def coverup_rectangle(xy, w, h): gca().add_patch( patches.Rectangle(xy, w, h, linewidth=0, facecolor=realcolor, zorder=2)) def elltheta(z, tau): return tuple(complex(c) for c in acb(z).modular_theta(tau)) theta1 = lambda z, tau: elltheta(z, tau)[0] theta2 = lambda z, tau: elltheta(z, tau)[1] theta3 = lambda z, tau: elltheta(z, tau)[2] theta4 = lambda z, tau: elltheta(z, tau)[3] def ellzeta(z, tau): return complex(acb(z).elliptic_zeta(tau)) def modlambda(tau): if tau.imag < 0.01: return 0.0 return complex(acb(tau).modular_lambda()) def eisene(k, tau): if tau.imag < 0.01: return 0.0 if k == 2: return ellzeta(0.5, tau) / fp.zeta(2) _, a, b, c = elltheta(0, tau) E4 = 0.5 * (a**8 + b**8 + c**8) E6 = 0.5 * (-3 * a**8 * (b**4 + c**4) + b**12 + c**12) E8 = 0.5 * (a**16 + b**16 + c**16) if k == 4: return E4 if k == 6: return E6 if k == 8: return E8 if k == 10: return E4 * E6 if k == 12: return (441 * E4**3 + 250 * E6**2) / 691 if k == 14: return E4**2 * E6 if k == 16: return (1617 * E4**4 + 2000 * E4 * E6**2) / 3617 raise ValueError xrayplot(lambda z: complex(acb(z).digamma()), (-5, 5), (-5, 5), 400, "digamma", xout=0.1, yout=0.1) xrayplot(lambda z: complex(acb(z).polygamma(1)), (-5, 5), (-5, 5), 400, "trigamma", xout=0.1, yout=0.1) xrayplot(lambda tau: 0.0 if tau.imag < 0.13 else theta1(1 / 3. + 0.75j, tau), (-2.5, 2.5), (0, 2), 600, "jacobi_theta_1_tau_b", decorations=lambda: coverup_rectangle((-2.5, 0), 5, 0.14), xout=0.1, yout=0.0, xtks=([-2, -1, 0, 1, 2], ), ytks=([0, 1, 2], )) xrayplot(lambda tau: 0.0 if tau.imag < 0.13 else theta2(1 / 3. + 0.75j, tau), (-2.5, 2.5), (0, 2), 600, "jacobi_theta_2_tau_b", decorations=lambda: coverup_rectangle((-2.5, 0), 5, 0.14), xout=0.1, yout=0.0, xtks=([-2, -1, 0, 1, 2], ), ytks=([0, 1, 2], )) xrayplot(lambda tau: 0.0 if tau.imag < 0.13 else theta3(1 / 3. + 0.75j, tau), (-2.5, 2.5), (0, 2), 600, "jacobi_theta_3_tau_b", decorations=lambda: coverup_rectangle((-2.5, 0), 5, 0.14), xout=0.1, yout=0.0, xtks=([-2, -1, 0, 1, 2], ), ytks=([0, 1, 2], )) xrayplot(lambda tau: 0.0 if tau.imag < 0.13 else theta4(1 / 3. + 0.75j, tau), (-2.5, 2.5), (0, 2), 600, "jacobi_theta_4_tau_b", decorations=lambda: coverup_rectangle((-2.5, 0), 5, 0.14), xout=0.1, yout=0.0, xtks=([-2, -1, 0, 1, 2], ), ytks=([0, 1, 2], )) xrayplot(lambda tau: theta2(0, tau), (-2.5, 2.5), (0, 2), 600, "jacobi_theta_2_tau", xout=0.1, yout=0.0, xtks=([-2, -1, 0, 1, 2], ), ytks=([0, 1, 2], )) xrayplot(lambda tau: theta3(0, tau), (-2.5, 2.5), (0, 2), 600, "jacobi_theta_3_tau", xout=0.1, yout=0.0, xtks=([-2, -1, 0, 1, 2], ), ytks=([0, 1, 2], )) xrayplot(lambda tau: theta4(0, tau), (-2.5, 2.5), (0, 2), 600, "jacobi_theta_4_tau", xout=0.1, yout=0.0, xtks=([-2, -1, 0, 1, 2], ), ytks=([0, 1, 2], )) w3 = 0.25 + 0.75j xrayplot(lambda z: theta1(z, w3), (-2, 2), (-2, 2), 400, "jacobi_theta_1_z_c", xout=0.1, yout=0.1) xrayplot(lambda z: theta2(z, w3), (-2, 2), (-2, 2), 400, "jacobi_theta_2_z_c", xout=0.1, yout=0.1) xrayplot(lambda z: theta3(z, w3), (-2, 2), (-2, 2), 400, "jacobi_theta_3_z_c", xout=0.1, yout=0.1) xrayplot(lambda z: theta4(z, w3), (-2, 2), (-2, 2), 400, "jacobi_theta_4_z_c", xout=0.1, yout=0.1) xrayplot(lambda z: theta1(z, 1j), (-2, 2), (-2, 2), 400, "jacobi_theta_1_z", xout=0.1, yout=0.1) xrayplot(lambda z: theta2(z, 1j), (-2, 2), (-2, 2), 400, "jacobi_theta_2_z", xout=0.1, yout=0.1) xrayplot(lambda z: theta3(z, 1j), (-2, 2), (-2, 2), 400, "jacobi_theta_3_z", xout=0.1, yout=0.1) xrayplot(lambda z: theta4(z, 1j), (-2, 2), (-2, 2), 400, "jacobi_theta_4_z", xout=0.1, yout=0.1) xrayplot(lambda z: theta1(z, 0.5j), (-2, 2), (-2, 2), 400, "jacobi_theta_1_z_b", xout=0.1, yout=0.1) xrayplot(lambda z: theta2(z, 0.5j), (-2, 2), (-2, 2), 400, "jacobi_theta_2_z_b", xout=0.1, yout=0.1) xrayplot(lambda z: theta3(z, 0.5j), (-2, 2), (-2, 2), 400, "jacobi_theta_3_z_b", xout=0.1, yout=0.1) xrayplot(lambda z: theta4(z, 0.5j), (-2, 2), (-2, 2), 400, "jacobi_theta_4_z_b", xout=0.1, yout=0.1) fundament_lambda_x = list(linspace(-1, 0, 80)) fundament_lambda_y = [ 0.5 * sqrt(1 - (2 * x + 1)**2) for x in fundament_lambda_x ] x2 = [x + 1.0 for x in fundament_lambda_x] y2 = fundament_lambda_y[:] fundament_lambda_x = fundament_lambda_x + x2 fundament_lambda_y = fundament_lambda_y + y2 fundament_lambda_x = [-1.0] + fundament_lambda_x + [1.0] fundament_lambda_y = [2.0] + fundament_lambda_y + [2.0] def lambda_decorations(): coverup_rectangle((-1.5, 0), 3, 0.015) coverup_rectangle((-0.05, 0), 0.1, 0.1) fill(fundament_lambda_x, fundament_lambda_y, facecolor=highlightcolor, edgecolor=highlightbordercolor, alpha=0.5, linewidth=0.5, zorder=2) xrayplot(lambda tau: modlambda(tau), (-1.5, 1.5), (0, 2), 600, "modular_lambda", xtks=([-1.5, -1, -0.5, 0, 0.5, 1, 1.5], ), ytks=([0, 0.5, 1, 1.5, 2], ), decorations=lambda_decorations, xout=0.1, yout=0.0) fundament_x = list(linspace(-0.5, 0.5, 100)) fundament_y = [sqrt(1 - x**2) for x in fundament_x] fundament_x = [-0.5] + fundament_x + [0.5] fundament_y = [2.0] + fundament_y + [2.0] def eisenstein_decorations(): coverup_rectangle((-1, 0), 2, 0.015) fill(fundament_x, fundament_y, facecolor=highlightcolor, edgecolor=highlightbordercolor, alpha=0.5, linewidth=0.5, zorder=2) xrayplot(lambda tau: eisene(2, tau), (-1, 1), (0, 2), 600, "eisenstein_e2", xtks=([-1, -0.5, 0, 0.5, 1], ), ytks=([0, 0.5, 1, 1.5, 2], ), decorations=eisenstein_decorations, xout=0.1, yout=0.0) xrayplot(lambda tau: eisene(4, tau), (-1, 1), (0, 2), 600, "eisenstein_e4", xtks=([-1, -0.5, 0, 0.5, 1], ), ytks=([0, 0.5, 1, 1.5, 2], ), decorations=eisenstein_decorations, xout=0.1, yout=0.0) xrayplot(lambda tau: eisene(6, tau), (-1, 1), (0, 2), 600, "eisenstein_e6", xtks=([-1, -0.5, 0, 0.5, 1], ), ytks=([0, 0.5, 1, 1.5, 2], ), decorations=eisenstein_decorations, xout=0.1, yout=0.0) xrayplot(lambda tau: eisene(8, tau), (-1, 1), (0, 2), 600, "eisenstein_e8", xtks=([-1, -0.5, 0, 0.5, 1], ), ytks=([0, 0.5, 1, 1.5, 2], ), decorations=eisenstein_decorations, xout=0.1, yout=0.0) xrayplot(lambda tau: eisene(10, tau), (-1, 1), (0, 2), 600, "eisenstein_e10", xtks=([-1, -0.5, 0, 0.5, 1], ), ytks=([0, 0.5, 1, 1.5, 2], ), decorations=eisenstein_decorations, xout=0.1, yout=0.0) xrayplot(lambda tau: eisene(12, tau), (-1, 1), (0, 2), 600, "eisenstein_e12", xtks=([-1, -0.5, 0, 0.5, 1], ), ytks=([0, 0.5, 1, 1.5, 2], ), decorations=eisenstein_decorations, xout=0.1, yout=0.0) def zeta_decorations(): axvspan(0, 1, alpha=0.5, color=highlightcolor) axvline(0, alpha=0.5, color=highlightbordercolor, linewidth=0.5) axvline(1, alpha=0.5, color=highlightbordercolor, linewidth=0.5) xrayplot(lambda z: complex(acb(z).zeta()), (-22, 22), (-27, 27), 400, "zeta", zeta_decorations, xout=0.1, yout=0.1) def plot_elliptic(tau, filename): xrayplot( lambda z: complex(acb(z).elliptic_p(tau)), (-1.5, 1.5), (-1.5, 1.5), 400, filename, xout=0.1, yout=0.1, xtks=([-1, 0, 1], ), ytks=([-1, 0, 1], ), decorations=lambda: fill([0.0, 1.0, tau.real + 1.0, tau.real, 0.0], [0.0, 0.0, tau.imag, tau.imag, 0.0], facecolor=highlightcolor, edgecolor=highlightbordercolor, alpha=0.5, linewidth=0.5, zorder=2)) plot_elliptic(1j, "elliptic_p") plot_elliptic(0.5 + 0.75**0.5 * 1j, "elliptic_p_2") plot_elliptic(-0.8 + 0.7j, "elliptic_p_3") xrayplot(lambda z: complex(acb(z).airy_ai()), (-6, 6), (-6, 6), 400, "airy_ai", xout=0.1, yout=0.1) xrayplot(lambda z: complex(acb(z).airy_bi()), (-6, 6), (-6, 6), 400, "airy_bi", xout=0.1, yout=0.1) xrayplot(lambda z: complex(acb(z).erf()), (-4, 4), (-4, 4), 400, "erf", xout=0.1, yout=0.1) def lgamma_decor(): branchcutline(0, -1, offset=0.07) branchcutline(-1, -2, offset=0.07) branchcutline(-2, -3, offset=0.07) branchcutline(-3, -4, offset=0.07) branchcutline(-4, -5, offset=0.07) xrayplot(lambda z: complex(acb(z).lgamma()), (-5, 5), (-5, 5), 400, "log_gamma", xout=0.1, yout=0.1, decorations=lgamma_decor) def atan_decor(): branchcutline(1j, 10j) branchcutline(-1j, -10j) xrayplot(lambda z: complex(acb(z).log()), (-3, 3), (-3, 3), 400, "log", xout=0.1, yout=0.1, decorations=lambda: branchcutline(0, -10, offset=0.05)) xrayplot(lambda z: complex(acb(z).sqrt()), (-3, 3), (-3, 3), 400, "sqrt", xout=0.1, yout=0.1, decorations=lambda: branchcutline(0, -10, offset=0.05)) xrayplot(lambda z: complex(acb(z).atan()), (-2, 2), (-2, 2), 400, "atan", xout=0.1, yout=0.1, decorations=atan_decor) xrayplot(lambda z: complex(acb(z).lambertw()), (-3, 3), (-3, 3), 400, "lambertw", xout=0.1, yout=0.1, decorations=lambda: branchcutline(-exp(-1), -10, offset=0.05)) xrayplot(lambda z: complex(acb(z).exp()), (-5, 5), (-5, 5), 400, "exp", xout=0.1, yout=0.1) xrayplot(lambda z: complex(acb(z).sin()), (-5, 5), (-5, 5), 400, "sin", xout=0.1, yout=0.1) xrayplot(lambda z: complex(acb(z).gamma()), (-5, 5), (-5, 5), 400, "gamma", xout=0.1, yout=0.1) def coverup_rectangle(xy, w, h): gca().add_patch( patches.Rectangle(xy, w, h, linewidth=0, facecolor=realcolor, zorder=2)) def modj(z): if z.imag < 0.03: return 0.0 return complex(acb(z).modular_j()) / 1728.0 fundament_x = list(linspace(-0.5, 0.5, 100)) fundament_y = [sqrt(1 - x**2) for x in fundament_x] fundament_x = [-0.5] + fundament_x + [0.5] fundament_y = [2.0] + fundament_y + [2.0] def modular_j_decorations(): coverup_rectangle((-1, 0), 2, 0.04) coverup_rectangle((-1, 0), 0.1, 0.1) coverup_rectangle((-0.1, 0), 0.2, 0.1) coverup_rectangle((0.9, 0), 0.1, 0.1) fill(fundament_x, fundament_y, facecolor=highlightcolor, edgecolor=highlightbordercolor, alpha=0.5, linewidth=0.5, zorder=2) xrayplot(modj, (-1, 1), (0, 2), 600, "modular_j", xtks=([-1, -0.5, 0, 0.5, 1], ), ytks=([0, 0.5, 1, 1.5, 2], ), decorations=modular_j_decorations, xout=0.1, yout=0.0)
def guess(z, deg=None, verbose=False, try_smaller=True, check=True): """ Use LLL to try to find an algebraic number matching the real or complex enclosure *z* (given as a *flint.arb* or *flint.acb*). Returns *None* if unsuccessful. To determine the number of bits to use in the LLL matrix, the algorithm accounts for the accuracy of the input as well as the current Arb working precision (*flint.ctx.prec*). The maximum degree is determined by the *deg* parameter. By default the degree is set to roughly the square root of the working precision. If *try_smaller* is set, then the guessing is attempted recursively with lower degree bounds to speed up detection of lower-degree numbers. If *check* is True (default), the algorithm verifies that the result is contained in the complex interval *z*. (At high precision, this reduces the likelihood of spurious results.) """ z = acb(z) if not z.is_finite(): return None if deg is None: deg = max(1, int(ctx.prec**0.5)) if try_smaller and deg > 8: g = alg.guess(z, deg // 4, verbose=verbose, try_smaller=True, check=check) if g is not None: return g # todo: early detect exact (dyadic) real and imaginary parts? # (avoid reliance on enclosure(pretty=True) prec = ctx.prec z = acb(z) zpow = [z**i for i in range(deg + 1)] magn = max(abs(t) for t in zpow) if magn >= arb(2)**prec: return None # too large magnrad = max(abs(t.rad()) for t in zpow) if magnrad >= 0.125: return None # too imprecise magnrad = max(2**(max(1, prec // 20)) * magnrad, arb(2)**(-2 * prec)) scale = 1 / magnrad nonreal = z.imag != 0 A = fmpz_mat(deg + 1, deg + 2 + nonreal) for i in range(deg + 1): A[i, i] = 1 for i in range(deg + 1): v = zpow[i] * scale # fixme: don't use unique_fmpz A[i, deg + 1] = v.real.mid().floor().unique_fmpz() if nonreal: A[i, deg + 2] = v.imag.mid().floor().unique_fmpz() A = A.lll() poly = fmpz_poly([A[0, i] for i in range(deg + 1)]) if verbose: print("LLL-reduced matrix:") print(A) print("poly(z) =", poly(z)) if not check: candidates = alg.polynomial_roots(poly) or [(alg(0), 1)] return min([cand for (cand, mult) in candidates], key=lambda x: abs(x.enclosure() - z).mid()) if not poly(z).contains(0): return None orig = ctx.prec try: candidates = alg.polynomial_roots(poly) while ctx.prec <= 16 * orig: for cand, mult in candidates: r = cand.enclosure(pretty=True) if z.contains(r): return cand ctx.prec *= 2 finally: ctx.prec = orig return None
def elltheta(z, tau): return tuple(complex(c) for c in acb(z).modular_theta(tau))
def plots(outdir): directory[0] = outdir def zeta_decorations(): axvspan(0, 1, alpha=0.5, color=highlightcolor) axvline(0, alpha=0.5, color=highlightbordercolor, linewidth=0.5) axvline(1, alpha=0.5, color=highlightbordercolor, linewidth=0.5) xrayplot(lambda z: complex(acb(z).zeta()), (-22,22), (-27,27), 400, "zeta", zeta_decorations, xout=0.1, yout=0.1) def plot_elliptic(tau, filename): xrayplot(lambda z: complex(acb(z).elliptic_p(tau)), (-1.5,1.5), (-1.5,1.5), 400, filename, xout=0.1, yout=0.1, xtks=([-1,0,1],), ytks=([-1,0,1],), decorations=lambda: fill([0.0, 1.0, tau.real+1.0, tau.real, 0.0], [0.0, 0.0, tau.imag, tau.imag, 0.0], facecolor=highlightcolor, edgecolor=highlightbordercolor, alpha=0.5, linewidth=0.5, zorder=2)) plot_elliptic(1j, "elliptic_p") plot_elliptic(0.5+0.75**0.5*1j, "elliptic_p_2") plot_elliptic(-0.8+0.7j, "elliptic_p_3") xrayplot(lambda z: complex(acb(z).airy_ai()), (-6,6), (-6,6), 400, "airy_ai", xout=0.1, yout=0.1) xrayplot(lambda z: complex(acb(z).airy_bi()), (-6,6), (-6,6), 400, "airy_bi", xout=0.1, yout=0.1) xrayplot(lambda z: complex(acb(z).erf()), (-4,4), (-4,4), 400, "erf", xout=0.1, yout=0.1) def lgamma_decor(): branchcutline(0, -1, offset=0.07) branchcutline(-1, -2, offset=0.07) branchcutline(-2, -3, offset=0.07) branchcutline(-3, -4, offset=0.07) branchcutline(-4, -5, offset=0.07) xrayplot(lambda z: complex(acb(z).lgamma()), (-5,5), (-5,5), 400, "log_gamma", xout=0.1, yout=0.1, decorations=lgamma_decor) def atan_decor(): branchcutline(1j, 10j) branchcutline(-1j, -10j) xrayplot(lambda z: complex(acb(z).log()), (-3,3), (-3,3), 400, "log", xout=0.1, yout=0.1, decorations=lambda: branchcutline(0, -10, offset=0.05)) xrayplot(lambda z: complex(acb(z).sqrt()), (-3,3), (-3,3), 400, "sqrt", xout=0.1, yout=0.1, decorations=lambda: branchcutline(0, -10, offset=0.05)) xrayplot(lambda z: complex(acb(z).atan()), (-2,2), (-2,2), 400, "atan", xout=0.1, yout=0.1, decorations=atan_decor) xrayplot(lambda z: complex(acb(z).lambertw()), (-3,3), (-3,3), 400, "lambertw", xout=0.1, yout=0.1, decorations=lambda: branchcutline(-exp(-1), -10, offset=0.05)) xrayplot(lambda z: complex(acb(z).exp()), (-5,5), (-5,5), 400, "exp", xout=0.1, yout=0.1) xrayplot(lambda z: complex(acb(z).sin()), (-5,5), (-5,5), 400, "sin", xout=0.1, yout=0.1) xrayplot(lambda z: complex(acb(z).gamma()), (-5,5), (-5,5), 400, "gamma", xout=0.1, yout=0.1) def coverup_rectangle(xy,w,h): gca().add_patch(patches.Rectangle(xy,w,h,linewidth=0,facecolor=realcolor,zorder=2)) def modj(z): if z.imag < 0.03: return 0.0 return complex(acb(z).modular_j())/1728.0 fundament_x = list(linspace(-0.5,0.5,100)) fundament_y = [sqrt(1-x**2) for x in fundament_x] fundament_x = [-0.5] + fundament_x + [0.5] fundament_y = [2.0] + fundament_y + [2.0] def modular_j_decorations(): coverup_rectangle((-1,0),2,0.04) coverup_rectangle((-1,0),0.1,0.1) coverup_rectangle((-0.1,0),0.2,0.1) coverup_rectangle((0.9,0),0.1,0.1) fill(fundament_x, fundament_y, facecolor=highlightcolor, edgecolor=highlightbordercolor, alpha=0.5, linewidth=0.5, zorder=2) xrayplot(modj, (-1,1), (0,2), 600, "modular_j", xtks=([-1,-0.5,0,0.5,1],), ytks=([0,0.5,1,1.5,2],), decorations=modular_j_decorations, xout=0.1, yout=0.0)
def imag(self): if self.is_real(): return alg(0) return (self - self.conjugate()) / alg(_minpoly=fmpz_poly([4, 0, 1]), _enclosure=acb(0, 2))