fredstro/psage — pull request #4 by sehlen (2013-10-17 12:13:55+00:00)
Title: Mainly fix for 2-adic Jordan decomposition

Please check that the following patch works.

## Bug description 1
I corrected the calculation of the Jordan decomposition. The 2-signature was broken
producing wrong genus symbols and wrong characteristic invariants
for certain FQMs.

For instance this happened *before*:
```
sage: M = FiniteQuadraticModule('2^-2.2_1^1'); M
Finite quadratic module in 3 generators:
gens: e0, e1, e2
form: 1/2*x0^2 + 1/2*x0*x1 + 1/2*x1^2 + 1/4*x2^2
sage: M.jordan_decomposition().genus_symbol()
2_5^-3
```

But this is clearly wrong and at least inconsistent, as this example shows:
```
sage: M
Finite quadratic module in 3 generators:
gens: e0, e1, e2
form: 1/4*x0^2 + 1/4*x1^2 + 3/4*x2^2
```

Thus, the module 2_5^-3 is _isotropic_, whereas
2^-2.2_1^1 is in fact equal to 2_1^-3 and is _anisotropic_!

## Here is how I fixed this:

The method orthogonal_basis() does not always return an orthogonal basis.
This seems to be a known problem which I didn't fix. This occurs in particular in the example above.
The matrix F that is calculated in __init__(self) of JordanDecomposition will be equal to
[ 1 0 0 ]
[ 0 2 1 ]
[ 0 1 2 ]
in the first example above.
However, the "even block" now contributes a 4 to the trace, which is not the oddity of that block, which is 0.
The point here is that changing the basis will result in a change of the trace as we do *not* just conjugate.
I solved this by ignoring all even diagonal entries when calculating the trace.
This should always give the correct result as long as the "orthogonal basis" that is used to compute F is at least orthogonal on the direct sum of simple odd components. This seems to be the case (please double check).

## Second bug
There was another bug which I forgot to document in the commits:
The characteristic invariants were not always computed correctly.
Check out this example. This is how it was *before*:

```
sage: M = FiniteQuadraticModule('4_0^2'); M
Finite quadratic module in 2 generators:
gens: e0, e1
form: 1/8*x0^2 + 7/8*x1^2
sage: M.char_invariant(4)
(1, 1)
```

The correct result should be 0:
```
sage: z = CyclotomicField(M.level()).gen()
sage: sum([z**(M.Q(x)*M.level()*4) for x in M])
0
```

This bug was due to line 572 in the old code. See the change in the diff (line 572 removed, new line: 563).

## Further remarks/changes
* I also implemented the p-signatures, maybe in a slightly funny way. I take it for granted that the output of the char_invariant(1,p) give me e_8(p-sign) as the first component of the output as an element of CyclotomicField(8). I take the representation as a vector in terms of the power basis 1,zeta_8, zeta_8^2,zeta_8^3 and read off the sign mod 8.