Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should python-flint abstract over Flint's C types #55

Open
oscarbenjamin opened this issue Aug 13, 2023 · 3 comments
Open

Should python-flint abstract over Flint's C types #55

oscarbenjamin opened this issue Aug 13, 2023 · 3 comments

Comments

@oscarbenjamin
Copy link
Collaborator

The basic question here is whether it makes sense to distinguish between things like nmod vs fmpz_mod in python-flint. Currently python-flint only has nmod. It would be good to add fmpz_mod but should it even be exposed as something separate in python-flint?

Flint's nmod type is for "integers mod n (word size n)" whereas fmpz_mod is for "arithmetic modulo integers". At the C level it clearly makes sense to distinguish these because the data structures are different and many functions have different call signatures and the need to manage memory makes these things not really interchangeable. In Python though there is no "word size" and integers are just integers so unless I misunderstand something the python-flint interface for nmod and fmpz_mod would end up being identical.

Considering the notation in #53 maybe there should just be a context object called something like fFF(p) that would internally choose the best representation (nmod, fmpz_mod or anything else) without the user needing to consider which implementation to use.

For integers mod n it seems like it could be easy enough to do that but then there are cases like fq and fq_nmod which seem easy but could the same extend to fq_zech or should that always be treated as separate (see #50)?

See also #53 which discusses the idea of contexts to represent different types in python-flint and #54 which discusses the idea of having a low-level direct imitation of Flint's C API. Currently python-flint sort of sits in between a low and a high-level interface.

The question here is essentially whether python-flint's main interface should just be a nicer version of the low-level interface described in #54 or whether it should actually be more like the higher-level abstracted interface described in #53.

@oscarbenjamin
Copy link
Collaborator Author

Thinking about this a bit I think that maybe the ideal would be to have three levels of API:

  • level 0: The low-level interface described in A lower-level interface to Flint #54 that is a very thin wrapper around each C function.
  • level 1: Like the current python-flint API. Nicer to use from Python but more or less still a one-to-one correspondence to C types and functions (perhaps it should be made more precisely a one to one correspondence).
  • Level 2: Something more abstract with contexts and explicit conversions like described in Context/Domain objects in python-flint #53. At this level it is python-flint's job to choose the (likely) best representations and algorithms but the interface is presented more in terms of abstract mathematical concepts rather than Flint's low-level types.

Then level 0 is good for prototyping etc. Level 1 is good for having a nicer interface when you want precise control of lower-level routines and is probably best for libraries that might use pthon-flint. Level 2 ends up being the interface for python-flint's direct end users.

@deinst
Copy link
Contributor

deinst commented Sep 3, 2023

I think a level 0 that works for flint like https://github.com/cython/cython/tree/master/Cython/Includes/cpython works for the cpython internals is both workable and a good idea. This would entail taking what is now _flint.pxd and blowing it up into a submodule of python flint. As @fredrik-johansson notes this can (mostly) be done by parsing the .rst files.

I think the only question is whether we want this to be a submodule of python-flint or a separate module altogether (I don't see much point to a separate module, but I know little about library distribution)

On a related note do we want to export the cython interface to python interface as well? Right now there isn't much point as most of the methods are just def methods, though there are some cdef conversion methods.

If I understand the level 2 interface would be much like a python layer over flint's new generics.

@oscarbenjamin
Copy link
Collaborator Author

I think the only question is whether we want this to be a submodule of python-flint or a separate module altogether (I don't see much point to a separate module, but I know little about library distribution)

It can just be a submodule like flint.libflint. It should be possible to interface between level 1 and level 0 so if there is a level 0 version of e.g. fmpz_poly then there should be some way to convert a level 1 fmpz_poly to a level 0 fmpz_poly and also back again. For that I think that probably it all needs to be within the same project (at least it would be easier that way).

On a related note do we want to export the cython interface to python interface as well?

I assume that what you mean here is should python-flint expose cython functions/methods that can be used for downstream cython code? Then if a downstream library is written in cython it can call some of python-flint's cython functions/methods. This is something that I know very little about: I don't know how exactly exposing a cython interface from one package to another works in practice. I am not sure exactly how to expose a Cython interface or what the benefits or limitations would be.

If I understand the level 2 interface would be much like a python layer over flint's new generics.

Possibly, although I am still a bit unclear about exactly where Flint's new generics are going to end up. Level 2 could just be a nicer level over the top of level 1 that abstracts away the things that can be abstracted (like the distinction between fq and fq_nmod etc) and perhaps has better support for things like explicit coercions etc. Whether it makes sense to use the generics for that is unclear to me right now.

Basically in my mind level 2 looks more like a simple CAS and is designed to have a nice CAS interface for users. For now my intention in distinguishing level 2 is really to say that we should not worry too much about trying to design a "nice" interface at level 1 and should just focus on making it as complete as possible in wrapping flint's most important functionality in a way that is fast and safe (no segfaults etc, unlike level 0). It is easy to get tied down in designing the ideal UI once you start thinking of a CAS but if we just remember that there can be a separate level 2 for that then we can avoid worrying too much about it for level 1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants