Exemplo n.º 1
0
    def __classcall_private__(cls, R, s_coeff, names=None, index_set=None,
                              category=None, **kwds):
        """
        Normalize input to ensure a unique representation.

        EXAMPLES:

        If the variable order is specified, the order of structural
        coefficients does not matter::

            sage: from sage.algebras.lie_algebras.nilpotent_lie_algebra import NilpotentLieAlgebra_dense
            sage: L1.<x,y,z> = NilpotentLieAlgebra_dense(QQ, {('x','y'): {'z': 1}})
            sage: L2.<x,y,z> = NilpotentLieAlgebra_dense(QQ, {('y','x'): {'z': -1}})
            sage: L1 is L2
            True

        If the variables are implicitly defined by the structural coefficients,
        the ordering may be different and the Lie algebras will be considered
        different::

            sage: from sage.algebras.lie_algebras.nilpotent_lie_algebra import NilpotentLieAlgebra_dense
            sage: L1 = NilpotentLieAlgebra_dense(QQ, {('x','y'): {'z': 1}})
            sage: L2 = NilpotentLieAlgebra_dense(QQ, {('y','x'): {'z': -1}})
            sage: L1
            Nilpotent Lie algebra on 3 generators (x, y, z) over Rational Field
            sage: L2
            Nilpotent Lie algebra on 3 generators (y, x, z) over Rational Field
            sage: L1 is L2
            False

        Constructed using two different methods from :class:`LieAlgebra`
        yields the same Lie algebra::

            sage: sc = {('X','Y'): {'Z': 1}}
            sage: C = LieAlgebras(QQ).Nilpotent().FiniteDimensional().WithBasis()
            sage: L1.<X,Y,Z> = LieAlgebra(QQ, sc, category=C)
            sage: L2 = LieAlgebra(QQ, sc, nilpotent=True, names=['X','Y','Z'])
            sage: L1 is L2
            True
        """
        if not names:
            # extract names from structural coefficients
            names = []
            for (X, Y), d in s_coeff.items():
                if X not in names: names.append(X)
                if Y not in names: names.append(Y)
                for k in d:
                    if k not in names: names.append(k)

        from sage.structure.indexed_generators import standardize_names_index_set
        names, index_set = standardize_names_index_set(names, index_set)
        s_coeff = LieAlgebraWithStructureCoefficients._standardize_s_coeff(
            s_coeff, index_set)

        cat = LieAlgebras(R).FiniteDimensional().WithBasis().Nilpotent()
        category = cat.or_subcategory(category)

        return super(NilpotentLieAlgebra_dense, cls).__classcall__(
            cls, R, s_coeff, names, index_set, category=category, **kwds)
Exemplo n.º 2
0
    def __init__(self, R, names, index_set, category, **kwds):
        """
        Initialize ``self``.

        EXAMPLES::

            sage: L = LieAlgebra(QQ, 3, 'x', abelian=True)
            sage: TestSuite(L).run()
        """
        cat = LieAlgebras(R).FiniteDimensional().WithBasis().Nilpotent()
        category = cat.or_subcategory(category)
        LieAlgebraWithStructureCoefficients.__init__(self, R, Family({}), names,
                                                     index_set, category, **kwds)
Exemplo n.º 3
0
    def __init__(self, R, n):
        """
        Initialize ``self``.

        EXAMPLES::

            sage: g = lie_algebras.gl(QQ, 4)
            sage: TestSuite(g).run()

        TESTS:

        Check that :trac:`23266` is fixed::

            sage: gl2 = lie_algebras.gl(QQ, 2)
            sage: isinstance(gl2.basis().keys(), FiniteEnumeratedSet)
            True
            sage: Ugl2 = gl2.pbw_basis()
            sage: prod(Ugl2.gens())
            PBW['E_0_0']*PBW['E_0_1']*PBW['E_1_0']*PBW['E_1_1']
        """
        MS = MatrixSpace(R, n, sparse=True)
        one = R.one()
        names = []
        gens = []
        for i in range(n):
            for j in range(n):
                names.append('E_{0}_{1}'.format(i,j))
                mat = MS({(i,j):one})
                mat.set_immutable()
                gens.append(mat)
        self._n = n
        category = LieAlgebras(R).FiniteDimensional().WithBasis()
        from sage.sets.finite_enumerated_set import FiniteEnumeratedSet
        index_set = FiniteEnumeratedSet(names)
        LieAlgebraFromAssociative.__init__(self, MS, tuple(gens),
                                           names=tuple(names),
                                           index_set=index_set,
                                           category=category)
Exemplo n.º 4
0
        def is_ideal(self, A):
            """
            Return if ``self`` is an ideal of ``A``.

            EXAMPLES::

                sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example()
                sage: a, b, c = L.lie_algebra_generators()
                sage: I = L.ideal([2*a - c, b + c])
                sage: I.is_ideal(L)
                True

                sage: L.<x,y> = LieAlgebra(QQ, {('x','y'):{'x':1}})
                sage: L.is_ideal(L)
                True

                sage: F = LieAlgebra(QQ, 'F', representation='polynomial')
                sage: L.is_ideal(F)
                Traceback (most recent call last):
                ...
                NotImplementedError: A must be a finite dimensional Lie algebra
                 with basis
            """
            if A == self:
                return True
            if A not in LieAlgebras(
                    self.base_ring()).FiniteDimensional().WithBasis():
                raise NotImplementedError("A must be a finite dimensional"
                                          " Lie algebra with basis")
            B = self.basis()
            AB = A.basis()
            try:
                b_mat = matrix(
                    A.base_ring(),
                    [A.bracket(b, ab).to_vector() for b in B for ab in AB])
            except (ValueError, TypeError):
                return False
            return b_mat.row_space().is_submodule(self.module())
Exemplo n.º 5
0
    def __init__(self, R):
        r"""
        Initialize ``self``.

        EXAMPLES::

            sage: ACE = lie_algebras.AlternatingCentralExtensionOnsagerAlgebra(QQ)
            sage: TestSuite(ACE).run()

            sage: B = ACE.basis()
            sage: A1, A2, Am2 = B[0,1], B[0,2], B[0,-2]
            sage: B1, B2, Bm2 = B[1,1], B[1,2], B[1,-2]
            sage: TestSuite(ACE).run(elements=[A1,A2,Am2,B1,B2,Bm2,ACE.an_element()])
        """
        cat = LieAlgebras(R).WithBasis()
        from sage.rings.integer_ring import ZZ
        from sage.sets.disjoint_union_enumerated_sets import DisjointUnionEnumeratedSets
        I = DisjointUnionEnumeratedSets([ZZ, ZZ], keepkey=True, facade=True)
        IndexedGenerators.__init__(self, I)
        InfinitelyGeneratedLieAlgebra.__init__(self,
                                               R,
                                               index_set=I,
                                               category=cat)
Exemplo n.º 6
0
    def __init__(self, R, ct, e, f, h):
        """
        Initialize ``self``.

        EXAMPLES::

            sage: g = lie_algebras.sl(QQ, 3, representation='matrix')
            sage: TestSuite(g).run()

        TESTS:

        Check that :trac:`23266` is fixed::

            sage: sl2 = lie_algebras.sl(QQ, 2, 'matrix')
            sage: isinstance(sl2.indices(), FiniteEnumeratedSet)
            True
        """
        n = len(e)
        names = ['e%s'%i for i in range(1, n+1)]
        names += ['f%s'%i for i in range(1, n+1)]
        names += ['h%s'%i for i in range(1, n+1)]
        category = LieAlgebras(R).FiniteDimensional().WithBasis()
        from sage.sets.finite_enumerated_set import FiniteEnumeratedSet
        index_set = FiniteEnumeratedSet(names)
        LieAlgebraFromAssociative.__init__(self, e[0].parent(),
                                           gens=tuple(e + f + h),
                                           names=tuple(names),
                                           index_set=index_set,
                                           category=category)
        self._cartan_type = ct

        gens = tuple(self.gens())
        i_set = ct.index_set()
        self._e = Family(dict( (i, gens[c]) for c,i in enumerate(i_set) ))
        self._f = Family(dict( (i, gens[n+c]) for c,i in enumerate(i_set) ))
        self._h = Family(dict( (i, gens[2*n+c]) for c,i in enumerate(i_set) ))
Exemplo n.º 7
0
    def __init__(self, R, n):
        """
        Initialize ``self``.

        EXAMPLES::

            sage: L = lie_algebras.Heisenberg(QQ, 2, representation="matrix")
            sage: TestSuite(L).run()
        """
        HeisenbergAlgebra_fd.__init__(self, n)
        MS = MatrixSpace(R, n + 2, sparse=True)
        one = R.one()
        p = tuple(MS({(0, i): one}) for i in range(1, n + 1))
        q = tuple(MS({(i, n + 1): one}) for i in range(1, n + 1))
        z = (MS({(0, n + 1): one}), )
        names = tuple('p%s' % i for i in range(1, n + 1))
        names = names + tuple('q%s' % i for i in range(1, n + 1)) + ('z', )
        cat = LieAlgebras(R).Nilpotent().FiniteDimensional().WithBasis()
        LieAlgebraFromAssociative.__init__(self,
                                           MS,
                                           p + q + z,
                                           names=names,
                                           index_set=names,
                                           category=cat)
Exemplo n.º 8
0
    def __classcall_private__(cls,
                              R,
                              s_coeff,
                              names=None,
                              index_set=None,
                              category=None,
                              **kwds):
        """
        Normalize input to ensure a unique representation.

        EXAMPLES:

        If the variable order is specified, the order of structural
        coefficients does not matter::

            sage: from sage.algebras.lie_algebras.nilpotent_lie_algebra import NilpotentLieAlgebra_dense
            sage: L1.<x,y,z> = NilpotentLieAlgebra_dense(QQ, {('x','y'): {'z': 1}})
            sage: L2.<x,y,z> = NilpotentLieAlgebra_dense(QQ, {('y','x'): {'z': -1}})
            sage: L1 is L2
            True

        If the variables are implicitly defined by the structural coefficients,
        the ordering may be different and the Lie algebras will be considered
        different::

            sage: from sage.algebras.lie_algebras.nilpotent_lie_algebra import NilpotentLieAlgebra_dense
            sage: L1 = NilpotentLieAlgebra_dense(QQ, {('x','y'): {'z': 1}})
            sage: L2 = NilpotentLieAlgebra_dense(QQ, {('y','x'): {'z': -1}})
            sage: L1
            Nilpotent Lie algebra on 3 generators (x, y, z) over Rational Field
            sage: L2
            Nilpotent Lie algebra on 3 generators (y, x, z) over Rational Field
            sage: L1 is L2
            False

        Constructed using two different methods from :class:`LieAlgebra`
        yields the same Lie algebra::

            sage: sc = {('X','Y'): {'Z': 1}}
            sage: C = LieAlgebras(QQ).Nilpotent().FiniteDimensional().WithBasis()
            sage: L1.<X,Y,Z> = LieAlgebra(QQ, sc, category=C)
            sage: L2 = LieAlgebra(QQ, sc, nilpotent=True, names=['X','Y','Z'])
            sage: L1 is L2
            True
        """
        if not names:
            # extract names from structural coefficients
            names = []
            for (X, Y), d in s_coeff.items():
                if X not in names: names.append(X)
                if Y not in names: names.append(Y)
                for k in d:
                    if k not in names: names.append(k)

        from sage.structure.indexed_generators import standardize_names_index_set
        names, index_set = standardize_names_index_set(names, index_set)
        s_coeff = LieAlgebraWithStructureCoefficients._standardize_s_coeff(
            s_coeff, index_set)

        cat = LieAlgebras(R).FiniteDimensional().WithBasis().Nilpotent()
        category = cat.or_subcategory(category)

        return super(NilpotentLieAlgebra_dense,
                     cls).__classcall__(cls,
                                        R,
                                        s_coeff,
                                        names,
                                        index_set,
                                        category=category,
                                        **kwds)
Exemplo n.º 9
0
    def __init__(self, R, cartan_type):
        r"""
        Initialize ``self``.

        TESTS::

            sage: L = LieAlgebra(QQ, cartan_type=['A',2])
            sage: TestSuite(L).run()  # long time
        """
        self._cartan_type = cartan_type
        RL = cartan_type.root_system().root_lattice()
        alpha = RL.simple_roots()
        p_roots = list(RL.positive_roots_by_height())
        n_roots = [-x for x in p_roots]
        self._p_roots_index = {al: i for i,al in enumerate(p_roots)}
        alphacheck = RL.simple_coroots()
        roots = frozenset(RL.roots())
        num_sroots = len(alpha)
        one = R.one()

        # Determine the signs for the structure coefficients from the root system
        # We first create the special roots
        sp_sign = {}
        for i,a in enumerate(p_roots):
            for b in p_roots[i+1:]:
                if a + b not in p_roots:
                    continue

                # Compute the sign for the extra special pair
                x, y = (a + b).extraspecial_pair()

                if (x, y) == (a, b): # If it already is an extra special pair
                    if (x, y) not in sp_sign:
                        # This swap is so the structure coefficients match with GAP
                        if (sum(x.coefficients()) == sum(y.coefficients())
                            and str(x) > str(y)):
                            y,x = x,y
                        sp_sign[(x, y)] = -one
                        sp_sign[(y, x)] = one
                    continue

                if b - x in roots:
                    t1 = ((b-x).norm_squared() / b.norm_squared()
                          * sp_sign[(x, b-x)] * sp_sign[(a, y-a)])
                else:
                    t1 = 0
                if a - x in roots:
                    t2 = ((a-x).norm_squared() / a.norm_squared()
                          * sp_sign[(x, a-x)] * sp_sign[(b, y-b)])
                else:
                    t2 = 0

                if t1 - t2 > 0:
                    sp_sign[(a,b)] = -one
                elif t2 - t1 > 0:
                    sp_sign[(a,b)] = one
                sp_sign[(b,a)] = -sp_sign[(a,b)]

        # Function to construct the structure coefficients (up to sign)
        def e_coeff(r, s):
            p = 1
            while r - p*s in roots:
                p += 1
            return p

        # Now we can compute all necessary structure coefficients
        s_coeffs = {}
        for i,r in enumerate(p_roots):
            # [e_r, h_i] and [h_i, f_r]
            for ac in alphacheck:
                c = r.scalar(ac)
                if c == 0:
                    continue
                s_coeffs[(r, ac)] = {r: -c}
                s_coeffs[(ac, -r)] = {-r: -c}

            # [e_r, f_r]
            s_coeffs[(r, -r)] = {alphacheck[j]: c
                                 for j, c in r.associated_coroot()}

            # [e_r, e_s] and [e_r, f_s] with r != +/-s
            # We assume s is positive, as otherwise we negate
            #   both r and s and the resulting coefficient
            for j, s in enumerate(p_roots[i+1:]):
                j += i+1 # Offset
                # Since h(s) >= h(r), we have s - r > 0 when s - r is a root
                # [f_r, e_s]
                if s - r in p_roots:
                    c = e_coeff(r, -s)
                    a, b = s-r, r
                    if self._p_roots_index[a] > self._p_roots_index[b]: # Note a != b
                        c *= -sp_sign[(b, a)]
                    else:
                        c *= sp_sign[(a, b)]
                    s_coeffs[(-r, s)] = {a: -c}
                    s_coeffs[(r, -s)] = {-a: c}

                # [e_r, e_s]
                a = r + s
                if a in p_roots:
                    # (r, s) is a special pair
                    c = e_coeff(r, s) * sp_sign[(r, s)]
                    s_coeffs[(r, s)] = {a: c}
                    s_coeffs[(-r, -s)] = {-a: -c}

        # Lastly, make sure a < b for all (a, b) in the coefficients and flip if necessary
        for k in s_coeffs.keys():
            a,b = k[0], k[1]
            if self._basis_key(a) > self._basis_key(b):
                s_coeffs[(b,a)] = [(index, -v) for index,v in s_coeffs[k].items()]
                del s_coeffs[k]
            else:
                s_coeffs[k] = s_coeffs[k].items()

        names = ['e{}'.format(i) for i in range(1, num_sroots+1)]
        names += ['f{}'.format(i) for i in range(1, num_sroots+1)]
        names += ['h{}'.format(i) for i in range(1, num_sroots+1)]
        category = LieAlgebras(R).FiniteDimensional().WithBasis()
        index_set = p_roots + list(alphacheck) + n_roots
        names = tuple(names)
        from sage.sets.finite_enumerated_set import FiniteEnumeratedSet
        index_set = FiniteEnumeratedSet(index_set)
        LieAlgebraWithStructureCoefficients.__init__(self, R, s_coeffs, names, index_set,
                                                     category, prefix='E', bracket='[',
                                                     sorting_key=self._basis_key)
Exemplo n.º 10
0
    def __classcall_private__(cls,
                              I,
                              ambient=None,
                              names=None,
                              index_set=None,
                              category=None):
        r"""
        Normalize input to ensure a unique representation.

        EXAMPLES:

        Specifying the ambient Lie algebra is not necessary::

            sage: from sage.algebras.lie_algebras.quotient import LieQuotient_finite_dimensional_with_basis
            sage: L.<X,Y> = LieAlgebra(QQ, {('X','Y'): {'X': 1}})
            sage: Q1 = LieQuotient_finite_dimensional_with_basis(X, ambient=L)
            sage: Q2 = LieQuotient_finite_dimensional_with_basis(X)
            sage: Q1 is Q2
            True

        Variable names are extracted from the ambient Lie algebra by default::

            sage: Q3 = L.quotient(X, names=['Y'])
            sage: Q1 is Q3
            True
        """
        if not isinstance(I, LieSubalgebra_finite_dimensional_with_basis):
            # assume I is an element or list of elements of some lie algebra
            if ambient is None:
                if not isinstance(I, (list, tuple)):
                    ambient = I.parent()
                else:
                    ambient = I[0].parent()
            I = ambient.ideal(I)
        if ambient is None:
            ambient = I.ambient()

        if not ambient.base_ring().is_field():
            raise NotImplementedError("quotients over non-fields "
                                      "not implemented")

        # extract an index set from a complementary basis to the ideal
        I_supp = [X.leading_support() for X in I.leading_monomials()]
        inv = ambient.basis().inverse_family()
        sorted_indices = [inv[X] for X in ambient.basis()]
        index_set = [i for i in sorted_indices if i not in I_supp]

        if names is None:
            amb_names = dict(zip(sorted_indices, ambient.variable_names()))
            names = [amb_names[i] for i in index_set]
        elif isinstance(names, str):
            if len(index_set) == 1:
                names = [names]
            else:
                names = [
                    '%s_%d' % (names, k + 1) for k in range(len(index_set))
                ]
        names, index_set = standardize_names_index_set(names, index_set)

        cat = LieAlgebras(ambient.base_ring()).FiniteDimensional().WithBasis()
        if ambient in LieAlgebras(ambient.base_ring()).Nilpotent():
            cat = cat.Nilpotent()
        category = cat.Subquotients().or_subcategory(category)

        sup = super(LieQuotient_finite_dimensional_with_basis, cls)
        return sup.__classcall__(cls,
                                 I,
                                 ambient,
                                 names,
                                 index_set,
                                 category=category)
Exemplo n.º 11
0
    def __init__(self,
                 R,
                 s_coeff,
                 names,
                 index_set,
                 category=None,
                 prefix=None,
                 bracket=None,
                 latex_bracket=None,
                 string_quotes=None,
                 **kwds):
        """
        Initialize ``self``.

        EXAMPLES::

            sage: L = LieAlgebra(QQ, 'x,y', {('x','y'): {'x':1}})
            sage: TestSuite(L).run()
        """
        default = (names != tuple(index_set))
        if prefix is None:
            if default:
                prefix = 'L'
            else:
                prefix = ''
        if bracket is None:
            bracket = default
        if latex_bracket is None:
            latex_bracket = default
        if string_quotes is None:
            string_quotes = default

        #self._pos_to_index = dict(enumerate(index_set))
        self._index_to_pos = {k: i for i, k in enumerate(index_set)}
        if "sorting_key" not in kwds:
            kwds["sorting_key"] = self._index_to_pos.__getitem__

        cat = LieAlgebras(R).WithBasis().FiniteDimensional().or_subcategory(
            category)
        FinitelyGeneratedLieAlgebra.__init__(self, R, names, index_set, cat)
        IndexedGenerators.__init__(self,
                                   self._indices,
                                   prefix=prefix,
                                   bracket=bracket,
                                   latex_bracket=latex_bracket,
                                   string_quotes=string_quotes,
                                   **kwds)

        self._M = FreeModule(R, len(index_set))

        # Transform the values in the structure coefficients to elements
        def to_vector(tuples):
            vec = [R.zero()] * len(index_set)
            for k, c in tuples:
                vec[self._index_to_pos[k]] = c
            vec = self._M(vec)
            vec.set_immutable()
            return vec

        self._s_coeff = {(self._index_to_pos[k[0]], self._index_to_pos[k[1]]):
                         to_vector(s_coeff[k])
                         for k in s_coeff.keys()}
Exemplo n.º 12
0
def in_new_basis(L, basis, names, check=True, category=None):
    r"""
    Return an isomorphic copy of the Lie algebra in a different basis.

    INPUT:

    - ``L`` -- the Lie algebra
    - ``basis`` -- a list of elements of the Lie algebra
    - ``names`` -- a list of strings to use as names for the new basis
    - ``check`` -- (default:``True``) a boolean; if ``True``, verify
      that the list ``basis`` is indeed a basis of the Lie algebra
    - ``category`` -- (default:``None``) a subcategory of
      :class:`FiniteDimensionalLieAlgebrasWithBasis` to apply to the
      new Lie algebra.

    EXAMPLES:

    The method may be used to relabel the elements::

        sage: import sys, pathlib
        sage: sys.path.append(str(pathlib.Path().absolute()))
        sage: from lie_gradings.gradings.utilities import in_new_basis
        sage: L.<X,Y> = LieAlgebra(QQ, {('X','Y'): {'Y': 1}})
        sage: K.<A,B> = in_new_basis(L, [X, Y])
        sage: K[A,B]
        B

    The new Lie algebra inherits nilpotency::

        sage: L = lie_algebras.Heisenberg(QQ, 1)
        sage: X,Y,Z = L.basis()
        sage: L.category()
        Category of finite dimensional nilpotent lie algebras with basis over Rational Field
        sage: K.<A,B,C> = in_new_basis(L, [X + Y, Y - X, Z])
        sage: K[A,B]
        2*C
        sage: K[[A,B],A]
        0
        sage: K.is_nilpotent()
        True
        sage: K.category()
        Category of finite dimensional nilpotent lie algebras with basis over Rational Field

    Some properties such as being stratified may in general be lost when
    changing the basis, and are therefore not preserved::

        sage: L.<X,Y,Z> = LieAlgebra(QQ, 2, step=2)
        sage: L.category()
        Category of finite dimensional stratified lie algebras with basis over Rational Field
        sage: K.<A,B,C> = in_new_basis(L, [Z, X, Y])
        sage: K.category()
        Category of finite dimensional nilpotent lie algebras with basis over Rational Field

    If the property is known to be preserved, an extra category may
    be passed to the method::

        sage: C = L.category()
        sage: K.<A,B,C> = in_new_basis(L, [Z, X, Y], category=C)
        sage: K.category()
        Category of finite dimensional stratified lie algebras with basis over Rational Field
    """
    try:
        m = L.module()
    except AttributeError:
        m = FreeModule(L.base_ring(), L.dimension())
    sm = m.submodule_with_basis([X.to_vector() for X in basis])

    if check:
        # check that new basis is a basis
        A = matrix([X.to_vector() for X in basis])
        if not A.is_invertible():
            raise ValueError("%s is not a basis of the Lie algebra" % basis)

    # form dictionary of structure coefficients in the new basis
    sc = {}
    for (X, nX), (Y, nY) in combinations(zip(basis, names), 2):
        Z = X.bracket(Y)
        zvec = sm.coordinate_vector(Z.to_vector())
        sc[(nX, nY)] = {nW: c for nW, c in zip(names, zvec)}

    C = LieAlgebras(L.base_ring()).FiniteDimensional().WithBasis()
    C = C.or_subcategory(category)
    if L.is_nilpotent():
        C = C.Nilpotent()

    return LieAlgebra(L.base_ring(), sc, names=names, category=C)