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

Add fq_default_poly #182

Merged
merged 22 commits into from
Aug 16, 2024
Merged

Add fq_default_poly #182

merged 22 commits into from
Aug 16, 2024

Conversation

GiacomoPope
Copy link
Contributor

Still a draft, spent this evening just getting the flintlib started and creating the necessary structs

@oscarbenjamin
Copy link
Collaborator

When you get to writing the tests I think it would be good to try to achieve as high as possible coverage through the generic tests. It is fine to add test cases like:

if domain is nmod or fq:
    assert p.some_func() == p2
else:
    # update this when some_func is added to fmpz_poly etc.
    assert not hasattr(p, "some_func")

It is very useful for future additions if the test cases are generic in so far as possible because it means that we can apply the same tests to all types to check consistency. It also makes it a lot easier to add new types or new methods to types if most of the test cases are already in place. A test that the type does not have the method serves as a reminder to future contributors to update the test when the method is added as well as a clear cue in the code that there is something that is yet to be implemented.

@GiacomoPope
Copy link
Contributor Author

Yeah this is a nice idea and should definitely be done for fmpz_mod, nmod and fq as well as the same as before but _poly.

@GiacomoPope
Copy link
Contributor Author

I haven't made "unique" tests for the type yet, but it's now tested in the generic poly tests. this uncovered a segfault in flint: flintlib/flint#2046 so the polynomial evaluation for certain a certain type is currently an ugly hack

@GiacomoPope GiacomoPope marked this pull request as ready for review August 13, 2024 17:18
@GiacomoPope
Copy link
Contributor Author

I think aside from reviewer comments, the main thing to do now is run coverage and start making sure I capture as much as possible.

@oscarbenjamin
Copy link
Collaborator

Generally looks good to me.

@GiacomoPope
Copy link
Contributor Author

I'll try and write some detailed tests for everything tomorrow, the coverage for this and fq_default is maybe a little low at the time of writing.

@GiacomoPope
Copy link
Contributor Author

latest push uses the fmpz_mod_poly as a template for further testing for coverage and it caught a few bugs which is nice.

@oscarbenjamin
Copy link
Collaborator

latest push uses the fmpz_mod_poly as a template for further testing for coverage and it caught a few bugs which is nice.

Rather than copying the test function it would be better if these are handled using generic test code that is shared. Especially if test_fq_default_poly is practically identical to test_fmpz_mod_poly then at least those two types can share the same code.

I wrote the test_all_polys function in gh-90 while you were working on fmpz_mod_poly because I could see that there were interface differences like different method names, things being handled differently, different exceptions etc. At the time I tried to maximise coverage for fmpz_poly, fmpq_poly and nmod_poly just in that one test function excluding only those methods that were obviously not generic (swinnerton_dyer, ...). In the process inconsistencies were fixed, missing methods were added etc.

Then you added fmpz_mod_poly to it and it found inconsistencies or bugs (in either test code or implementation) which you fixed in e.g. a793997 as part of gh-87.

Now fmpz_mod_poly and fq_default_poly have many more methods than existed when I wrote the test_all_polys function. It is still useful to have generic test code now for the same reason it was before which is that we can share a lot of the test code across different types and it helps to ensure consistent interfaces, handling of edge cases, etc. Adding a new type as you are doing now is much easier if you can mostly reuse the existing tests. It also means that in future if some edge case is found and added to the tests then it will automatically be tested against all implementations.

The best thing to do here is to try to achieve maximum coverage in generic tests. Then we can use those same tests originally written for e.g. fmpz_mod_poly for fq_default_poly and also in future for nmod_poly, fmpz_poly and fmpq_poly. If many of the methods tested only exist for fmpz_mod_poly and fq_default_poly then we can write a generic test function that for now only covers those two. Later on we would want to add all the other types to it though so we should write it in a way that allows that.

@oscarbenjamin
Copy link
Collaborator

I would say that first try to get maximum coverage using only generic tests like the test_all_polys function or similar generic tests. Looking at it now the test_matrices_* tests are the way that I think these tests should be written: each is a small test for one function/operation but applied generically to all matrix types.

At some point there won't be anything left that can reasonably be covered by generic tests but there will likely still be a few things that should be tested specifically for fq_default_poly. Those things can then be covered by test_fq_default_poly.

@oscarbenjamin
Copy link
Collaborator

My issue with trying to help with coverage is that ./bin/coverage.sh is still just testing the tests, so I'm blind

Let me check that. I had a working coverage measurement before...

@oscarbenjamin
Copy link
Collaborator

Note that it needs to be:

PYTHONPATH=src bin/coverage.sh

First confirm that flint is not importable:

$ python -m flint
/home/oscar/.pyenv/versions/python-flint-3.11/bin/python: No module named flint

Then with PYTHONPATH set the coverage script should measure coverage:

$ PYTHONPATH=src bin/coverage.sh 
running build_ext
Running tests...
test_pyflint...OK
...
flint.test: all 52 tests passed!
flint.test: all 3601 doctests passed!
----------------------------------------
OK: Your installation of python-flint seems to be working just fine!
----------------------------------------
Wrote HTML report to htmlcov/index.html
$ coverage report --sort=cover
Name                                     Stmts   Miss  Cover
------------------------------------------------------------
src/flint/types/fmpz.pxd                     2      2     0%
src/flint/types/fq_default.pxd               2      2     0%
src/flint/types/acb_series.pyx             582    573     2%
src/flint/types/arb_series.pyx             576    496    14%
src/flint/types/arb_poly.pyx               217    183    16%
src/flint/types/acb_poly.pyx               257    194    25%
src/flint/types/fmpz_mpoly.pxd              11      8    27%
src/flint/types/arf.pyx                    107     76    29%
src/flint/types/fmpq_vec.pyx                47     26    45%
src/flint/flint_base/flint_context.pxd       8      4    50%
src/flint/types/dirichlet.pyx               57     25    56%
src/flint/types/fmpq_mpoly.pxd              11      4    64%
src/flint/types/arb_mat.pyx                313    111    65%
src/flint/types/fmpz_vec.pyx                45     15    67%
src/flint/types/acb_mat.pyx                375    113    70%
src/flint/test/__main__.py                  82     18    78%
src/flint/flint_base/flint_base.pyx        222     45    80%
src/flint/types/arb.pyx                    830    134    84%
src/flint/types/acb.pyx                    900    140    84%
src/flint/functions/showgood.pyx            61      8    87%
src/flint/types/fq_default.pyx             301     39    87%
src/flint/types/fmpz_series.pyx            189     13    93%
src/flint/types/fmpq_series.pyx            363     14    96%
src/flint/flint_base/flint_context.pyx      27      1    96%
src/flint/types/nmod_poly.pyx              335     11    97%
src/flint/types/fmpq_mpoly.pyx             461     11    98%
src/flint/types/fmpq_poly.pyx              272      5    98%
src/flint/types/fmpq.pyx                   229      4    98%
src/flint/types/fmpq_mat.pyx               247      4    98%
src/flint/types/nmod_mat.pyx               253      4    98%
src/flint/types/fmpz_mpoly.pyx             446      7    98%
src/flint/types/fmpz_poly.pyx              327      4    99%
src/flint/types/fmpz_mat.pyx               273      3    99%
src/flint/types/fmpz_mod_poly.pyx          595      5    99%
src/flint/test/test_all.py                2983      7    99%
src/flint/types/fmpz.pyx                   486      1    99%
src/flint/__init__.py                       34      0   100%
src/flint/flint_base/__init__.py             0      0   100%
src/flint/functions/__init__.py              0      0   100%
src/flint/pyflint.pyx                        3      0   100%
src/flint/test/__init__.py                   0      0   100%
src/flint/types/__init__.py                  0      0   100%
src/flint/types/fmpz_mod.pyx               210      0   100%
src/flint/types/fmpz_mod_mat.pyx           287      0   100%
src/flint/types/nmod.pyx                   135      0   100%
src/flint/types/nmod_series.pyx              1      0   100%
src/flint/utils/__init__.py                  0      0   100%
src/flint/utils/flint_exceptions.py          6      0   100%
------------------------------------------------------------
TOTAL                                    13168   2310    82%

You can see that it is also happening in CI after gh-181:
https://github.com/flintlib/python-flint/actions/runs/10385769844/job/28755628925?pr=182

@GiacomoPope
Copy link
Contributor Author

OK so setting the path might have been the issue, but I'm getting weird compilation errors now...

src/flint/types/fmpz_mpoly.c:6683:7: error: call to undeclared function 'fmpz_mpoly_push_term_fmpz_ffmpz'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
      fmpz_mpoly_push_term_fmpz_ffmpz(__pyx_v_res->val, ((struct __pyx_obj_5flint_5types_4fmpz_fmpz *)__pyx_v_o)->val, __pyx_v_exp_vec->val, __pyx_v_self->val);
      ^
src/flint/types/fmpz_mpoly.c:6683:7: note: did you mean 'fmpz_mpoly_push_term_fmpz_fmpz'?
/Users/Jack/Documents/GitHub/python-flint/.local/include/flint/fmpz_mpoly.h:499:6: note: 'fmpz_mpoly_push_term_fmpz_fmpz' declared here
void fmpz_mpoly_push_term_fmpz_fmpz(fmpz_mpoly_t A,
src/flint/types/fmpq_mpoly.c:7016:7: error: call to undeclared function 'fmpq_mpoly_push_term_fmpq_ffmpz'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
      fmpq_mpoly_push_term_fmpq_ffmpz(__pyx_v_res->val, ((struct __pyx_obj_5flint_5types_4fmpq_fmpq *)__pyx_v_o)->val, __pyx_v_exp_vec->val, __pyx_v_self->val);
      ^
src/flint/types/fmpq_mpoly.c:7016:7: note: did you mean 'fmpq_mpoly_push_term_fmpq_fmpz'?
/Users/Jack/Documents/GitHub/python-flint/.local/include/flint/fmpq_mpoly.h:488:6: note: 'fmpq_mpoly_push_term_fmpq_fmpz' declared here
void fmpq_mpoly_push_term_fmpq_fmpz(fmpq_mpoly_t A,

I can comment out these two lines, but further along I then get

5 warnings generated.
clang -bundle -undefined dynamic_lookup -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk -L/usr/local/opt/openssl@1.1/lib -I/usr/local/opt/openssl@1.1/include build/temp.macosx-14.0-x86_64-cpython-312/src/flint/types/fmpq_mpoly.o -lflint -o /Users/Jack/Documents/GitHub/python-flint/src/flint/types/fmpq_mpoly.cpython-312-darwin.so
No module named 'flint.types.fmpz_vec'

Which is super super weird.

I'll have to try and debug later

@oscarbenjamin
Copy link
Collaborator

This is possibly a problem with mixing setuptools and the in-place build vs editable install vs spin...

That's why I said to confirm that flint is not importable: you don't want coverage to pick up the wrong version of the module.

You might want to use a separate git checkout for the setuptools coverage build. Otherwise I would recommend using a full git clean and rebuilding the coverage build from scratch.

@oscarbenjamin
Copy link
Collaborator

Actually I think that you maybe have an old version of Flint installed in .local. Comment out the source bin/activate line in coverage.sh.

@GiacomoPope
Copy link
Contributor Author

yeah im not sure, i tried a few things and got different errors. ill have to come back to this another day

@GiacomoPope
Copy link
Contributor Author

I downloaded the branch clean and rand everything which compiled, but setting the python path to src breaks my imports.

clang -bundle -undefined dynamic_lookup -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk -L/usr/local/opt/openssl@1.1/lib -I/usr/local/include -L/usr/local/lib -I/usr/local/opt/openssl@1.1/include build/temp.macosx-14.0-x86_64-cpython-312/src/flint/functions/showgood.o -lflint -o /Users/Jack/Downloads/python-flint-add_fq_poly/src/flint/functions/showgood.cpython-312-darwin.so
ld: warning: search path '/Users/Jack/Downloads/python-flint-add_fq_poly/.local/lib' not found
No module named 'flint.pyflint'
Jack: python-flint-add_fq_poly % echo $PYTHONPATH
/Users/Jack/Downloads/python-flint-add_fq_poly/src

Here you can see i can import it, just things break when i run the bin/coverage with the python path set to source. If I set it to PWD I again only do coverage of the test stuff...

Jack: python-flint-add_fq_poly % python3
Python 3.12.4 (main, Jun  6 2024, 18:26:44) [Clang 15.0.0 (clang-1500.3.9.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import flint
>>> 
Jack: python-flint-add_fq_poly % python3 -m flint
/usr/local/opt/python@3.12/bin/python3.12: No module named flint.__main__; 'flint' is a package and cannot be directly executed

@oscarbenjamin
Copy link
Collaborator

You haven't said where you have installed Flint so I am assuming it is a system-wide install (i.e. not in .local). That is fine if that is the case but the coverage script sets environment variables assuming that you are using the .local install. I think that explains this warning:

ld: warning: search path '/Users/Jack/Downloads/python-flint-add_fq_poly/.local/lib' not found

I'm assuming that can be ignored.

If I set it to PWD

I think that one thing that is confusing things here is that you also have a separate installation of python-flint that is not just the code in the source directory i.e. it is in your virtual environment somewhere or something like that. To avoid confusion you should pip uninstall python-flint or conda uninstall python-flint.

If you don't set PYTHONPATH then it should not be possible to import flint at all:

$ python -m flint
/home/oscar/.pyenv/versions/python-flint-3.11/bin/python: No module named flint
$ python
Python 3.11.3 (main, Apr  5 2023, 23:03:48) [GCC 11.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import flint
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'flint'

This error message is expected:

$ python3 -m flint
/usr/local/opt/python@3.12/bin/python3.12: No module named flint.__main__; 'flint' is a package and cannot be directly executed

The flint package is not executable because it has no __main__. The flint.test subpackage does though so you need to use:

python3 -m flint.test

@oscarbenjamin
Copy link
Collaborator

Also if you can import flint then print out flint.__path__. That might give a clue as to what is going on. Make sure you have no other files called flint.py or directories called flint.

@GiacomoPope
Copy link
Contributor Author

GiacomoPope commented Aug 14, 2024

I dunno why, but it just doesnt behave as yours does.

Jack: python-flint-add_fq_poly % python3 -m flint
/usr/local/opt/python@3.12/bin/python3.12: No module named flint
Jack: python-flint-add_fq_poly % python3 -m flint.test
/usr/local/opt/python@3.12/bin/python3.12: Error while finding module specification for 'flint.test' (ModuleNotFoundError: No module named 'flint')
Jack: python-flint-add_fq_poly % python3 setup.py build_ext --inplace
running build_ext
Jack: python-flint-add_fq_poly % PYTHONPATH=src ./bin/coverage.sh
running build_ext
No module named 'flint.pyflint'
Jack: python-flint-add_fq_poly % PYTHONPATH=. ./bin/coverage.sh      
running build_ext
Running tests...
test_pyflint...OK
test_showgood...OK
test_fmpz...OK
test_fmpz_factor...OK
test_fmpz_functions...OK
...
flint.test: all 51 tests passed!
flint.test: all 3323 doctests passed!
----------------------------------------
OK: Your installation of python-flint seems to be working just fine!
----------------------------------------
Wrote HTML report to htmlcov/index.html

Then the coverage at the end of this call (which actually does something) is the one which shows the test coverage

@oscarbenjamin
Copy link
Collaborator

I don't understand why PYTHONPATH=. works. That shouldn't work unless you have a directory called flint inside . which you shouldn't have (it should be under ./src).

Then the coverage at the end of this call (which actually does something) is the one which shows the test coverage

I can think of one reason why you are only seeing coverage of .py files rather than Cython files though. You need to set this:

python-flint/setup.py

Lines 60 to 63 in 5445684

# Enable coverage tracing
if os.getenv('PYTHON_FLINT_COVERAGE'):
define_macros.append(('CYTHON_TRACE', 1))
compiler_directives['linetrace'] = True

Without that the Cython-generated C code will not output any tracing events that coverage can use to measure the coverage.

That is set by the coverage script:

export PYTHON_FLINT_COVERAGE=true
# Force a rebuild of everything with coverage tracing enabled:
# touch src/flint/flintlib/*
python setup.py build_ext --inplace

However note the commented out line to "force a rebuild". When you run the coverage script no rebuilding is happening as you showed above:

Jack: python-flint-add_fq_poly % python3 setup.py build_ext --inplace
running build_ext

There is a problem with Cython's setuptools build that it does not properly detect when a rebuild is needed in the way that meson does. With meson if you do:

meson configure build -Dcoverage=true

Then meson will detect if this requires rebuilding everything or not. Setuptools and Cython's cythonize are not so clever though. That is why the touch line is there in the coverage script but it is commented out because you don't usually want a full rebuild when just running the tests.

You need to build something like:

touch src/flint/flintlib/*
PYTHON_FLINT_COVERAGE=true python3 setup.py build_ext --inplace

Then something like this hopefully works:

coverage run -m flint.test
PYTHONPATH=src coverage run -m flint.test
PYTHONPATH=. coverage run -m flint.test

@GiacomoPope
Copy link
Contributor Author

Just to show paths, this is the current set up:

Jack: python-flint-add_fq_poly % ls
LICENSE               bin/                  htmlcov/              pyproject.toml        src/
MANIFEST.in           build/                meson.build           requirements-dev.txt
README.md             doc/                  meson.options         setup.py
Jack: python-flint-add_fq_poly % PYTHONPATH=. ./bin/coverage.sh       
running build_ext
Running tests...
test_pyflint...OK
test_showgood...OK
test_fmpz...OK

I will try everything you say above though :)

@GiacomoPope
Copy link
Contributor Author

GiacomoPope commented Aug 14, 2024

I ran:

Jack: python-flint-add_fq_poly % touch src/flint/flintlib/* 
Jack: python-flint-add_fq_poly % env "CFLAGS=-I/usr/local/include -L/usr/local/lib" PYTHON_FLINT_COVERAGE=true python3 setup.py build_ext --inplace

Which rebuilt everything, as expected. Then

Jack: python-flint-add_fq_poly % coverage run -m flint.test
...
flint.test: all 3323 doctests passed!
----------------------------------------
OK: Your installation of python-flint seems to be working just fine!
----------------------------------------
Jack: python-flint-add_fq_poly % coverage report
Name                                                                                       Stmts   Miss  Cover
--------------------------------------------------------------------------------------------------------------
/Users/Jack/Library/Python/3.11/lib/python/site-packages/flint/__init__.py                    34      0   100%
/Users/Jack/Library/Python/3.11/lib/python/site-packages/flint/flint_base/__init__.py          0      0   100%
/Users/Jack/Library/Python/3.11/lib/python/site-packages/flint/functions/__init__.py           0      0   100%
/Users/Jack/Library/Python/3.11/lib/python/site-packages/flint/test/__init__.py                0      0   100%
/Users/Jack/Library/Python/3.11/lib/python/site-packages/flint/test/__main__.py               82     19    77%
/Users/Jack/Library/Python/3.11/lib/python/site-packages/flint/test/test_all.py             2830      7    99%
/Users/Jack/Library/Python/3.11/lib/python/site-packages/flint/types/__init__.py               0      0   100%
/Users/Jack/Library/Python/3.11/lib/python/site-packages/flint/utils/__init__.py               0      0   100%
/Users/Jack/Library/Python/3.11/lib/python/site-packages/flint/utils/flint_exceptions.py       6      0   100%
/usr/local/lib/python3.11/site-packages/_distutils_hack/__init__.py                           97     92     5%
--------------------------------------------------------------------------------------------------------------
TOTAL                                                                                       3049    118    96%

If I try and point to the src

Jack: python-flint-add_fq_poly % PYTHONPATH=src coverage run -m flint.test
No module named 'flint.pyflint'

Unsurprisingly

Jack: python-flint-add_fq_poly % PYTHONPATH=. coverage run -m flint.test

Does the same as no PATH set :)

@oscarbenjamin
Copy link
Collaborator

You have another installation of python-flint here which is being picked up:

/Users/Jack/Library/Python/3.11/lib/python/site-packages/flint/__init__.py  

You possibly installed that with e.g. pip install python-flint in which case it got downloaded from PyPI. The PyPI builds don't have coverage enabled. This is probably being picked up by coverage because your coverage comes from that Python installation. Try e.g. which coverage to see where coverage comes from.

To avoid confusion uninstall that python-flint until you have things working.

You can also run coverage like:

python3 -m coverage

That makes sure to run coverage from the environment that corresponds to your python3 command.

The import failure when you set PYTHONPATH=src is because it is a different version of Python and the extension modules are specific to the version:

$ ls src/flint/pyflint.*
src/flint/pyflint.c                                src/flint/pyflint.pxd
src/flint/pyflint.cpython-311-x86_64-linux-gnu.so  src/flint/pyflint.pyx

You are building the extensions with Python 3.12 or something but then running coverage from a separate Python 3.11 installation.

@GiacomoPope
Copy link
Contributor Author

OMG I'm so stupid. Thank you for noticing this. My stupid mac has python3.12 under python3 but some python apps remain from an older 3.11

Jack: python-flint-add_fq_poly % python3 -m coverage run -m flint.test
No module named 'flint'
Jack: python-flint-add_fq_poly % PYTHONPATH=src python3 -m coverage run -m flint.test
Running tests...
test_pyflint...OK
test_showgood...OK
test_fmpz...OK
test_fmpz_factor...OK

Looks good!

Jack: python-flint-add_fq_poly % python3 -m coverage report                          
Name                                                                                   Stmts   Miss  Cover
----------------------------------------------------------------------------------------------------------
/Users/Jack/Library/Python/3.12/lib/python/site-packages/_distutils_hack/__init__.py     101     96     5%
src/flint/__init__.py                                                                     35      0   100%
src/flint/flint_base/__init__.py                                                           0      0   100%
src/flint/flint_base/flint_base.pyx                                                      222     42    81%
src/flint/flint_base/flint_context.pxd                                                     8      4    50%
src/flint/flint_base/flint_context.pyx                                                    27      1    96%
src/flint/functions/__init__.py                                                            0      0   100%
src/flint/functions/showgood.pyx                                                          61      8    87%
src/flint/pyflint.pyx                                                                      3      0   100%
src/flint/test/__init__.py                                                                 0      0   100%
src/flint/test/__main__.py                                                                86     19    78%
...

I have normal life things to do, but I will work on tests and coverage as the next commit to this repo. thanks for all your help

@oscarbenjamin
Copy link
Collaborator

This is another good reason to get spin coverage working.

I'll have another look at it.

@GiacomoPope
Copy link
Contributor Author

From the CI:

...
src/flint/types/fmpz_mod_poly.pyx          596      5    99%
src/flint/types/fq_default.pyx             290      1    99%
src/flint/test/test_all.py                3143      7    99%
src/flint/types/fmpz.pyx                   486      1    99%
src/flint/types/fq_default_poly.pyx        489      1    99%
...

Which means the targets for this PR seem to have high coverage. Happy for this to go through any last reviews now :)

``True``, ensures that the output is irreducible.

TODO: there is currently no fq_defualt_poly method for testing that
a polynomial is irreducible?!
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can add one here.

Apart from shortcutting some simple cases the general way to check is just to factorise the polynomial.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh this is outdated there is one it was just in the poly_factor header file rather than the poly header so I missed it when I was writing this.

Comment on lines +1620 to +1624
n_max = fq_default_poly_deflation(
self.val, self.ctx.field.val
)
if n > n_max:
raise ValueError(f"Cannot deflate with {n = }, maximum allowed value is {n_max = }")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this check necessary to prevent a core dump or something?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so, I had to do it for fmpz_mod and I just assumed the same check would need to be here (It will definitely need to be for the FMPZ_MOD type I suppose if nothing else...)

@oscarbenjamin
Copy link
Collaborator

I went through and it looks good. I just had one comment and another question.

@GiacomoPope
Copy link
Contributor Author

I realised that even though inverse mod is missing from FLINT we can just implement it with xgcd, so I did that quickly before bed

@oscarbenjamin
Copy link
Collaborator

Okay, looks good. Thanks again!

@oscarbenjamin oscarbenjamin merged commit ba1a7fe into flintlib:master Aug 16, 2024
32 checks passed
@GiacomoPope GiacomoPope deleted the add_fq_poly branch September 2, 2024 15:58
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

Successfully merging this pull request may close these issues.

2 participants