Repository: LMFDB/lmfdb

Issue:
Dirichlet character server error
The page https://www.lmfdb.org/Character/Dirichlet/68800/66667 is throwing a server error


Discussion:
Hm, I thought that #5621 fixed these kind of issues, but I guess there's another problem.
The problem is that, in the `galois_orbit` method
```
if order == 1:
    return [1]
elif order < limit or order * order < limit * self.modulus:
    return self.galois_orbit_all(limit)
elif limit == 1 or self.modulus < 30 * order:
    return self.galois_orbit_search(limit)
else:
    logger.debug(f"galois orbit of size {order} too expansive, give up")
    return []
```
we fall into the last case and give up (`modulus=68800` and `order=1680`), but we need to have at least one thing in the orbit in order to be able to look up from the database.
The first cahracter in the orbit is 68800.83.  It takes less than 60 ms to compute this in Magma using https://github.com/AndrewVSutherland/Magma/blob/main/chars.m#L393.  Are we sure this is still slow in the python+gp implementation?  If so, I'm sure @pascalmolin could figure out a way to speed it up, I would expect gp to be faster at this than my (somewhat hacky) Magma implementation.
Actually the function `MinimalConreyConjugate` in https://github.com/AndrewVSutherland/Magma/blob/main/chars.m#L320 does exactly what is needed here, and `MinimalConreyConjugate(68800,66667)` takes less than 10 milliseconds.  It is just 3 lines of code that I'm sure could be implemented in Sage or a call to gp (doing it in Sage might be faster due to the overhead of calling gp from Sage).
Yeah, this is basically what `galois_orbit_all(1)` does (defined [here](https://github.com/LMFDB/lmfdb/blob/master/lmfdb/characters/TinyConrey.py#L223)).  It takes 6ms in this case, so changing the cutoffs would certainly be helpful.  But we probably do want some cutoffs...
How about modulus or order 1,000,000 as a cutoff (this is how far I plan to extend the database of stored orbit data).

Resolving patch:
diff --git a/lmfdb/characters/TinyConrey.py b/lmfdb/characters/TinyConrey.py
--- a/lmfdb/characters/TinyConrey.py
+++ b/lmfdb/characters/TinyConrey.py
@@ -213,7 +213,7 @@ def galois_orbit(self, limit=31):
         elif order < limit or order * order < limit * self.modulus:
             logger.debug(f"compute all conjugate characters and return first {limit}")
             return self.galois_orbit_all(limit)
-        elif limit == 1 or self.modulus < 30 * order:
+        elif limit == 1 or self.modulus <= 1000000:
             logger.debug(f"compute {limit} first conjugate characters")
             return self.galois_orbit_search(limit)
         else:


Test patch:
diff --git a/lmfdb/characters/test_characters.py b/lmfdb/characters/test_characters.py
--- a/lmfdb/characters/test_characters.py
+++ b/lmfdb/characters/test_characters.py
@@ -142,6 +142,9 @@ def test_dirichletgalorbs(self):
         W = self.tc.get('/Character/Dirichlet/9999999999/banana', follow_redirects=True)
         assert 'Error: Galois orbits have only been computed for modulus up to 100,000' in W.get_data(as_text=True)
 
+        W = self.tc.get('/Character/Dirichlet/58589/50021', follow_redirects=True)
+        assert 'Number field defined by a degree 1428 polynomial' in W.get_data(as_text=True)
+
     def test_dirichletchar11(self):
         W = self.tc.get('/Character/Dirichlet/1/1')
         assert '/NumberField/1.1.1.1' in W.get_data(as_text=True)