def __classcall_private__(cls, R, classification, s_coeff, names, index_set=None, category=None, **kwds): r""" Normalize input to ensure a unique representation. """ 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(ClassifiedNilpotentLieAlgebra, cls).__classcall__(cls, R, classification, s_coeff, names, index_set, category=category, **kwds)
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)
def __init__(self, I, L, names, index_set, category=None): r""" Initialize ``self``. TESTS:: sage: L.<x,y,z> = LieAlgebra(SR, {('x','y'): {'x':1}}) sage: K = L.quotient(y) sage: K.dimension() 1 sage: TestSuite(K).run() """ B = L.basis() sm = L.module().submodule_with_basis( [I.reduce(B[i]).to_vector() for i in index_set]) SB = sm.basis() # compute and normalize structural coefficients for the quotient s_coeff = {} for i, ind_i in enumerate(index_set): for j in range(i + 1, len(index_set)): ind_j = index_set[j] brkt = I.reduce(L.bracket(SB[i], SB[j])) brktvec = sm.coordinate_vector(brkt.to_vector()) s_coeff[(ind_i, ind_j)] = dict(zip(index_set, brktvec)) s_coeff = LieAlgebraWithStructureCoefficients._standardize_s_coeff( s_coeff, index_set) self._ambient = L self._I = I self._sm = sm LieAlgebraWithStructureCoefficients.__init__(self, L.base_ring(), s_coeff, names, index_set, category=category) # register the quotient morphism as a conversion H = Hom(L, self) f = SetMorphism(H, self.retract) self.register_conversion(f)
def __init__(self, I, L, names, index_set, category=None): r""" Initialize ``self``. TESTS:: sage: L.<x,y,z> = LieAlgebra(SR, {('x','y'): {'x':1}}) sage: K = L.quotient(y) sage: K.dimension() 1 sage: TestSuite(K).run() """ B = L.basis() sm = L.module().submodule_with_basis([I.reduce(B[i]).to_vector() for i in index_set]) SB = sm.basis() # compute and normalize structural coefficients for the quotient s_coeff = {} for i, ind_i in enumerate(index_set): for j in range(i + 1, len(index_set)): ind_j = index_set[j] brkt = I.reduce(L.bracket(SB[i], SB[j])) brktvec = sm.coordinate_vector(brkt.to_vector()) s_coeff[(ind_i, ind_j)] = dict(zip(index_set, brktvec)) s_coeff = LieAlgebraWithStructureCoefficients._standardize_s_coeff( s_coeff, index_set) self._ambient = L self._I = I self._sm = sm LieAlgebraWithStructureCoefficients.__init__( self, L.base_ring(), s_coeff, names, index_set, category=category) # register the quotient morphism as a conversion H = Hom(L, self) f = SetMorphism(H, self.retract) self.register_conversion(f)
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)
def __init__(self, R, r, s, names, naming, category, **kwds): r""" Initialize ``self`` EXAMPLES:: sage: L = LieAlgebra(ZZ, 2, step=2) sage: TestSuite(L).run() sage: L = LieAlgebra(QQ, 4, step=3) sage: TestSuite(L).run() # long time """ if r not in ZZ or r <= 0: raise ValueError("number of generators %s is not " "a positive integer" % r) if s not in ZZ or s <= 0: raise ValueError("step %s is not a positive integer" % s) # extract an index set from the Lyndon words of the corresponding # free Lie algebra, and store the corresponding elements in a dict from sage.algebras.lie_algebras.lie_algebra import LieAlgebra free_gen_names = ['F%d' % k for k in range(r)] free_gen_names_inv = { val: i + 1 for i, val in enumerate(free_gen_names) } L = LieAlgebra(R, free_gen_names).Lyndon() basis_by_deg = {d: [] for d in range(1, s + 1)} for d in range(1, s + 1): for X in L.graded_basis(d): # convert brackets of form [X_1, [X_1, X_2]] to words (1,1,2) w = tuple(free_gen_names_inv[s] for s in X.leading_support().to_word()) basis_by_deg[d].append((w, X)) index_set = [ind for d in basis_by_deg for ind, val in basis_by_deg[d]] if len(names) == 1 and len(index_set) > 1: if not naming: if r >= 10: naming = 'linear' else: naming = 'index' if naming == 'linear': names = [ '%s_%d' % (names[0], k + 1) for k in range(len(index_set)) ] elif naming == 'index': if r >= 10: raise ValueError("'index' naming scheme not supported for " "10 or more generators") names = [ '%s_%s' % (names[0], "".join(str(s) for s in ind)) for ind in index_set ] else: raise ValueError("unknown naming scheme %s" % naming) # extract structural coefficients from the free Lie algebra s_coeff = {} for dx in range(1, s + 1): # Brackets are only computed when deg(X) + deg(Y) <= s # We also require deg(Y) >= deg(X) by the ordering for dy in range(dx, s + 1 - dx): if dx == dy: for i, val in enumerate(basis_by_deg[dx]): X_ind, X = val for Y_ind, Y in basis_by_deg[dy][i + 1:]: Z = L[X, Y] if not Z.is_zero(): s_coeff[(X_ind, Y_ind)] = { W_ind: Z[W.leading_support()] for W_ind, W in basis_by_deg[dx + dy] } else: for X_ind, X in basis_by_deg[dx]: for Y_ind, Y in basis_by_deg[dy]: Z = L[X, Y] if not Z.is_zero(): s_coeff[(X_ind, Y_ind)] = { W_ind: Z[W.leading_support()] for W_ind, W in basis_by_deg[dx + dy] } names, index_set = standardize_names_index_set(names, index_set) s_coeff = LieAlgebraWithStructureCoefficients._standardize_s_coeff( s_coeff, index_set) NilpotentLieAlgebra_dense.__init__(self, R, s_coeff, names, index_set, s, category=category, **kwds)
def __init__(self, R, r, s, names, naming, category, **kwds): r""" Initialize ``self`` EXAMPLES:: sage: L = LieAlgebra(ZZ, 2, step=2) sage: TestSuite(L).run() sage: L = LieAlgebra(QQ, 4, step=3) sage: TestSuite(L).run() # long time """ if r not in ZZ or r <= 0: raise ValueError("number of generators %s is not " "a positive integer" % r) if s not in ZZ or s <= 0: raise ValueError("step %s is not a positive integer" % s) # extract an index set from the Lyndon words of the corresponding # free Lie algebra, and store the corresponding elements in a dict from sage.algebras.lie_algebras.lie_algebra import LieAlgebra free_gen_names = ['F%d' % k for k in range(r)] free_gen_names_inv = {val: i + 1 for i, val in enumerate(free_gen_names)} L = LieAlgebra(R, free_gen_names).Lyndon() basis_by_deg = {d: [] for d in range(1, s + 1)} for d in range(1, s + 1): for X in L.graded_basis(d): # convert brackets of form [X_1, [X_1, X_2]] to words (1,1,2) w = tuple(free_gen_names_inv[s] for s in X.leading_support().to_word()) basis_by_deg[d].append((w, X)) index_set = [ind for d in basis_by_deg for ind, val in basis_by_deg[d]] if len(names) == 1 and len(index_set) > 1: if not naming: if r >= 10: naming = 'linear' else: naming = 'index' if naming == 'linear': names = ['%s_%d' % (names[0], k + 1) for k in range(len(index_set))] elif naming == 'index': if r >= 10: raise ValueError("'index' naming scheme not supported for " "10 or more generators") names = ['%s_%s' % (names[0], "".join(str(s) for s in w)) for w in index_set] else: raise ValueError("unknown naming scheme %s" % naming) # extract structural coefficients from the free Lie algebra s_coeff = {} for dx in range(1, s + 1): # Brackets are only computed when deg(X) + deg(Y) <= s # We also require deg(Y) >= deg(X) by the ordering for dy in range(dx, s + 1 - dx): if dx == dy: for i, val in enumerate(basis_by_deg[dx]): X_ind, X = val for Y_ind, Y in basis_by_deg[dy][i + 1:]: Z = L[X, Y] if not Z.is_zero(): s_coeff[(X_ind, Y_ind)] = {W_ind: Z[W.leading_support()] for W_ind, W in basis_by_deg[dx + dy]} else: for X_ind, X in basis_by_deg[dx]: for Y_ind, Y in basis_by_deg[dy]: Z = L[X, Y] if not Z.is_zero(): s_coeff[(X_ind, Y_ind)] = {W_ind: Z[W.leading_support()] for W_ind, W in basis_by_deg[dx + dy]} names, index_set = standardize_names_index_set(names, index_set) s_coeff = LieAlgebraWithStructureCoefficients._standardize_s_coeff( s_coeff, index_set) NilpotentLieAlgebra_dense.__init__(self, R, s_coeff, names, index_set, s, category=category, **kwds)