1 | initial version |

The following may be a solution for small values of the degree of the cyclotomic field. In order to have a handy situation, where tests and prints are easy to follow, i will use `P, N = 19, 18`

instead of the data `P, N = 53, 52`

, extracted and generalized from the post. It may be that the following fails for bigger values of `P, N`

.

Let us start with:

```
P, N = 19, 18
F.<a> = CyclotomicField( P )
L.<b> = F.extension( cyclotomic_polynomial(N) )
V, psi, phi = L.relative_vector_space()
```

That's all. The values `a`

and `b`

correspond to
begin{align}
a&=\zeta_P=\zeta_{19}\ ,\\
b&=\zeta_N=\zeta_{18}\ ,\text{ so that }\\
c=\frac ba&=\zeta_{PN}
\end{align}
corresponds to a primitive root of order $PN=19\cdot 18$. ("This" works for relatively prime numbers $P,N$, the powers of $a$ and $b$ were copy+pasted from $\frac 1{18}- \frac 1{19}=\frac 1{18\cdot 19}$. For other $P,N$...)

The above code constructs the following objects:

```
sage: V
Vector space of dimension 6 over Cyclotomic Field of order 19 and degree 18
sage: psi
Isomorphism map:
From: Vector space of dimension 6 over Cyclotomic Field of order 19 and degree 18
To: Number Field in b with defining polynomial x^6 - x^3 + 1 over its base field
sage: phi
Isomorphism map:
From: Number Field in b with defining polynomial x^6 - x^3 + 1 over its base field
To: Vector space of dimension 6 over Cyclotomic Field of order 19 and degree 18
sage:
```

Above, $V$ is the (canonical) vector space $F^{\texttt{euler_phi}(N)}$.

We have the maps $\phi:!L\to V$ and $\psi:V\to !L$ (where the $!$ stays for the forgetful functor from field extensions of $F$ to vector spaces over $F$).

Code samples illustrating the way computations can be done:

```
sage: phi(1)
(1, 0, 0, 0, 0, 0)
sage: phi(b)
(0, 1, 0, 0, 0, 0)
sage: phi(b^2)
(0, 0, 1, 0, 0, 0)
sage: phi(b^3)
(0, 0, 0, 1, 0, 0)
sage: phi(b^4)
(0, 0, 0, 0, 1, 0)
sage: phi(b^5)
(0, 0, 0, 0, 0, 1)
sage: b^6
b^3 - 1
sage: phi(b^6)
(-1, 0, 0, 1, 0, 0)
```

This would be the solution, a structural, sage-specific solution, but it appears to be a **very slow** one.
And it is good possible, that this way to define `L`

in a tower is not the suitable way in application, where the direct definition via `CyclotomicField( P*N )`

is the natural one.

For these reasons, here is an other way to define elementwise an isomorphism. Letters have a slightly different meaning.

This gives:

```
P, N = 53, 52
F.<a> = CyclotomicField( P )
K.<c> = CyclotomicField( P*N )
L.<b> = CyclotomicField( N )
D = euler_phi( N )
W = F^D
def phi( k ):
"""For k in K deliver its image in W.
Here we simplify the program by considering F, K, a, c, N, P above as globals...
"""
w = W(0) # and we add, then finally return w
coeffs = k.lift().coefficients(sparse=False)
# if coeffs is [0,0,...,0, 1 on position L, 0,0,0,...,0]
# then this k corresponds to c^L
# rewrite c^L = (b/a)^L = b^L / a^L and reduce b^L (and a^L)
# here a^L = a^(L modulo P) and it can still be reduced, but we do not need this,
# since the coefficients in the final vector are in F.<a> and sage it computes for us.
# we need only to rewrite b^L in terms of 1, b, b^2, ... with powers < euler_phi(N).
for L in range(len(coeffs)):
if not coeffs[L]:
continue
bL_coeffs = (b^L).lift().coefficients(sparse=0) # i need padto= but...
bL_coeffs += [ QQ(0) for _ in range(D - len(bL_coeffs)) ]
w += coeffs[L] * a^(-L) * W( bL_coeffs )
return w
# test the above, e.g. the F-linearity
k = 777 + c + c^2 + c^20 + c^100
aK = c^N
struc = F.Hom( K, Fields() )( aK ) # a -> aK, structural morphism
for L in [1..9]:
print "check for phi(a^%s k) == a^%s phi(k) :: %s" % (L, L, bool( phi(struc(a^L)*k) == a^L*phi(k) ) )
```

The test gives:

```
check for phi(a^1 k) == a^1 phi(k) :: True
check for phi(a^2 k) == a^2 phi(k) :: True
check for phi(a^3 k) == a^3 phi(k) :: True
check for phi(a^4 k) == a^4 phi(k) :: True
check for phi(a^5 k) == a^5 phi(k) :: True
check for phi(a^6 k) == a^6 phi(k) :: True
check for phi(a^7 k) == a^7 phi(k) :: True
check for phi(a^8 k) == a^8 phi(k) :: True
check for phi(a^9 k) == a^9 phi(k) :: True
```

We have tested the $F$-multiplicativity for the ad-hoc map $\phi$ map $K\to W$ in some particular cases. For the additivity:

```
k1, k2 = K.random_element(), K.random_element()
phi(k1+k2) == phi(k1) + phi(k2)
```

This time i was lucky, got

```
True
```

Copyright Sage, 2010. Some rights reserved under creative commons license. Content on this site is licensed under a Creative Commons Attribution Share Alike 3.0 license.