Closed williamstein closed 16 years ago
Description changed:
---
+++
@@ -36,7 +36,7 @@
CPU time: 23.93 s, Wall time: 26.22 s
-NOTE: Sage should use PARI for charpoly's over number +NOTE: Sage should use PARI for charpoly's over number fields, but currently it doesn't. Notice how much faster PARI is at the same computation!
@@ -48,13 +48,12 @@ Time: CPU 2.52 s, Wall: 2.76 s
-But a <b>multimodular algorithm</b> should blow away all of them. Student project?
+But a **multimodular algorithm** should blow away all of them. Student project?
Basically, charpoly mod p is extremely fast in Sage, and one could reduce modulo
-<i>primes of a number field</i>, do the computation mod p, then lift, and get the
+*primes of a number field*, do the computation mod p, then lift, and get the
correct result. I know of no implementations of this. A student project could be
to implement this and tune it to be the fastest program in the world for charpoly
over number fields.
-<br>
time m.echelonize()
The following IRC transcript is relevant.
ncalexan-827: wstein-1606: is there a good way to find degree 1 primes in a number field.
ncalexan-827: ?
wstein-1606: theoretically or in sage right now?
ncalexan-827: wstein-1606: right now, but also in theory.
wstein-1606: for all but finitely many primes you factor the defining poly of the field and see if it splits completely.
dmharvey left the chat room.
wstein-1606: you can do that more quickly by taking the gcd mod p with x^p - x
ncalexan-827: Right.
wstein-1606: or something like that.
wstein-1606: I bet you get the idea.
ncalexan-827: Doesn't this only work if your ring of integers is generated by a single element?
wstein-1606: nick -- that's why I said "all but finitely many".
wstein-1606: For all but a couple primes the ring of integers is monogenic.
wstein-1606: just avoid primes dividing the discriminant.
wstein-1606: for those do the usual factorization algorithm.
ncalexan-827: wstein-1606: sure. It sounds like a degree_one_primes() generator would be handy for multi modular algorithms, then.
wstein-1606: yep!
wstein-1606: But beware -- it is very very very hard to find any degree one primes if the field isn't cyclotomic.
wstein-1606: For a galois S_n extension of degree n, only 1/n! of the primes split completely (by cebo.)
ncalexan-827: Hmm. So it's not even worth it?
wstein-1606: Well it's very worth it in the cyclotomic case.
wstein-1606: more generally, in the abelian case.
wstein-1606: E.g., for quadratic fields.
wstein-1606: and even 1/n! isn't bad if n is small, which it often is.
I needed exactly this for my work on Unimodular Integer Circulants (To appear in: Mathematics of Computation) or see my web page. At the time I used pari and have been meaning to try it in Sage too. Rather than take gcd(f,x^p-x) -- all mof p of course -- , I took Mod(x,fMod(1,p))^p and that worked pretty well. My worst example: deg(f) = 18, the first degree 1 prime was about 250 million and did not work for me so I sed the second one which was around 2 billion. This poly has a Galois group of order only 2(n/2)! ; if it been the generic n! I would probably still be waiting.
This suggests to me that for anything other than small degrees the implementation will need to use primes of higher degree.
See #2835 for a possible primes of degree one iterator implementation.
Attachment: 903-charpoly_pari.patch.gz
I suggest that we implement the easy fix and get that merged, and open an enhancement ticket along the lines "implement multimodular algorithm for charpoly over number fields".
I'm attaching a patch with the easy fix. On my machine, William's example runs 15 times faster after the patch than before.
I am not happy with this patch. I want to see an explicit doctest (not random) that has a polynomial defined over the number field, not over QQ.
I also want to see doctests for stacked relative fields -- I.e.
x = QQ['x'].gen()
K.<a> = NumberField(x^2 - 2)
L.<b> = K.extension(x^3 - a)
M.<c> = L.extension(x^2 - a*x + b)
and see it work for matrices over all those fields.
This is hard -- we need polynomials over arbitrary pari number fields, and it doesn't work for #2329 yet, so it shouldn't work here yet.
Attachment: 903-charpoly_pari_doctests.patch.gz
apply after 903-charpoly_pari.patch
The point about the doctests is correct. I put up a new patch that adds the appropriate doctests and fixes a small bug (due to some unrelated weirdness that I don't want to deal with right now).
The doctests pass and I checked the results. It looks to me like it's working, so I'm not sure I agree with the last part of the last comment.
The patches apply and pass tests for me. Nick, what are your thoughts?
I prefer the attached patch because it does not require string parsing, at least not in the code. It will be more robust to changes to PARI and uses the Sage library. It's shorter, too, and I prefer the factored-out function.
Nick's patch applies and passes the tests. I think it is preferable since it avoids string parsing. I'm going to give it a positive review. Alex, if you disagree, feel free to comment and change it.
Yes, I much prefer Nick's code over mine. I was struggling to get things from Pari into Sage and the way I was doing things was obscure and rather fragile.
There is one problem I run into with this: 2 doctests in number_field_element.pyx fail. Probably an easy fix?
Attachment: 903-small_fix.patch.gz
apply after Nick's patch
It was indeed an easy fix. Pari treats the t_POLMOD 0 in a different way than the others, so the code chocked on that. I've put up a patch that fixes this and adds a direct doctest for this behavior.
We should apply 903-ncalexan-charpoly-over-number-field-1.patch and 903-small_fix.patch. When this ticket gets closed we should make a new enhancement ticket containing the above discussion of a multimodular algorithm.
BTW, in 3.0.alpha5, before the patches:
sage: K.<a> = NumberField(x^2 + 17)
sage: n = 40
sage: m = matrix(K, n, [(a+1)^randint(0,3) for _ in xrange(n^2)])
sage: time f = m.charpoly('Z')
CPU times: user 59.69 s, sys: 0.01 s, total: 59.70 s
Wall time: 59.70
and after the patches:
sage: K.<a> = NumberField(x^2 + 17)
sage: n = 40
sage: m = matrix(K, n, [(a+1)^randint(0,3) for _ in xrange(n^2)])
sage: time f = m.charpoly('Z')
CPU times: user 3.96 s, sys: 0.02 s, total: 3.98 s
Wall time: 3.98
903-ncalexan-charpoly-over-number-field-2.patch
stands alone, and doesn't muck about with PARI at all: it turns out that polynomials over number fields work to the extent that special parsing is not necessary.
BTW, great team effort guys!
I love the end result, it's so clean and simple (I wish there was a way to delete my old patches from this ticket, I'm somewhat embarrassed :)
Anyway, it works great and fast and it should be merged.
Nick, Alex,
am I correct to understand that I must only apply 903-ncalexan-charpoly-over-number-field-2.patch?
it applies by itself and does build, and doctests fine.
Cheers,
Michael
Merged 903-ncalexan-charpoly-over-number-field-2.patch in Sage 3.0.alpha6 only. In case that is not what is intended please comment here and I will merge those patches.
Cheers,
Michael
Yes, that patch was the only one that needed merging.
See the below examples that illustrate that charpoly(A), where A is over a number field, currently totally sucks. This has very bad implications for modular forms computations. Even switching to use PARI for charpoly would give a significant speedup (which is a lot faster than Magma, interestingly).
NOTE: Sage should use PARI for charpoly's over number fields, but currently it doesn't. Notice how much faster PARI is at the same computation!
But a multimodular algorithm should blow away all of them. Student project? Basically, charpoly mod p is extremely fast in Sage, and one could reduce modulo primes of a number field, do the computation mod p, then lift, and get the correct result. I know of no implementations of this. A student project could be to implement this and tune it to be the fastest program in the world for charpoly over number fields.
Component: linear algebra
Issue created by migration from https://trac.sagemath.org/ticket/903