diff --git a/.gitignore b/.gitignore index 4c66d67b..0f4ae48e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ build/* dist/* -src/flint/*.c +src/flint/**/*.c src/flint/*.html doc/build/* fmake* @@ -16,3 +16,4 @@ MANIFEST .coverage *.swp .python-version +*.DS_Store diff --git a/setup.py b/setup.py index 85b92404..060a324c 100644 --- a/setup.py +++ b/setup.py @@ -63,16 +63,26 @@ compiler_directives['linetrace'] = True -ext_modules = [ - Extension( - "flint._flint", ["src/flint/pyflint.pyx"], - libraries=libraries, - library_dirs=default_lib_dirs, - include_dirs=default_include_dirs, - define_macros=define_macros, - ) +ext_files = [ + ("flint._flint", ["src/flint/pyflint.pyx"]), # Main Module + # Submodules + ("flint.flint_base.flint_base", ["src/flint/flint_base/flint_base.pyx"]), + ("flint.flint_base.flint_context", ["src/flint/flint_base/flint_context.pyx"]), + ] +ext_options = { + "libraries" : libraries, + "library_dirs" : default_lib_dirs, + "include_dirs" : default_include_dirs, + "define_macros" : define_macros, +} + +ext_modules = [] +for mod_name, src_files in ext_files: + ext = Extension(mod_name, src_files, **ext_options) + ext_modules.append(ext) + for e in ext_modules: e.cython_directives = {"embedsignature": True} @@ -92,3 +102,4 @@ author_email='fredrik.johansson@gmail.com', license='MIT', classifiers=['Topic :: Scientific/Engineering :: Mathematics']) + diff --git a/src/flint/acb.pyx b/src/flint/acb.pyx index a7151a55..a3cb36c7 100644 --- a/src/flint/acb.pyx +++ b/src/flint/acb.pyx @@ -1,3 +1,6 @@ +from flint.flint_base.flint_base cimport flint_scalar +from flint.flint_base.flint_context cimport getprec + cdef int acb_set_python(acb_t x, obj, bint allow_conversion): cdef double re, im diff --git a/src/flint/acb_mat.pyx b/src/flint/acb_mat.pyx index 4f80870d..6755edd2 100644 --- a/src/flint/acb_mat.pyx +++ b/src/flint/acb_mat.pyx @@ -1,3 +1,7 @@ +from flint.flint_base.flint_context cimport getprec + +from flint.flint_base.flint_base cimport flint_mat + cdef acb_mat_coerce_operands(x, y): if isinstance(y, (fmpz_mat, fmpq_mat, arb_mat)): return x, acb_mat(y) diff --git a/src/flint/acb_poly.pyx b/src/flint/acb_poly.pyx index 252e57d9..fe41577c 100644 --- a/src/flint/acb_poly.pyx +++ b/src/flint/acb_poly.pyx @@ -1,3 +1,8 @@ +from flint.flint_base.flint_context cimport getprec +# TODO: waiting for fix on the roots method, currently +# globally defined. +# from flint.flint_base.flint_base cimport flint_poly + cdef acb_poly_coerce_operands(x, y): if isinstance(y, (int, long, float, complex, fmpz, fmpq, arb, acb, fmpz_poly, fmpq_poly, arb_poly)): return x, acb_poly(y) diff --git a/src/flint/acb_series.pyx b/src/flint/acb_series.pyx index dd2eba22..a642c46f 100644 --- a/src/flint/acb_series.pyx +++ b/src/flint/acb_series.pyx @@ -1,3 +1,6 @@ +from flint.flint_base.flint_context cimport getprec, getcap +from flint.flint_base.flint_base cimport flint_series + cdef acb_series_coerce_operands(x, y): if isinstance(y, (int, long, float, complex, fmpz, fmpz_poly, fmpz_series, fmpq, fmpq_poly, fmpq_series, arb, arb_poly, arb_series, acb, acb_poly)): return x, acb_series(y) diff --git a/src/flint/arb.pyx b/src/flint/arb.pyx index 6a52c557..19f31ecd 100644 --- a/src/flint/arb.pyx +++ b/src/flint/arb.pyx @@ -1,3 +1,9 @@ +from cpython.version cimport PY_MAJOR_VERSION + +from flint.flint_base.flint_context cimport getprec +from flint.flint_base.flint_base cimport flint_scalar +from flint.utils.conversion cimport chars_from_str, str_from_chars + cdef _str_trunc(s, trunc=0): if trunc > 0 and len(s) > 3 * trunc: left = right = trunc diff --git a/src/flint/arb_mat.pyx b/src/flint/arb_mat.pyx index 0cb89378..16cea15b 100644 --- a/src/flint/arb_mat.pyx +++ b/src/flint/arb_mat.pyx @@ -1,3 +1,6 @@ +from flint.flint_base.flint_context cimport getprec +from flint.flint_base.flint_base cimport flint_mat + cdef arb_mat_coerce_operands(x, y): if isinstance(y, (fmpz_mat, fmpq_mat)): return x, arb_mat(y) diff --git a/src/flint/arb_poly.pyx b/src/flint/arb_poly.pyx index a13ed454..518cdd51 100644 --- a/src/flint/arb_poly.pyx +++ b/src/flint/arb_poly.pyx @@ -1,3 +1,8 @@ +from flint.flint_base.flint_context cimport getprec +# TODO: waiting for fix on the roots method, currently +# globally defined. +# from flint.flint_base.flint_base cimport flint_poly + cdef arb_poly_coerce_operands(x, y): if isinstance(y, (int, long, float, fmpz, fmpq, arb, fmpz_poly, fmpq_poly)): return x, arb_poly(y) diff --git a/src/flint/arb_series.pyx b/src/flint/arb_series.pyx index 7eff177b..8713080d 100644 --- a/src/flint/arb_series.pyx +++ b/src/flint/arb_series.pyx @@ -1,3 +1,6 @@ +from flint.flint_base.flint_context cimport getprec, getcap +from flint.flint_base.flint_base cimport flint_series + cdef arb_series_coerce_operands(x, y): if isinstance(y, (int, long, float, fmpz, fmpz_poly, fmpz_series, fmpq, fmpq_poly, fmpq_series, arb, arb_poly)): return x, arb_series(y) diff --git a/src/flint/arf.pyx b/src/flint/arf.pyx index 9790218c..91da4290 100644 --- a/src/flint/arf.pyx +++ b/src/flint/arf.pyx @@ -1,3 +1,6 @@ +from flint.flint_base.flint_context cimport getprec +from flint.utils.conversion cimport prec_to_dps + cdef class arf: cdef arf_t val diff --git a/src/flint/dirichlet.pyx b/src/flint/dirichlet.pyx index 76801ff4..8ec160ec 100644 --- a/src/flint/dirichlet.pyx +++ b/src/flint/dirichlet.pyx @@ -1,3 +1,5 @@ +from flint.flint_base.flint_context cimport getprec + cdef dict _dirichlet_group_cache = {} cdef class dirichlet_group(object): diff --git a/src/flint/flint_base/__init__.py b/src/flint/flint_base/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/flint/flint_base/flint_base.pxd b/src/flint/flint_base/flint_base.pxd new file mode 100644 index 00000000..e8782db2 --- /dev/null +++ b/src/flint/flint_base/flint_base.pxd @@ -0,0 +1,19 @@ +cdef class flint_elem: + pass + +cdef class flint_scalar(flint_elem): + pass + +# TODO: +# See .pyx file +# cdef class flint_poly(flint_elem): +# pass + +cdef class flint_mpoly(flint_elem): + pass + +cdef class flint_mat(flint_elem): + pass + +cdef class flint_series(flint_elem): + pass diff --git a/src/flint/flint_base/flint_base.pyx b/src/flint/flint_base/flint_base.pyx new file mode 100644 index 00000000..5e4ebff0 --- /dev/null +++ b/src/flint/flint_base/flint_base.pyx @@ -0,0 +1,151 @@ +from flint.flint_base.flint_context cimport thectx + +cdef class flint_elem: + def __repr__(self): + if thectx.pretty: + return self.str() + else: + return self.repr() + + def __str__(self): + return self.str() + +cdef class flint_scalar(flint_elem): + pass + +# TODO: +# We cannot include this class until we can import +# acb_poly, so for now we leave this class as a global +# inside pyflint.pyx +# +# cdef class flint_poly(flint_elem): +# """ +# Base class for polynomials. +# """ + +# def __iter__(self): +# cdef long i, n +# n = self.length() +# for i in range(n): +# yield self[i] + +# def coeffs(self): +# return list(self) + +# def str(self, bint ascending=False): +# """ +# Convert to a human-readable string (generic implementation for +# all polynomial types). + +# If *ascending* is *True*, the monomials are output from low degree to +# high, otherwise from high to low. +# """ +# coeffs = [str(c) for c in self] +# if not coeffs: +# return "0" +# s = [] +# coeffs = enumerate(coeffs) +# if not ascending: +# coeffs = reversed(list(coeffs)) +# for i, c in coeffs: +# if c == "0": +# continue +# else: +# if c.startswith("-") or (" " in c): +# c = "(" + c + ")" +# if i == 0: +# s.append("%s" % c) +# elif i == 1: +# if c == "1": +# s.append("x") +# else: +# s.append("%s*x" % c) +# else: +# if c == "1": +# s.append("x^%s" % i) +# else: +# s.append("%s*x^%s" % (c, i)) +# return " + ".join(s) + +# def roots(self, **kwargs): +# """ +# Isolates the complex roots of *self*. See :meth:`.acb_poly.roots` +# for details. +# """ +# # TODO: +# # To avoid circular imports, we import within the method +# from XXX.XXX.acb_poly import acb_poly +# return acb_poly(self).roots(**kwargs) + +cdef class flint_mpoly(flint_elem): + """ + Base class for multivariate polynomials. + """ + +cdef class flint_series(flint_elem): + """ + Base class for power series. + """ + def __iter__(self): + cdef long i, n + n = self.length() + for i in range(n): + yield self[i] + + def coeffs(self): + return list(self) + + +cdef class flint_mat(flint_elem): + """ + Base class for matrices. + """ + + def repr(self): + if thectx.pretty: + return str(self) + # XXX + return "%s(%i, %i, [%s])" % (type(self).__name__, + self.nrows(), self.ncols(), (", ".join(map(str, self.entries())))) + + def str(self, *args, **kwargs): + tab = self.table() + if len(tab) == 0 or len(tab[0]) == 0: + return "[]" + tab = [[r.str(*args, **kwargs) for r in row] for row in tab] + widths = [] + for i in xrange(len(tab[0])): + w = max([len(row[i]) for row in tab]) + widths.append(w) + for i in xrange(len(tab)): + tab[i] = [s.rjust(widths[j]) for j, s in enumerate(tab[i])] + tab[i] = "[" + (", ".join(tab[i])) + "]" + return "\n".join(tab) + + def entries(self): + cdef long i, j, m, n + m = self.nrows() + n = self.ncols() + L = [None] * (m * n) + for i from 0 <= i < m: + for j from 0 <= j < n: + L[i*n + j] = self[i, j] + return L + + def __iter__(self): + cdef long i, j, m, n + m = self.nrows() + n = self.ncols() + for i from 0 <= i < m: + for j from 0 <= j < n: + yield self[i, j] + + def table(self): + cdef long i, m, n + m = self.nrows() + n = self.ncols() + L = self.entries() + return [L[i*n : (i+1)*n] for i in range(m)] + + # supports mpmath conversions + tolist = table diff --git a/src/flint/flint_base/flint_context.pxd b/src/flint/flint_base/flint_context.pxd new file mode 100644 index 00000000..2bcfcdb0 --- /dev/null +++ b/src/flint/flint_base/flint_context.pxd @@ -0,0 +1,25 @@ +from flint._flint cimport ( + arf_rnd_t, +) + +cdef class FlintContext: + cdef public bint pretty + cdef public long _prec + cdef public long _dps + cdef arf_rnd_t rnd + cdef public bint unicode + cdef public long _cap + +cdef FlintContext thectx + +cdef inline long getprec(long prec=0): + if prec > 1: + return prec + else: + return thectx._prec + +cdef inline long getcap(long cap=-1): + if cap >= 0: + return cap + else: + return thectx._cap diff --git a/src/flint/flint_base/flint_context.pyx b/src/flint/flint_base/flint_context.pyx new file mode 100644 index 00000000..c86a5d10 --- /dev/null +++ b/src/flint/flint_base/flint_context.pyx @@ -0,0 +1,72 @@ +from flint._flint cimport ( + ARF_RND_DOWN, + flint_cleanup, + flint_get_num_threads, + flint_set_num_threads +) +from flint.utils.conversion cimport prec_to_dps, dps_to_prec + +cdef class FlintContext: + def __init__(self): + self.default() + + def default(self): + self.pretty = True + self.rnd = ARF_RND_DOWN + self.prec = 53 + self.unicode = False + self.threads = 1 + self.cap = 10 + + @property + def prec(self): + return self._prec + + @prec.setter + def prec(self, prec): + cdef long cprec = prec + if cprec < 2: + raise ValueError("prec must be >= 2") + self._prec = cprec + self._dps = prec_to_dps(cprec) + + @property + def dps(self): + return self._dps + + @dps.setter + def dps(self, prec): + self.prec = dps_to_prec(prec) + + @property + def cap(self): + return self._cap + + @cap.setter + def cap(self, long cap): + if cap < 0: + raise ValueError("cap must be >= 0") + self._cap = cap + + @property + def threads(self): + return flint_get_num_threads() + + @threads.setter + def threads(self, long num): + assert num >= 1 and num <= 64 + flint_set_num_threads(num) + + def __repr__(self): + return "pretty = %-8s # pretty-print repr() output\n" \ + "unicode = %-8s # use unicode characters in output\n" \ + "prec = %-8s # real/complex precision (in bits)\n" \ + "dps = %-8s # real/complex precision (in digits)\n" \ + "cap = %-8s # power series precision\n" \ + "threads = %-8s # max number of threads used internally\n" % \ + (self.pretty, self.unicode, self.prec, self.dps, self.cap, self.threads) + + def cleanup(self): + flint_cleanup() + +cdef FlintContext thectx = FlintContext() diff --git a/src/flint/fmpq.pyx b/src/flint/fmpq.pyx index d70a68f2..e8e79b3b 100644 --- a/src/flint/fmpq.pyx +++ b/src/flint/fmpq.pyx @@ -1,3 +1,5 @@ +from flint.flint_base.flint_base cimport flint_scalar + cdef any_as_fmpq(obj): if typecheck(obj, fmpq): return obj diff --git a/src/flint/fmpq_mat.pyx b/src/flint/fmpq_mat.pyx index e81875e4..65d8a0a9 100644 --- a/src/flint/fmpq_mat.pyx +++ b/src/flint/fmpq_mat.pyx @@ -1,3 +1,5 @@ +from flint.flint_base.flint_base cimport flint_mat + cdef any_as_fmpq_mat(obj): if typecheck(obj, fmpq_mat): return obj diff --git a/src/flint/fmpq_poly.pyx b/src/flint/fmpq_poly.pyx index c3e68cef..db2c08ab 100644 --- a/src/flint/fmpq_poly.pyx +++ b/src/flint/fmpq_poly.pyx @@ -1,3 +1,7 @@ +# TODO: waiting for fix on the roots method, currently +# globally defined. +# from flint.flint_base.flint_base cimport flint_poly + cdef any_as_fmpq_poly(obj): if typecheck(obj, fmpq_poly): return obj diff --git a/src/flint/fmpq_series.pyx b/src/flint/fmpq_series.pyx index a5300ddc..9c76f69d 100644 --- a/src/flint/fmpq_series.pyx +++ b/src/flint/fmpq_series.pyx @@ -1,3 +1,5 @@ +from flint.flint_base.flint_base cimport flint_series + cdef fmpq_series_coerce_operands(x, y): if isinstance(y, (int, long, fmpz, fmpz_poly, fmpz_series, fmpq, fmpq_poly)): return x, fmpq_series(y) diff --git a/src/flint/fmpz.pyx b/src/flint/fmpz.pyx index 5900aa0e..c91359f8 100644 --- a/src/flint/fmpz.pyx +++ b/src/flint/fmpz.pyx @@ -1,3 +1,8 @@ +from cpython.version cimport PY_MAJOR_VERSION + +from flint.flint_base.flint_base cimport flint_scalar +from flint.utils.conversion cimport chars_from_str + cdef inline int fmpz_set_pylong(fmpz_t x, obj): cdef int overflow cdef slong longval diff --git a/src/flint/fmpz_mat.pyx b/src/flint/fmpz_mat.pyx index 1ff56ab7..887750b2 100644 --- a/src/flint/fmpz_mat.pyx +++ b/src/flint/fmpz_mat.pyx @@ -1,3 +1,5 @@ +from flint.flint_base.flint_base cimport flint_mat + cdef any_as_fmpz_mat(obj): if typecheck(obj, fmpz_mat): return obj diff --git a/src/flint/fmpz_mpoly.pyx b/src/flint/fmpz_mpoly.pyx index 32ed47d3..f4ddf026 100644 --- a/src/flint/fmpz_mpoly.pyx +++ b/src/flint/fmpz_mpoly.pyx @@ -1,3 +1,8 @@ +from cpython.version cimport PY_MAJOR_VERSION + +from flint.utils.conversion cimport str_from_chars +from flint.flint_base.flint_base cimport flint_mpoly + cdef any_as_fmpz_mpoly(x): cdef fmpz_mpoly res """ diff --git a/src/flint/fmpz_poly.pyx b/src/flint/fmpz_poly.pyx index 3f570ca4..0b9ad86a 100644 --- a/src/flint/fmpz_poly.pyx +++ b/src/flint/fmpz_poly.pyx @@ -1,3 +1,10 @@ +from cpython.version cimport PY_MAJOR_VERSION + +from flint.flint_base.flint_context cimport getprec +# TODO: waiting for fix on the roots method, currently +# globally defined. +# from flint.flint_base.flint_base cimport flint_poly + cdef any_as_fmpz_poly(x): cdef fmpz_poly res if typecheck(x, fmpz_poly): diff --git a/src/flint/fmpz_series.pyx b/src/flint/fmpz_series.pyx index c8f31343..dcb8cb3a 100644 --- a/src/flint/fmpz_series.pyx +++ b/src/flint/fmpz_series.pyx @@ -1,3 +1,5 @@ +from flint.flint_base.flint_base cimport flint_series + cdef fmpz_series_coerce_operands(x, y): if isinstance(y, (int, long, fmpz, fmpz_poly)): return x, fmpz_series(y) diff --git a/src/flint/functions.pyx b/src/flint/functions.pyx index b13f40e7..7bb8e6a4 100644 --- a/src/flint/functions.pyx +++ b/src/flint/functions.pyx @@ -1,3 +1,5 @@ +from .utils.conversion cimport dps_to_prec + # xxx: this doesn't work when changed to a cdef function. why? def __goodness(x, bint parts=True, metric=None): if metric is not None: diff --git a/src/flint/nmod.pyx b/src/flint/nmod.pyx index 75bce0c3..e212b668 100644 --- a/src/flint/nmod.pyx +++ b/src/flint/nmod.pyx @@ -1,3 +1,5 @@ +from flint.flint_base.flint_base cimport flint_scalar + cdef int any_as_nmod(mp_limb_t * val, obj, nmod_t mod) except -1: cdef int success cdef fmpz_t t diff --git a/src/flint/nmod_mat.pyx b/src/flint/nmod_mat.pyx index 9d9e918d..14a86309 100644 --- a/src/flint/nmod_mat.pyx +++ b/src/flint/nmod_mat.pyx @@ -1,3 +1,5 @@ +from flint.utils.conversion cimport matrix_to_str + cdef any_as_nmod_mat(obj, nmod_t mod): cdef nmod_mat r cdef mp_limb_t v diff --git a/src/flint/nmod_poly.pyx b/src/flint/nmod_poly.pyx index 9e43194c..2e928ecc 100644 --- a/src/flint/nmod_poly.pyx +++ b/src/flint/nmod_poly.pyx @@ -1,3 +1,7 @@ +# TODO: waiting for fix on the roots method, currently +# globally defined. +# from flint.flint_base.flint_base cimport flint_poly + cdef any_as_nmod_poly(obj, nmod_t mod): cdef nmod_poly r cdef mp_limb_t v diff --git a/src/flint/nmod_series.pyx b/src/flint/nmod_series.pyx index 125eb69c..160d5f2c 100644 --- a/src/flint/nmod_series.pyx +++ b/src/flint/nmod_series.pyx @@ -1,3 +1,5 @@ +from flint.flint_base.flint_base cimport flint_series + cdef class nmod_series(flint_series): pass diff --git a/src/flint/pyflint.pyx b/src/flint/pyflint.pyx index 63af457c..44d4a626 100644 --- a/src/flint/pyflint.pyx +++ b/src/flint/pyflint.pyx @@ -6,6 +6,8 @@ cimport flint cimport libc.stdlib cimport cython +from flint.flint_base.flint_context cimport thectx + cdef flint_rand_t global_random_state flint_randinit(global_random_state) @@ -22,33 +24,6 @@ cdef extern from "Python.h": double PyComplex_RealAsDouble(PyObject *op) double PyComplex_ImagAsDouble(PyObject *op) -from cpython.version cimport PY_MAJOR_VERSION - -cdef chars_from_str(s): - if PY_MAJOR_VERSION < 3: - return s - else: - return s.encode('ascii') - -cdef str_from_chars(s): - if PY_MAJOR_VERSION < 3: - return str(s) - else: - return bytes(s).decode('ascii') - -cdef matrix_to_str(tab): - if len(tab) == 0 or len(tab[0]) == 0: - return "[]" - tab = [[str(c) for c in row] for row in tab] - widths = [] - for i in xrange(len(tab[0])): - w = max([len(row[i]) for row in tab]) - widths.append(w) - for i in xrange(len(tab)): - tab[i] = [s.rjust(widths[j]) for j, s in enumerate(tab[i])] - tab[i] = "[" + (", ".join(tab[i])) + "]" - return "\n".join(tab) - cdef inline bint typecheck(object ob, object tp): return PyObject_TypeCheck(ob, tp) @@ -56,112 +31,14 @@ DEF FMPZ_UNKNOWN = 0 DEF FMPZ_REF = 1 DEF FMPZ_TMP = 2 - -cdef long prec_to_dps(n): - return max(1, int(round(int(n)/3.3219280948873626)-1)) - -cdef long dps_to_prec(n): - return max(1, int(round((int(n)+1)*3.3219280948873626))) - -cdef class FlintContext: - cdef public bint pretty - cdef public long _prec - cdef public long _dps - cdef arf_rnd_t rnd - cdef public bint unicode - cdef public long _cap - - def __init__(self): - self.default() - - def default(self): - self.pretty = True - self.rnd = ARF_RND_DOWN - self.prec = 53 - self.unicode = False - self.threads = 1 - self.cap = 10 - - property prec: - - def __set__(self, prec): - cdef long cprec = prec - if cprec < 2: - raise ValueError("prec must be >= 2") - self._prec = cprec - self._dps = prec_to_dps(cprec) - - def __get__(self): - return self._prec - - property dps: - - def __set__(self, prec): - self.prec = dps_to_prec(prec) - - def __get__(self): - return self._dps - - property cap: - - def __set__(self, long cap): - if cap < 0: - raise ValueError("cap must be >= 0") - self._cap = cap - - def __get__(self): - return self._cap - - property threads: - - def __set__(self, long num): - assert num >= 1 and num <= 64 - flint_set_num_threads(num) - - def __get__(self): - return flint_get_num_threads() - - def __repr__(self): - return "pretty = %-8s # pretty-print repr() output\n" \ - "unicode = %-8s # use unicode characters in output\n" \ - "prec = %-8s # real/complex precision (in bits)\n" \ - "dps = %-8s # real/complex precision (in digits)\n" \ - "cap = %-8s # power series precision\n" \ - "threads = %-8s # max number of threads used internally\n" % \ - (self.pretty, self.unicode, self.prec, self.dps, self.cap, self.threads) - - def cleanup(self): - flint_cleanup() - -cdef FlintContext thectx = FlintContext() - ctx = thectx -cdef inline long getprec(long prec=0): - if prec > 1: - return prec - else: - return thectx._prec - -cdef inline long getcap(long cap=-1): - if cap >= 0: - return cap - else: - return thectx._cap - -cdef class flint_elem: +# TODO: +# This should be factored out into flint_base +# but we cannot do this until we can import +# acb_poly to allow the roots() method to remain - def __repr__(self): - if ctx.pretty: - return self.str() - else: - return self.repr() - - def __str__(self): - return self.str() - -cdef class flint_scalar(flint_elem): - pass +from flint.flint_base.flint_base cimport flint_elem cdef class flint_poly(flint_elem): """ @@ -219,80 +96,6 @@ cdef class flint_poly(flint_elem): """ return acb_poly(self).roots(**kwargs) -cdef class flint_mpoly(flint_elem): - """ - Base class for multivariate polynomials. - """ - - -cdef class flint_mat(flint_elem): - """ - Base class for matrices. - """ - - def repr(self): - if ctx.pretty: - return str(self) - # XXX - return "%s(%i, %i, [%s])" % (type(self).__name__, - self.nrows(), self.ncols(), (", ".join(map(str, self.entries())))) - - def str(self, *args, **kwargs): - tab = self.table() - if len(tab) == 0 or len(tab[0]) == 0: - return "[]" - tab = [[r.str(*args, **kwargs) for r in row] for row in tab] - widths = [] - for i in xrange(len(tab[0])): - w = max([len(row[i]) for row in tab]) - widths.append(w) - for i in xrange(len(tab)): - tab[i] = [s.rjust(widths[j]) for j, s in enumerate(tab[i])] - tab[i] = "[" + (", ".join(tab[i])) + "]" - return "\n".join(tab) - - def entries(self): - cdef long i, j, m, n - m = self.nrows() - n = self.ncols() - L = [None] * (m * n) - for i from 0 <= i < m: - for j from 0 <= j < n: - L[i*n + j] = self[i, j] - return L - - def __iter__(self): - cdef long i, j, m, n - m = self.nrows() - n = self.ncols() - for i from 0 <= i < m: - for j from 0 <= j < n: - yield self[i, j] - - def table(self): - cdef long i, m, n - m = self.nrows() - n = self.ncols() - L = self.entries() - return [L[i*n : (i+1)*n] for i in range(m)] - - # supports mpmath conversions - tolist = table - -cdef class flint_series(flint_elem): - """ - Base class for power series. - """ - def __iter__(self): - cdef long i, n - n = self.length() - for i in range(n): - yield self[i] - - def coeffs(self): - return list(self) - - include "fmpz.pyx" include "fmpz_poly.pyx" include "fmpz_mpoly.pyx" diff --git a/src/flint/utils/__init__.py b/src/flint/utils/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/flint/utils/conversion.pxd b/src/flint/utils/conversion.pxd new file mode 100644 index 00000000..98df1a81 --- /dev/null +++ b/src/flint/utils/conversion.pxd @@ -0,0 +1,32 @@ +from cpython.version cimport PY_MAJOR_VERSION + +cdef inline long prec_to_dps(n): + return max(1, int(round(int(n)/3.3219280948873626)-1)) + +cdef inline long dps_to_prec(n): + return max(1, int(round((int(n)+1)*3.3219280948873626))) + +cdef inline chars_from_str(s): + if PY_MAJOR_VERSION < 3: + return s + else: + return s.encode('ascii') + +cdef inline str_from_chars(s): + if PY_MAJOR_VERSION < 3: + return str(s) + else: + return bytes(s).decode('ascii') + +cdef inline matrix_to_str(tab): + if len(tab) == 0 or len(tab[0]) == 0: + return "[]" + tab = [[str(c) for c in row] for row in tab] + widths = [] + for i in xrange(len(tab[0])): + w = max([len(row[i]) for row in tab]) + widths.append(w) + for i in xrange(len(tab)): + tab[i] = [s.rjust(widths[j]) for j, s in enumerate(tab[i])] + tab[i] = "[" + (", ".join(tab[i])) + "]" + return "\n".join(tab)