Thursday, 29 August 2013

padicxx again

I spent most of the morning thinking about the changes to padicxx related to my discussion with Sebastian and Bill. I think that I have now come up with a reasonable way to implement the design we agreed upon. I changed padicxx accordingly, and also wrote enough of padic_polyxx to see that this class will also work out.

Hence not a particularly productive day code-wise, but I expect to be able to use all of todays thinking to finish all the ?adic* classes tomorrow.

Wednesday, 28 August 2013

Another productive day

Today I did the following:

  • implement hensel lifting code for fmpzxx
  • fix a const correctness problem in fmpz_poly_mat
  • implement prod for fmpz_poly_matxx
  • implement solve_fflu_precomp for fmpz_poly_matxx and nmod_poly_matxx
  • implement various four-argument functions for nmod_polyxx
  • implement bit_pack and bit_unpack for fmpzxx
 This means that the only coding related tasks of priority (H) or (M) left on my TODO list are ustream and ?adic*. Yay!

Tuesday, 27 August 2013

Still more work to do

Today I finished the construction and randtest interfaces, added row reduction and lu decomposition interfaces to all matrix classes, and added radix conversion functionality for fmpz_mod_poly.

Monday, 26 August 2013

We're getting there

I'm in the process of working through my todo list of things which need to be done before the project can be finished. This is going to take a while, but seeing the list shrink is encouraging. Today I added conversion and construction interfaces to most classes, added static versions of randtest to classes which didn't have that, yet, and started adding set_zero, set_one functions. None of this is hard, but it all takes time ...

Thursday, 22 August 2013

work work work

Now that most classes are finished to some extent, it is hard to keep track of the work I'm doing, since it is all scattered about. Today I
  • fixed make install
  • implemented the ustream prototype (c/f mailing list)
  • removed the n % ctx syntax to construct an nmodxx 
  • added nmodxx::reduce static function replacing the member functions of fmpz_polyxx and fmpq_polyxx.
  • implemented fourary and fiveary expression templates
  • implemented the CRT function for fmpzxx

Wednesday, 21 August 2013

Factorisation code

I didn't write a blog post in a while since I have been active on the list. For this reason there has been a lot of progress since the last one, which I am not going to mention in detail. Instead, let me just focus on today's work: I implemented wrappers for the factorization functionality in flint (recall that this is one of the (H)igh priority tasks that need finishing). Hence there are new classes fmpz_factorxx, nmod_poly_factorxx, fmpz_poly_factorxx, fmpz_mod_poly_factorxx, together with associated methods/functions. As far as I can tell this is all the factoring functionality. This was quite a marathon, but I implemented, tested, and documented all of these today.

Wednesday, 14 August 2013

More progress, with an end almost visible.

Today was a good day. I finished nmod_matxx, documented it, added a codegen test. Then I started and finished nmod_poly_matxx and documented it. Finally I started fmpz_mod_poly. After this is done tomorrow (hopefully), we will nominally have initial versions of wrapper classes for every flint type. (Nominally, because quadic is missing (but it is not yet documented, either), and because the nmod_vecxx/fmpz_vecxx classes are very spartanic - but then again in flint they only have underscore methods, so...)

Tuesday, 13 August 2013

nmod_matxx and some

This morning I started out by writing codegen tests for nmod_polyxx. The results are in line with my expectations: the C++ code is generally a bit longer than handwritten C, but not much. Specifically

void test_nmod_polyxx_1(nmod_polyxx& to, const nmod_polyxx& p1,
            const nmod_polyxx& p2)
    to = (p1*p1) + (p2*p2);

void test_nmod_polyxx_3(nmod_polyxx& to, const nmod_polyxx& p1,
            const nmod_polyxx& p2)
    to = ((p1*p1) + (p2*p2)) + ((p1*p2) + (p2*p1));

Both come out about 20% longer than C equivalents, and using a few more stack spill frames (and precisely the same FLINT function calls). Recall that for fmpzxx and similar the code usually gets 10% longer; I attribute this to the fact that nmod_polyxx instantiation requires an additional argument (the modulus) which has to be kept track of.

After that, I wrote a new helper file flintxx/matrix.h encapsulating some code common to (probably) all matrix classes, updated fmpz_matxx to use it, and then I started nmod_matxx (using this new helper). I'm about 75% through with the nmod_matxx functions, will finish and document this tomorrow.

Monday, 12 August 2013


Today I finished nmod_polyxx (with the usual reservations). Along the way I implemented nmod_vecxx (with very limited functionality) and reference types for nmodxx.

I also extended create_doc.c to allow for opening subsections using lines of pluses instead of stars; with the new version of the program using a leg grammar this was done in about five minutes. I then documented nmod_polyxx, using the same subsection structure as the nmod_poly_t documentation.

The only thing left to do with nmod_polyxx for now is writing codegen tests; this I will do first thing tomorrow.

Thursday, 8 August 2013

fmpz_matxx again

First of all, yesterday was an unproductive day. I got up feeling slightly sick, and spent about two hours writing documentation. Then I gave up for the day and went back to bed.

Fortunately, all seems to be fine again today. I finished yesterday's documentation task; now finally all documentation is up to speed again with respect to the recent library changes. After that, I finished the fmpz_matxx class, at least to the extent that other classes are finished, and documented it.

Tuesday, 6 August 2013

Lots and lots of documenting

As announced yesterday, this morning I finished adding member functions to all the existing wrapper classes. After that, I began the task of bringing my documentation up to date with respect to the changes of the last week(s). This is again a fairly laborious task; I estimate I am about halfway through.

Monday, 5 August 2013


Today I began implementing some more improvements to the existing wrapper classes suggested by Bill / John Cremona. First I added "complex component access" functionality to all classes where it makes sense. The easiest example is fmpqxx. The following all work:

fmpqxx a(3, 4u);
a.num() = 5;
std::cout << (a+a).num() << '\n';

 In particular, depending on the object type, num() will return a reference to the denominator, or constant reference, or an expression template.

After that, I began adding member functions for all global functions. So one can e.g. do a.divrem(b) instead of divrem(a, b). As is to be expected, this process is quite laborious (simply because there are a lot of functions in flint), and I will have to continue it tomorrow. Then I will also update the documentation.

Thursday, 1 August 2013

some more honest work

This morning I implemented getters for ltuples. You can now do things like

fmpzxx a;
int b = 0;
ltupleref(a, b).get<0>() == a;

Depending on the situation, the get() call may evaluate a lazy tuple (if the return type cannot be made lazy), or yield a lazy expression, or yield a reference without needing to evaluate (if the tuple itself is immediate).

After that I began work on allowing lazy functions with more than two arguments. This requires writing generic code to evaluate n possibly lazy expressions. Things can get as complicated as one wants, but for the sake of (a) simplicity, (b) compilation performance and (c) because of my distrust in the optimizer, I have now decided to do the following: If there are precisely two non-immediate subexpressions, do the clever logic we already have. Otherwise, we evaluate things strictly in-order.

This way no tests are broken, and the minimal number of temporaries is used if there are at most two non-immediate subexpressions. If there are more than two, then the code might be (slightly) non-optimal. I assume this should not be a particularly common case.