Skip to content

Commit def8da5

Browse files
more updates (some depending on flint trunk)
1 parent 26f46ff commit def8da5

9 files changed

Lines changed: 257 additions & 2 deletions

File tree

src/acb.pyx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,23 @@ cdef class acb(flint_scalar):
266266
acb_neg_round((<acb>res).val, (<acb>self).val, getprec())
267267
return res
268268

269+
def neg(self, bint exact=False):
270+
res = acb.__new__(acb)
271+
if exact:
272+
acb_set((<acb>res).val, (<acb>self).val)
273+
else:
274+
acb_set_round((<acb>res).val, (<acb>self).val, getprec())
275+
return res
276+
277+
def conjugate(self, bint exact=False):
278+
res = acb.__new__(acb)
279+
if exact:
280+
acb_conj((<acb>res).val, (<acb>self).val)
281+
else:
282+
acb_set_round((<acb>res).val, (<acb>self).val, getprec())
283+
acb_conj((<acb>res).val, (<acb>res).val)
284+
return res
285+
269286
def __abs__(self):
270287
res = arb.__new__(arb)
271288
acb_abs((<arb>res).val, (<acb>self).val, getprec())
@@ -431,6 +448,12 @@ cdef class acb(flint_scalar):
431448
if ttype == FMPZ_TMP: acb_clear(tval)
432449
return u
433450

451+
def union(s, t):
452+
v = acb.__new__(acb)
453+
t = any_as_acb(t)
454+
acb_union((<acb>v).val, (<acb>s).val, (<acb>t).val, getprec())
455+
return v
456+
434457
def pow(s, t, bint analytic=False):
435458
"""
436459
Power `s^t`.

src/arb.pyx

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,25 @@ cdef class arb(flint_scalar):
230230
arf_get_fmpz_2exp(man.val, exp.val, arb_midref(self.val))
231231
return man, exp
232232

233+
def fmpq(self):
234+
cdef fmpq res
235+
if not self.is_finite() or not self.is_exact():
236+
raise ValueError("fmpq requires an exact, finite value")
237+
res = fmpq()
238+
arf_get_fmpq(res.val, arb_midref(self.val))
239+
return res
240+
241+
def fmpz(self):
242+
cdef fmpz res
243+
if not self.is_integer():
244+
raise ValueError("fmpz requires an exact, integer value")
245+
res = fmpz()
246+
arf_get_fmpz(res.val, arb_midref(self.val), ARF_RND_DOWN)
247+
return res
248+
249+
cpdef bint is_integer(self):
250+
return arb_is_int(self.val)
251+
233252
def mid(self):
234253
"""
235254
Returns the midpoint of *self* as an exact *arb*:
@@ -479,6 +498,14 @@ cdef class arb(flint_scalar):
479498
def contains_integer(self):
480499
return bool(arb_contains_int(self.val))
481500

501+
@property
502+
def real(self):
503+
return self
504+
505+
@property
506+
def imag(self):
507+
return arb()
508+
482509
def __pos__(self):
483510
res = arb.__new__(arb)
484511
arb_set_round((<arb>res).val, (<arb>self).val, getprec())
@@ -489,6 +516,14 @@ cdef class arb(flint_scalar):
489516
arb_neg_round((<arb>res).val, (<arb>self).val, getprec())
490517
return res
491518

519+
def neg(self, bint exact=False):
520+
res = arb.__new__(arb)
521+
if exact:
522+
arb_set((<arb>res).val, (<arb>self).val)
523+
else:
524+
arb_set_round((<arb>res).val, (<arb>self).val, getprec())
525+
return res
526+
492527
def __abs__(self):
493528
res = arb.__new__(arb)
494529
arb_abs((<arb>res).val, (<arb>self).val)

src/flint.pxd

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ cdef extern from "flint/nmod_mat.h":
180180

181181
cdef extern from "flint/ulong_extras.h":
182182
ulong n_gcd(ulong n, ulong k)
183+
int n_is_prime(ulong n)
183184

184185
cdef extern from "flint/fmpz.h":
185186
ctypedef fmpz_struct fmpz_t[1]
@@ -210,6 +211,7 @@ cdef extern from "flint/fmpz.h":
210211
int fmpz_cmp_ui( fmpz_t f, ulong g)
211212
int fmpz_cmp_si( fmpz_t f, long g)
212213
int fmpz_cmpabs( fmpz_t f, fmpz_t g)
214+
int fmpz_equal_si(const fmpz_t f, long g)
213215
int fmpz_is_even(fmpz_t f)
214216
int fmpz_is_odd(fmpz_t f)
215217
mp_size_t fmpz_size(fmpz_t f)
@@ -235,6 +237,7 @@ cdef extern from "flint/fmpz.h":
235237
int fmpz_sqrtmod(fmpz_t b, fmpz_t a, fmpz_t p)
236238
void fmpz_sqrt(fmpz_t f, fmpz_t g)
237239
void fmpz_sqrtrem(fmpz_t f, fmpz_t r, fmpz_t g)
240+
void fmpz_root(fmpz_t r, const fmpz_t f, long n)
238241
ulong fmpz_fdiv_ui(fmpz_t g, ulong h)
239242
ulong fmpz_mod_ui(fmpz_t f, fmpz_t g, ulong h)
240243
void fmpz_mod(fmpz_t f, fmpz_t g, fmpz_t h)
@@ -393,6 +396,8 @@ cdef extern from "flint/fmpz_poly.h":
393396
void fmpz_poly_cos_minpoly(fmpz_poly_t, ulong)
394397
void fmpz_poly_swinnerton_dyer(fmpz_poly_t, ulong)
395398

399+
int fmpz_poly_sqrt(fmpz_poly_t b, const fmpz_poly_t a)
400+
396401
cdef extern from "flint/fmpz_poly_factor.h":
397402
void fmpz_poly_factor_init(fmpz_poly_factor_t fac)
398403
void fmpz_poly_factor_clear(fmpz_poly_factor_t fac)
@@ -451,6 +456,9 @@ cdef extern from "flint/fmpz_mat.h":
451456
void fmpz_mat_snf(fmpz_mat_t S, const fmpz_mat_t A)
452457
int fmpz_mat_is_in_snf(const fmpz_mat_t A)
453458

459+
void fmpz_mat_charpoly(fmpz_poly_t cp, const fmpz_mat_t mat)
460+
void fmpz_mat_minpoly(fmpz_poly_t cp, const fmpz_mat_t mat)
461+
454462
cdef extern from "flint/fmpz_lll.h":
455463
ctypedef struct fmpz_lll_struct:
456464
double delta
@@ -675,6 +683,9 @@ cdef extern from "flint/fmpq_mat.h":
675683
long fmpq_mat_rref(fmpq_mat_t B, fmpq_mat_t A)
676684
void fmpq_mat_transpose(fmpq_mat_t B, fmpq_mat_t A)
677685

686+
void fmpq_mat_charpoly(fmpq_poly_t cp, const fmpq_mat_t mat)
687+
void fmpq_mat_minpoly(fmpq_poly_t cp, const fmpq_mat_t mat)
688+
678689
cdef extern from "flint/arith.h":
679690
void arith_number_of_partitions(fmpz_t res, ulong n)
680691
int arith_moebius_mu(fmpz_t n)
@@ -722,6 +733,9 @@ cdef extern from "arf.h":
722733
ctypedef int arf_rnd_t
723734
cdef arf_rnd_t ARF_RND_DOWN
724735
cdef arf_rnd_t ARF_RND_NEAR
736+
cdef arf_rnd_t ARF_RND_FLOOR
737+
cdef arf_rnd_t ARF_RND_CEIL
738+
cdef arf_rnd_t ARF_RND_UP
725739

726740
void arf_init(arf_t x)
727741
void arf_clear(arf_t x)
@@ -1170,6 +1184,7 @@ cdef extern from "acb.h":
11701184
int acb_contains(const acb_t x, const acb_t y)
11711185
int acb_get_unique_fmpz(fmpz_t z, const acb_t x)
11721186
int acb_contains_int(const acb_t x)
1187+
void acb_union(acb_t z, const acb_t x, const acb_t y, long prec)
11731188
void acb_set_ui(acb_t z, ulong c)
11741189
void acb_set_si(acb_t z, long c)
11751190
void acb_set_fmpz(acb_t z, const fmpz_t c)
@@ -2183,6 +2198,8 @@ cdef extern from "arb_fmpz_poly.h":
21832198
void arb_fmpz_poly_evaluate_arb(arb_t res, const fmpz_poly_t poly, const arb_t x, long prec)
21842199
void arb_fmpz_poly_evaluate_acb(acb_t res, const fmpz_poly_t poly, const acb_t x, long prec)
21852200
void arb_fmpz_poly_complex_roots(acb_ptr roots, const fmpz_poly_t poly, int flags, long prec)
2201+
ulong arb_fmpz_poly_deflation(const fmpz_poly_t poly)
2202+
void arb_fmpz_poly_deflate(fmpz_poly_t res, const fmpz_poly_t poly, ulong deflation)
21862203

21872204
cdef extern from "acb_dft.h":
21882205
void acb_dft(acb_ptr w, acb_srcptr v, long n, long prec)

src/fmpq.pyx

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,13 @@ cdef class fmpq(flint_scalar):
7474
res = not res
7575
return res
7676
else:
77-
raise NotImplementedError("fmpq comparisons")
77+
# todo: use fmpq_cmp when available
78+
if op == 0: res = (s-t).p < 0
79+
elif op == 1: res = (s-t).p <= 0
80+
elif op == 4: res = (s-t).p > 0
81+
elif op == 5: res = (s-t).p >= 0
82+
else: raise ValueError
83+
return res
7884

7985
def numer(self):
8086
"""
@@ -272,3 +278,27 @@ cdef class fmpq(flint_scalar):
272278
cdef fmpq v = fmpq()
273279
fmpq_harmonic_ui(v.val, n)
274280
return v
281+
282+
def floor(self):
283+
cdef fmpz r = fmpz.__new__(fmpz)
284+
fmpz_fdiv_q(r.val, fmpq_numref(self.val), fmpq_denref(self.val))
285+
return r
286+
287+
def ceil(self):
288+
cdef fmpz r = fmpz.__new__(fmpz)
289+
fmpz_cdiv_q(r.val, fmpq_numref(self.val), fmpq_denref(self.val))
290+
return r
291+
292+
def __hash__(self):
293+
from fractions import Fraction
294+
return hash(Fraction(int(self.p), int(self.q), _normalize=False))
295+
296+
def height_bits(self, bint signed=False):
297+
cdef long b1, b2
298+
b1 = fmpz_bits(fmpq_numref(self.val))
299+
b2 = fmpz_bits(fmpq_denref(self.val))
300+
if signed and fmpz_sgn(fmpq_numref(self.val)) < 0:
301+
return -max(b1, b2)
302+
else:
303+
return max(b1, b2)
304+

src/fmpq_mat.pyx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,3 +417,18 @@ cdef class fmpq_mat(flint_mat):
417417
den = fmpz()
418418
fmpq_mat_get_fmpz_mat_matwise(num.val, den.val, self.val)
419419
return num, den
420+
421+
def charpoly(self):
422+
cdef fmpq_poly u
423+
u = fmpq_poly.__new__(fmpq_poly)
424+
fmpq_poly_init(u.val)
425+
fmpq_mat_charpoly(u.val, self.val)
426+
return u
427+
428+
def minpoly(self):
429+
cdef fmpq_poly u
430+
u = fmpq_poly.__new__(fmpq_poly)
431+
fmpq_poly_init(u.val)
432+
fmpq_mat_minpoly(u.val, self.val)
433+
return u
434+

src/fmpq_poly.pyx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,16 @@ cdef class fmpq_poly(flint_poly):
158158
return v
159159
raise TypeError("cannot call fmpq_poly with input of type %s", type(other))
160160

161+
def derivative(self):
162+
cdef fmpq_poly res = fmpq_poly.__new__(fmpq_poly)
163+
fmpq_poly_derivative(res.val, self.val)
164+
return res
165+
166+
def integral(self):
167+
cdef fmpq_poly res = fmpq_poly.__new__(fmpq_poly)
168+
fmpq_poly_integral(res.val, self.val)
169+
return res
170+
161171
def __pos__(self):
162172
return self
163173

src/fmpz.pyx

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,3 +508,40 @@ cdef class fmpz(flint_scalar):
508508
cdef fmpz v = fmpz()
509509
arith_euler_phi(v.val, n.val)
510510
return v
511+
512+
def __hash__(self):
513+
return hash(int(self))
514+
515+
def height_bits(self, bint signed=False):
516+
if signed and fmpz_sgn(self.val) < 0:
517+
return -self.bit_length()
518+
else:
519+
return self.bit_length()
520+
521+
def isqrt(self):
522+
cdef fmpz v
523+
if fmpz_sgn(self.val) < 0:
524+
raise ValueError("integer square root of a negative number")
525+
v = fmpz()
526+
fmpz_sqrt(v.val, self.val)
527+
return v
528+
529+
def sqrtrem(self):
530+
cdef fmpz u, v
531+
if fmpz_sgn(self.val) < 0:
532+
raise ValueError("integer square root of a negative number")
533+
u = fmpz()
534+
v = fmpz()
535+
fmpz_sqrtrem(u.val, v.val, self.val)
536+
return u, v
537+
538+
def root(self, long n):
539+
cdef fmpz v
540+
if fmpz_sgn(self.val) < 0:
541+
raise ValueError("integer root of a negative number")
542+
if n <= 0:
543+
raise ValueError("n >= 1 is required")
544+
v = fmpz()
545+
fmpz_root(v.val, self.val, n)
546+
return v
547+

src/fmpz_mat.pyx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,3 +690,18 @@ cdef class fmpz_mat(flint_mat):
690690
True
691691
"""
692692
return bool(fmpz_mat_is_in_snf(self.val))
693+
694+
def charpoly(self):
695+
cdef fmpz_poly u
696+
u = fmpz_poly.__new__(fmpz_poly)
697+
fmpz_poly_init(u.val)
698+
fmpz_mat_charpoly(u.val, self.val)
699+
return u
700+
701+
def minpoly(self):
702+
cdef fmpz_poly u
703+
u = fmpz_poly.__new__(fmpz_poly)
704+
fmpz_poly_init(u.val)
705+
fmpz_mat_minpoly(u.val, self.val)
706+
return u
707+

0 commit comments

Comments
 (0)