@@ -130,6 +130,15 @@ cdef class acb(flint_scalar):
130130 if not arb_set_python(acb_imagref(self .val), imag, 1 ):
131131 raise TypeError (" cannot create arb from type %s " % type (imag))
132132
133+ cpdef bint is_zero(self ):
134+ return acb_is_zero(self .val)
135+
136+ cpdef bint is_finite(self ):
137+ return acb_is_finite(self .val)
138+
139+ cpdef bint is_exact(self ):
140+ return acb_is_exact(self .val)
141+
133142 @property
134143 def real (self ):
135144 cdef arb re = arb()
@@ -175,10 +184,17 @@ cdef class acb(flint_scalar):
175184 other = any_as_acb(other)
176185 return bool (acb_contains(self .val, (< acb> other).val))
177186
187+ def contains_interior (self , other ):
188+ other = any_as_acb(other)
189+ return bool (acb_contains_interior(self .val, (< acb> other).val))
190+
178191 def overlaps (self , other ):
179192 other = any_as_acb(other)
180193 return bool (acb_overlaps((< acb> self ).val, (< acb> other).val))
181194
195+ def contains_integer (self ):
196+ return bool (acb_contains_int(self .val))
197+
182198 def mid (self ):
183199 """
184200 Returns an exact *acb* representing the midpoint of *self*:
@@ -254,6 +270,23 @@ cdef class acb(flint_scalar):
254270 acb_neg_round((< acb> res).val, (< acb> self ).val, getprec())
255271 return res
256272
273+ def neg (self , bint exact = False ):
274+ res = acb.__new__ (acb)
275+ if exact:
276+ acb_set((< acb> res).val, (< acb> self ).val)
277+ else :
278+ acb_set_round((< acb> res).val, (< acb> self ).val, getprec())
279+ return res
280+
281+ def conjugate (self , bint exact = False ):
282+ res = acb.__new__ (acb)
283+ if exact:
284+ acb_conj((< acb> res).val, (< acb> self ).val)
285+ else :
286+ acb_set_round((< acb> res).val, (< acb> self ).val, getprec())
287+ acb_conj((< acb> res).val, (< acb> res).val)
288+ return res
289+
257290 def __abs__ (self ):
258291 res = arb.__new__ (arb)
259292 acb_abs((< arb> res).val, (< acb> self ).val, getprec())
@@ -377,8 +410,9 @@ cdef class acb(flint_scalar):
377410 if ttype == FMPZ_TMP: acb_clear(tval)
378411 return u
379412
413+ # important: must not be cdef because of cython magic
380414 @staticmethod
381- cdef _div_(s, t):
415+ def _div_ (s , t ):
382416 cdef acb_struct sval[1 ]
383417 cdef acb_struct tval[1 ]
384418 cdef int stype, ttype
@@ -418,6 +452,12 @@ cdef class acb(flint_scalar):
418452 if ttype == FMPZ_TMP: acb_clear(tval)
419453 return u
420454
455+ def union (s , t ):
456+ v = acb.__new__ (acb)
457+ t = any_as_acb(t)
458+ acb_union((< acb> v).val, (< acb> s).val, (< acb> t).val, getprec())
459+ return v
460+
421461 def pow (s , t , bint analytic = False ):
422462 """
423463 Power `s^t`.
@@ -545,7 +585,10 @@ cdef class acb(flint_scalar):
545585 acb_agm1((< acb> u).val, (< acb> s).val, getprec())
546586 return u
547587 else :
548- return (s / t).agm() * t
588+ t = acb(t)
589+ u = acb.__new__ (acb)
590+ acb_agm((< acb> u).val, (< acb> s).val, (< acb> t).val, getprec())
591+ return u
549592
550593 def gamma (s ):
551594 """
@@ -620,6 +663,16 @@ cdef class acb(flint_scalar):
620663 acb_hurwitz_zeta((< acb> u).val, (< acb> s).val, (< acb> a).val, getprec())
621664 return u
622665
666+ def dirichlet_l (s , chi ):
667+ cdef dirichlet_char cchar
668+ if isinstance (chi, dirichlet_char):
669+ cchar = chi
670+ else :
671+ cchar = dirichlet_char(chi[0 ], chi[1 ])
672+ u = acb.__new__ (acb)
673+ acb_dirichlet_l((< acb> u).val, (< acb> s).val, cchar.G.val, cchar.val, getprec())
674+ return u
675+
623676 @staticmethod
624677 def pi ():
625678 """
@@ -994,7 +1047,7 @@ cdef class acb(flint_scalar):
9941047 acb_hypgeom_erf((< acb> u).val, (< acb> s).val, getprec())
9951048 return u
9961049
997- def modular_theta (z , tau ):
1050+ def modular_theta (z , tau , ulong r = 0 ):
9981051 r """
9991052 Computes the Jacobi theta functions `\t heta_1( z,\t au) `,
10001053 `\t heta_2( z,\t au) `, `\t heta_3( z,\t au) `, `\t heta_4( z,\t au) `,
@@ -1011,14 +1064,37 @@ cdef class acb(flint_scalar):
10111064 0. 9694430387796704100046143 - 0. 03055696120816803328582847j
10121065 1. 030556961196006476576271 + 0. 03055696120816803328582847j
10131066 """
1067+ cdef acb_ptr T1, T2, T3, T4
1068+ assert r <= 1000000
10141069 tau = any_as_acb(tau)
10151070 t1 = acb.__new__ (acb)
10161071 t2 = acb.__new__ (acb)
10171072 t3 = acb.__new__ (acb)
10181073 t4 = acb.__new__ (acb)
1019- acb_modular_theta((< acb> t1).val, (< acb> t2).val,
1020- (< acb> t3).val, (< acb> t4).val,
1021- (< acb> z).val, (< acb> tau).val, getprec())
1074+ if r == 0 :
1075+ acb_modular_theta((< acb> t1).val, (< acb> t2).val,
1076+ (< acb> t3).val, (< acb> t4).val,
1077+ (< acb> z).val, (< acb> tau).val, getprec())
1078+ else :
1079+ T1 = _acb_vec_init(r + 1 )
1080+ T2 = _acb_vec_init(r + 2 )
1081+ T3 = _acb_vec_init(r + 3 )
1082+ T4 = _acb_vec_init(r + 4 )
1083+ acb_modular_theta_jet(T1, T2, T3, T4,
1084+ (< acb> z).val, (< acb> tau).val, r + 1 , getprec())
1085+ acb_set((< acb> t1).val, T1 + r)
1086+ acb_set((< acb> t2).val, T2 + r)
1087+ acb_set((< acb> t3).val, T3 + r)
1088+ acb_set((< acb> t4).val, T4 + r)
1089+ c = arb.fac_ui(r)
1090+ t1 *= c
1091+ t2 *= c
1092+ t3 *= c
1093+ t4 *= c
1094+ _acb_vec_clear(T1, r + 1 )
1095+ _acb_vec_clear(T2, r + 1 )
1096+ _acb_vec_clear(T3, r + 1 )
1097+ _acb_vec_clear(T4, r + 1 )
10221098 return (t1, t2, t3, t4)
10231099
10241100 def modular_eta (tau ):
@@ -2267,6 +2343,63 @@ cdef class acb(flint_scalar):
22672343 acb_root_ui((< acb> v).val, (< acb> s).val, n, getprec())
22682344 return v
22692345
2346+ @staticmethod
2347+ def zeta_zero (n ):
2348+ """
2349+ Returns the *n*-th nontrivial zero of the Riemann zeta function.
2350+
2351+ >>> showgood(lambda: acb.zeta_zero(1), dps=25)
2352+ 0.5000000000000000000000000 + 14.13472514173469379045725j
2353+ >>> showgood(lambda: acb.zeta_zero(2), dps=25)
2354+ 0.5000000000000000000000000 + 21.02203963877155499262848j
2355+ >>> showgood(lambda: acb.zeta_zero(100), dps=25)
2356+ 0.5000000000000000000000000 + 236.5242296658162058024755j
2357+ >>> showgood(lambda: acb.zeta_zero(10**6), dps=25)
2358+ 0.5000000000000000000000000 + 600269.6770124449555212339j
2359+ """
2360+ n = fmpz(n)
2361+ if n < 1 :
2362+ raise ValueError (" require n >= 1" )
2363+ v = acb.__new__ (acb)
2364+ acb_dirichlet_zeta_zero((< acb> v).val, (< fmpz> n).val, getprec())
2365+ return v
2366+
2367+ @staticmethod
2368+ def zeta_zeros (n , long num ):
2369+ """
2370+ Returns *num* consecutive nontrivial zeros of the Riemann zeta function
2371+ starting at index *n*.
2372+
2373+ >>> for r in acb.zeta_zeros(1000, 10):
2374+ ... print(r.str(10, radius=False))
2375+ ...
2376+ 0.5000000000 + 1419.422481j
2377+ 0.5000000000 + 1420.416526j
2378+ 0.5000000000 + 1421.850567j
2379+ 0.5000000000 + 1422.461311j
2380+ 0.5000000000 + 1424.463046j
2381+ 0.5000000000 + 1425.873469j
2382+ 0.5000000000 + 1426.645980j
2383+ 0.5000000000 + 1427.365671j
2384+ 0.5000000000 + 1428.592306j
2385+ 0.5000000000 + 1429.650477j
2386+ """
2387+ cdef long i
2388+ cdef acb_ptr w
2389+ cdef list v
2390+ n = fmpz(n)
2391+ if n < 1 or num < 0 :
2392+ raise ValueError (" require n >= 1 and num >= 0" )
2393+ v = [acb() for i in range (num)]
2394+ w = < acb_ptr> libc.stdlib.malloc(num * cython.sizeof(acb_struct))
2395+ for i in range (num):
2396+ w[i] = (< acb> (v[i])).val[0 ]
2397+ acb_dirichlet_zeta_zeros(w, (< fmpz> n).val, num, getprec())
2398+ for i in range (num):
2399+ (< acb> (v[i])).val[0 ] = w[i]
2400+ libc.stdlib.free(w)
2401+ return v
2402+
22702403 @staticmethod
22712404 def integral (func , a , b , params = None ,
22722405 rel_tol = None , abs_tol = None ,
@@ -2376,3 +2509,55 @@ cdef class acb(flint_scalar):
23762509 raise ictx.exn_type, ictx.exn_obj, ictx.exn_tb
23772510
23782511 return res
2512+
2513+ def coulomb (self , l , eta ):
2514+ r """
2515+ Computes the Coulomb wave functions `F_{\e ll}( \e ta,z) `,
2516+ `G_{\e ll}( \e ta,z) `, `H^ {+ }_{\e ll}( \e ta,z) `, `H^ {-}_{\e ll}( \e ta,z) `
2517+ where * z* is given by * self* .
2518+ All function values are computed simultaneously and a tuple
2519+ is returned.
2520+
2521+ >>> showgood( lambda: acb( 1) . coulomb( 0. 5, 0. 25) , dps=10)
2522+ ( 0. 4283180781, 1. 218454487, 1. 218454487 + 0. 4283180781j, 1. 218454487 - 0. 4283180781j)
2523+ """
2524+ l = any_as_acb(l)
2525+ eta = any_as_acb(eta)
2526+ F = acb.__new__ (acb)
2527+ G = acb.__new__ (acb)
2528+ Hpos = acb.__new__ (acb)
2529+ Hneg = acb.__new__ (acb)
2530+ acb_hypgeom_coulomb((< acb> F).val, (< acb> G).val, (< acb> Hpos).val, (< acb> Hneg).val,
2531+ (< acb> l).val, (< acb> eta).val, (< acb> self ).val, getprec())
2532+ return F, G, Hpos, Hneg
2533+
2534+ def coulomb_f (self , l , eta ):
2535+ r """
2536+ Regular Coulomb wave function `F_{\e ll}( \e ta,z) ` where
2537+ * z* is given by * self* .
2538+
2539+ >>> showgood( lambda: acb( 1+ 1j) . coulomb_f( 0. 5, 0. 25) , dps=25)
2540+ 0. 3710338871231483199425544 + 0. 7267604204004146050054782j
2541+ """
2542+ l = any_as_acb(l)
2543+ eta = any_as_acb(eta)
2544+ F = acb.__new__ (acb)
2545+ acb_hypgeom_coulomb((< acb> F).val, NULL , NULL , NULL ,
2546+ (< acb> l).val, (< acb> eta).val, (< acb> self ).val, getprec())
2547+ return F
2548+
2549+ def coulomb_g (self , l , eta ):
2550+ r """
2551+ Irregular Coulomb wave function `G_{\e ll}( \e ta,z) ` where
2552+ * z* is given by * self* .
2553+
2554+ >>> showgood( lambda: acb( 1+ 1j) . coulomb_g( 0. 5, 0. 25) , dps=25)
2555+ 1. 293346292234270672155324 - 0. 3516893313311703662702556j
2556+ """
2557+ l = any_as_acb(l)
2558+ eta = any_as_acb(eta)
2559+ G = acb.__new__ (acb)
2560+ acb_hypgeom_coulomb(NULL , (< acb> G).val, NULL , NULL ,
2561+ (< acb> l).val, (< acb> eta).val, (< acb> self ).val, getprec())
2562+ return G
2563+
0 commit comments