Finished implementation of isomorphism computation
This commit is contained in:
parent
31528d9202
commit
48e50dcd72
|
@ -234,8 +234,9 @@ def wedderburn_splitting_large_field(C):
|
|||
f = a.minimal_polynomial()
|
||||
if f.degree() == d:
|
||||
break
|
||||
return splitting_from_idems(C, idems_from_element(a))
|
||||
|
||||
splits = splitting_from_idems(C, idems_from_element(a))
|
||||
return [(split[0], [split[2](b) for b in split[0].basis()])
|
||||
for split in splits]
|
||||
|
||||
def wedderburn_splitting_small_field(C):
|
||||
r"""
|
||||
|
@ -244,21 +245,20 @@ def wedderburn_splitting_small_field(C):
|
|||
"""
|
||||
k = C.base_ring()
|
||||
test = matrix([(a**k.cardinality()- a).vector() for a in C.basis()])
|
||||
basis = frob.left_kernel()
|
||||
basis = test.left_kernel()
|
||||
if len(basis) == 1:
|
||||
return C, lambda a: a, lambda a: a
|
||||
return [(C, C.basis())]
|
||||
one = C.one()
|
||||
e = basis[0]
|
||||
mat = matrix([one.vector(), e.vector()])
|
||||
mat = matrix([one.vector(), e])
|
||||
if mat.rank() == 1:
|
||||
e = basis[1]
|
||||
partial_split = splitting_from_idems(C,idems_from_element(e))
|
||||
partial_split = splitting_from_idems(C,idems_from_element(C(e)))
|
||||
splits_of_splits = [wedderburn_splitting_comm(S[0]) for S in partial_split]
|
||||
return sum([[(split[0],
|
||||
lambda a: split[1](S[1](a)),
|
||||
lambda a: S[1](split[1](a)))
|
||||
[S[2](b) for b in split[1]])
|
||||
for split in splits]
|
||||
for splits, S in zip(partial_split, splits_of_splits)], [])
|
||||
for S, splits in zip(partial_split, splits_of_splits)], [])
|
||||
|
||||
|
||||
def wedderburn_splitting_comm(C):
|
||||
|
@ -304,8 +304,8 @@ def wedderburn_splitting(A):
|
|||
"""
|
||||
C, to_C, from_C = center(A)
|
||||
split = wedderburn_splitting_comm(C)
|
||||
return [subalgebra_from_gens(A, [a * from_C(s[2](b))
|
||||
for a in A.basis() for b in s[0].basis()])
|
||||
return [subalgebra_from_gens(A, [a * from_C(b)
|
||||
for a in A.basis() for b in s[1]])
|
||||
for s in split]
|
||||
|
||||
|
||||
|
|
|
@ -1107,9 +1107,10 @@ class VectorBundle(SageObject):
|
|||
r"""
|
||||
Return an isomorphism from self to other if it exists and None otherwise.
|
||||
|
||||
May fail to find an isomorphism with probability less than proba.This
|
||||
only works if the constant base field is larger than
|
||||
``len(self.end().h0())``.
|
||||
May fail to find an isomorphism with probability less than
|
||||
`(\frac{s}{|k|})^\mathrm{tries}`, where k is the constant field and
|
||||
s is ``len(self.hom(other).h0())``. This is only usefule if `k` has
|
||||
cardinality larger than ``len(self.end().h0())``.
|
||||
"""
|
||||
Hom1 = self.hom(other)
|
||||
hom1 = Hom1.h0()
|
||||
|
@ -1285,30 +1286,59 @@ class VectorBundle(SageObject):
|
|||
isom = block_matrix([sum(phis, [])])
|
||||
return inds, ns, isom
|
||||
|
||||
def _isomorphism_to_small_field(self, other):
|
||||
r"""
|
||||
Return an isomorphism from self to other if it exists and None otherwise
|
||||
"""
|
||||
inds_self, ns_self, isom_self = self.split()
|
||||
inds_other, ns_other, isom_other = other.split()
|
||||
if sorted(ns_self) != sorted(ns_other):
|
||||
return None
|
||||
isoms = [[ind_self._isomorphism_indecomposable(ind_other)
|
||||
for ind_other in inds_other] for ind_self in inds_self]
|
||||
fits = [[i for i, iso in enumerate(isos) if iso is not None]
|
||||
for isos in isoms]
|
||||
if any([len(fit) != 1 for fit in fits]):
|
||||
return None
|
||||
#We now know that self and other are isomorphic
|
||||
fits = [fit[0] for fit in fits]
|
||||
ranks_self = [ind.rank() for ind in inds_self]
|
||||
ranks_other = [ind.rank() for ind in inds_other]
|
||||
s = len(inds_self)
|
||||
blocks = [block_diagonal_matrix([isoms[i][fits[i]]]*ns_self[i])
|
||||
for i in range(s)]
|
||||
isom = block_matrix([[blocks[i] if j == fits[i] else 0
|
||||
for j in range(s)]
|
||||
for i in range(s)])
|
||||
return isom_other * isom * isom_self**-1
|
||||
|
||||
def isomorphism_to(self, other):
|
||||
r"""
|
||||
Return an isomorphism from self to other if it exists and None otherwise
|
||||
|
||||
EXAMPLES ::
|
||||
|
||||
sage: from vector_bundle import trivial_bundle, canonical_bundle
|
||||
sage: F.<x> = FunctionField(GF(101))
|
||||
sage: from vector_bundle import (trivial_bundle, canonical_bundle,
|
||||
....: atiyah_bundle)
|
||||
sage: F.<x> = FunctionField(GF(3))
|
||||
sage: R.<y> = F[]
|
||||
sage: K.<y> = F.extension(y^2 - x^3 - x)
|
||||
sage: triv = trivial_bundle(K)
|
||||
sage: can = canonical_bundle(K)
|
||||
sage: iso = triv.isomorphism_to(can)
|
||||
sage: iso.ncols()
|
||||
1
|
||||
sage: iso.nrows()
|
||||
1
|
||||
sage: iso.is_zero()
|
||||
False
|
||||
sage: triv.hom(can).is_isomorphism(iso)
|
||||
True
|
||||
sage: V = can.direct_sum(atiyah_bundle(K, 2, 0, can))\
|
||||
....: .direct_sum(triv)
|
||||
sage: W = can.direct_sum(atiyah_bundle(K, 2, 0)).direct_sum(can)
|
||||
sage: iso = V.isomorphism_to(W)
|
||||
sage: V.hom(W).is_isomorphism(iso)
|
||||
True
|
||||
|
||||
WARNING:
|
||||
|
||||
Not well implemented for infinite fields: need to specify how to chose
|
||||
random elements and adequatly alter the number for tries.
|
||||
random elements and adequatly set the sample size.
|
||||
"""
|
||||
s = len(self.end().h0())
|
||||
k = self._function_field.constant_base_field()
|
||||
|
@ -1316,6 +1346,7 @@ class VectorBundle(SageObject):
|
|||
return self._isomorphism_to_large_field(
|
||||
other,
|
||||
integer_ceil(60/log(k.cardinality()/s)))
|
||||
return self._isomorphism_to_small_field(other)
|
||||
|
||||
def apply_isomorphism(self, isom):
|
||||
r"""
|
||||
|
|
Loading…
Reference in New Issue