Closed oscarbenjamin closed 2 months ago
I've just added the gr poly, mpoly and series types. This gives e.g. multivariate polynomials over the Gaussian integers:
In [4]: from flint.types import _gr
In [5]: R = _gr.gr_gr_mpoly_ctx.new(_gr.gr_fmpzi_ctx, 2)
In [6]: R
Out[6]: gr_gr_mpoly_ctx(gr_fmpzi_ctx, 2, 0)
In [7]: R.gens_recursive()
Out[7]: [I, x1, x2]
In [8]: i, x1, x2 = R.gens_recursive()
In [9]: (x1 + x2 + i)**3
Out[9]: x1^3 + 3*x1^2*x2 + (3*I)*x1^2 + 3*x1*x2^2 + (6*I)*x1*x2 - 3*x1 + x2^3 + (3*I)*x2^2 - 3*x2 - I
This needs a lot more thought about how to design things but I thought it would be useful to put this up and maybe just merge as is on the basis that it is unstable/private.
The changes here are:
gr_*
types and functions.flint.types._gr
.gr
type that can represent the elements of any of the scalar contexts.What I haven't added are polynomials and matrices (
gr_mat
,gr_poly
,gr_mpoly
) and also series (gr_series
). I also haven't added many functions beyond arithmetic.I don't think that the design here is really exactly what we would want because it uses the same
gr
type at the Python level for everything (fmpz
,arb
, ...) whereas I think that we want these to be different types at the Python level with different methods/attributes. More work is needed to figure out the right design but I think it might be like this:gr_ctx
contexts and designed around the same structure as the generic rings code.gr_
functions could be made available in a base class from which non-generic types likefmpz
etc inherit.Introducing a context based interface provides an opportunity to change the interface of many things and to solve many problems simultaneously:
And of course the big one is that the generic rings code allows constructing new rings like a ring of matrices of multivariate polynomials etc.
I haven't added tests etc because I expect the design here to change a lot but I think it is worth just adding this as a private/unstable module so that people can test it out and we can work out the full design over time. I think that it would be worth fleshing this out with matrices, polynomials, special functions etc, figuring all the types, conversions and coercions and so on before making it "public". It can also be fine for people to use this as long as they understand that the interfaces are subject to change in future.
These are the scalar types that can be created through the generic system with this PR:
Note that some of these are just abstract classes e.g. there are no polynomials or matrices here. Some of these duplicate things that already exist like
fmpz
,nmod
etc.Some examples of things this allows that are not currently accessible through python-flint are:
In [4]: R Out[4]: gr_fmpzi_ctx
In [5]: R.i() Out[5]: I
In [6]: R.i() + 2 Out[6]: (2+I)
In [7]: _*2 Out[7]: (3+4I)
In [10]: a = 1 + R.i()
In [11]: a Out[11]: (1+I)
In [13]: (2a).gcd(4a) Out[13]: (2+2*I)
In [36]: R Out[36]: gr_real_qqbar_ctx(-1, -1)
In [34]: R(2).sqrt() Out[34]: Root a = 1.41421 of a^2-2
In [35]: R(2).sqrt() ** 3 Out[35]: Root a = 2.82843 of a^2-8
In [41]: R Out[41]: gr_fexpr_ctx
In [42]: R(123)/2 + 1 Out[42]: Add(Div(123, 2), 1)