# Re: [sage-devel] Re: BUGS in tensor products of algebras

Hi!

Dne pátek 23. února 2018 0:15:59 UTC+1 Travis Scrimshaw napsal(a):
>
> Hey Vit,
>
>    Some of these issues are probably related to bad input. Let us start
>>> with *.algebras_generators(). It is useful to look at the output:
>>>
>>> sage: PBW.algebra_generators()
>>> Finite family {-alpha[1]: PBW[-alpha[1]], alpha[1]: PBW[alpha[1]],
>>> alphacheck[1]: PBW[alphacheck[1]]}
>>>
>>> So it is expecting a simple root as input. Similarly, for your tensor
>>> product:
>>>
>>
>>
>>>
>>> sage: UC = PBW.tensor(C)
>>> Lazy family (Term map from Image of Cartesian product of Free abelian
>>> monoid indexed by {alpha[1], alphacheck[1], -alpha[1]}, Subsets of {0, 1
>>> } by <type 'tuple'> to Universal enveloping algebra of Lie algebra of [
>>> 'A', 1] in the Chevalley basis in the Poincare-Birkhoff-Witt basis #
>>> The Clifford algebra of the Quadratic form in 2 variables over Rational
>>> Field with coefficients:
>>> [ 1 0 ]
>>> [ * 1 ](i))_{i in Image of Cartesian product of Free abelian monoid
>>> indexed by {alpha[1], alphacheck[1], -alpha[1]}, Subsets of {0, 1} by <type
>>> 'tuple'>}
>>>
>>> The tensor product as QQ-modules knows that it is a QQ-algebra, but it
>>> plays it safe and uses its basis as the generating set, which in turn, is a
>>> Cartesian product of the bases of its factors. Subsequently, the keys for
>>> the basis is the Cartesian product of the keys of the factors. So in this
>>> case, the (1,1) corresponds to the keys for the Clifford algebra basis
>>> (more of a by-product of the implementation, but the subsets are natural):
>>>
>>>
>> That sounds fine. But for a newcomer it's really hard to figure out what
>> should he input. I am still not sure myself. Consider this:
>>
>> alpha = PBW.algebra_generators().keys()
>> PBW.basis()[alpha[0]] == PBW.algebra_generators()[alpha[0]]
>>
>>
>>
>> I think this is a bug.
>>
>
> No, it is not. The keys for the basis of the PBW are different than those
> for the algebra generators. See the output:
>
> sage: PBW.basis()
> Lazy family (Term map from Free abelian monoid indexed by {alpha[1],
> alphacheck[1], -alpha[1]} to Universal enveloping algebra of Lie algebra
> of ['A', 1] in the Chevalley basis in the Poincare-Birkhoff-Witt basis(i))
> _{i in Free abelian monoid indexed by {alpha[1], alphacheck[1], -alpha[1
> ]}}
> sage: PBW.algebra_generators()
> Finite family {-alpha[1]: PBW[-alpha[1]], alpha[1]: PBW[alpha[1]],
> alphacheck[1]: PBW[alphacheck[1]]}
>
> It clearly indicates that the basis keys should be an element of a free
> abelian monoid. LBYL. Now in this case, if we did try to convert the input
> into the keys, it should work. See https://trac.sagemath.org/ticket/18750.
> Actually, it is not as bad as I remembered in terms of outright timings,
> but there are some other technical issues.
>
>
Oh. Sorry. I admit that I have trouble parsing the Lazy family description.
Free abelian monoid... Hmmm... What free abelian monoid?

sage: PBW.basis().keys().an_element()

PBW[alpha[1]]^2*PBW[alphacheck[1]]^2*PBW[-alpha[1]]^3

So PBW.basis() is _indexed_ by elements of the basis of PBW? I am sorry for
all these stupid questions but (as you can clearly see) I am confused as
hell. I looked at the ticket and I have no idea what it is about.

>
>>
>>
>>> sage: C.basis()
>>> Lazy family (Term map from Subsets of {0, 1} to The Clifford algebra of
>>> the Quadratic form in 2 variables over Rational Field with coefficients:
>>> [ 1 0 ]
>>> [ * 1 ](i))_{i in Subsets of {0, 1}}
>>>
>>> So it is expecting subsets and that the user will not input bad data.
>>> There is no reason for it to simplify and not a bug. Granted, we could put
>>> a check on the user input here, but there is a speed penalty as this can be
>>> a well-used code path internally. Moreover, ducktyping can also be useful.
>>> So we are fairly permissive here, but not without due cause IMO.
>>>
>>>
>> Pardon my ignorance, but If there is no simplification then what is all
>> this good for? It does simplify for universal enveloping algebra and so it
>> should do it for Clifford algebras as well. Also I have a big issue with
>> naming convention here. The method basis() does not produce a basis!
>>
>
> it is *bad input*. It does produce a basis, one indexed by *subsets*, not
> words/multisets. In math terms, if you have a sequence (x_i)_{i \in I},
> then want x_j, where j \notin I, then you have an error. With #18750, this
> input might instead raise an error. If you want to do that, then you can do
> this:
>
> sage: Q = QuadraticForm(QQ, 2, [1,0,1])
> sage: C = CliffordAlgebra(Q)
> sage: g = list(C.algebra_generators()); g
> [e0, e1]
> sage: prod(g[i] for i in [0,0,1,0,1,1,0,0])
> -e0*e1
>
> If you took your input and wrapped it with set:
>
> sage: set((1,1,0,1))
> {0, 1}
>
> which would be the other possible outcome with #18750.
>

But sets are unhashable so how do I actually input the correct keys to cb =
C.basis()? Another way to solve my original problem (which is to construct
certain element of U \otimes C) would be to take tensor product of elements
of U and C. Something like UC.tensor_elements(E*F+F*E, e*f - f*e).

>
>
>>  I understand that it might be convenient for implementation details to
>> use tuples of numbers (not subsets!!!) to index elements, but why can I
>> index with E, F and H in the universal enveloping algebra case and not with
>> e and f in the Clifford algebra case?
>>
>> It seems that accessing Clifford algebra elements through basis just
>> messes up with the simplification.
>>
>> x = cb[(1,1,0,1)]
>> print(simplify(x))
>> print(type(x))
>> print(f*f*e*f)
>> print(type(f*f*e*f))
>> print(f*f*e*f == x)
>>
>>
>> Do not confuse a bug with a not-yet-implemented feature: (noncommutative)
>>> polynomial rings are not in AlgebrasWithBasis, so it is not expected that
>>> they work with something like tensor(). However, it would be a good feature
>>> to add. :)
>>>
>>
>> I guess are referring to my complaints about not being able to take
>> tensor product with noncommutative ring. I see the naming convention as a
>> BUG. If the method has "algebra" in it's name, it should produce algebra
>> and not a ring. If a method has "basis" in its name, it should produce
>> basis not a generating set as C.basis() does or a basis and not an algebra
>> as pbw_basis() does.
>>
>
> Remember that we are bound by the facilities of computer science and
> programming within Sage as well, which are usually much stronger
> constraints than mathematics (e.g., consider the set of real numbers). For
> the current implementation of tensor products, we require the algebra to be
> in AlgebrasWithBasis. I would not say limitations of the current framework
> to be a bug. Also, NC poly rings are in the category of algebras, so it
> does produce an algebra.
>
>
I understand. I just object to naming conventions. I mean the object that
results from calling universal_algebra() presents itself as a ring. How can
I know that it is actually also in category of algebras without digging
through the code?

> C.basis() does produce a basis.
>
> sage: list(C.basis())
> [1, e0, e1, e0*e1]
>
> Now pbw_basis() does return an algebra in a particular basis, so in some
> ways, it is returning a basis, just not for the Lie algebra. So now I see
> why you feel it is not completely natural. However, do you have a proposal
> for how to have convenient access to the PBW basis of U(*g*)? IMO, it
> cannot be connected with universal_enveloping_algebra() because that only
> has to return a class modeling the UEA, which should not be required to
> have a PBW basis method. Also, I feel that a PBW basis is really more
> closely connected to the Lie algebra and it is clear to someone working in
> this field what pbw_basis would return.
>

But that nonocmmutative ring that one gets from
universal_enveloping_algebra() also has some implicit basis. What is this
ring actually good for? I would think that most people would want to work
with some PBW basis anyway. My objection is not only that pbw_basis()
doesn't return a basis of L, but also that it returns algebra (with a
preffered chosen basis). I propose to get rid of pbw_basis method and
introduce optional argument pbw_basis_ordering to
universal_enveloping_algebra method. Something like this:

def universal_enveloping_algebra(self, pbw_basis_ordering=None):
"""
Examples of pbw_basis_ordering:
"""
if pbw_basis_ordering is None:
return self._universal_enveloping_algebra() # return the
noncommutative ring
else:
return self._pbw_basis(pbw_basis_ordering) # return the UAE with
PBW basis given by the ordering

>
>>
>>>
>>> if you want to access the basis, use the .basis() method.
>>>
>>> Also, how is pbw_basis not an intuitive name for obtaining the PBW basis
>>> (there is also the fully spelled out version too)? If you want to change
>>> the ordering, RTM of "PBW?" to pass in an ordering function to
>>> L.pbw_basis().
>>>
>>>
>> For naming conventions see above. I checked out helpstring for PBW and I
>> am still not sure how to produce e.g. E, F, H ordering. I suggest to move
>> this helpstring to L.pbw_basis().
>>
>
> -1 It is connected with the construction of the PBW class and not handled
> in the pbw_basis() method. However, I do agree that it would be good to
> have an (different) example in the pbw_basis() and a reference to the PBW
> class in the docstring.
>

If you don't like my proposal above then I have no objections here.

>
>> Now the fact that you sometimes obtaining random attribute errors when
>>> running that code block is a definite bug. Please submit a trac ticket.
>>>
>>>
>> Submitted as https://trac.sagemath.org/ticket/24822
>>
>
> Great, thank you.
>
>
>> In general, I think it is difficult to determine the tensor product of
>>> two (non commutative, non PBW) algebras over an arbitrary subalgebra. There
>>> is some code for doing smash products somewhere on #15874, but it has
>>> bitrotted and IDK if that will give you what you want. I did write some
>>> code to compute Verma modules via the PBW basis. I had to work somewhat
>>> hard to make it work, and it wasn't apparent to me how to extend that to
>>> more general framework.
>>>
>>>
>> Verma modules (for finite-dimensional semisimple Lie algebras) were
>> exactly what I had in mind. Are they already in Sage somewhere? I haven't
>> seen them.
>>
>
> See https://trac.sagemath.org/ticket/23517. I try to track the overall
> progress of Lie algebras in Sage in essentially metaticket
> https://trac.sagemath.org/ticket/14901.
>

Awesome!

>
> Best,
> Travis
>
>
Best,
Vit

On 23 February 2018 at 00:15, Travis Scrimshaw <tsc...@ucdavis.edu> wrote:

> Hey Vit,
>
>    Some of these issues are probably related to bad input. Let us start
>>> with *.algebras_generators(). It is useful to look at the output:
>>>
>>> sage: PBW.algebra_generators()
>>> Finite family {-alpha[1]: PBW[-alpha[1]], alpha[1]: PBW[alpha[1]],
>>> alphacheck[1]: PBW[alphacheck[1]]}
>>>
>>> So it is expecting a simple root as input. Similarly, for your tensor
>>> product:
>>>
>>
>>
>>>
>>> sage: UC = PBW.tensor(C)
>>> Lazy family (Term map from Image of Cartesian product of Free abelian
>>> monoid indexed by {alpha[1], alphacheck[1], -alpha[1]}, Subsets of {0, 1
>>> } by <type 'tuple'> to Universal enveloping algebra of Lie algebra of [
>>> 'A', 1] in the Chevalley basis in the Poincare-Birkhoff-Witt basis #
>>> The Clifford algebra of the Quadratic form in 2 variables over Rational
>>> Field with coefficients:
>>> [ 1 0 ]
>>> [ * 1 ](i))_{i in Image of Cartesian product of Free abelian monoid
>>> indexed by {alpha[1], alphacheck[1], -alpha[1]}, Subsets of {0, 1} by <type
>>> 'tuple'>}
>>>
>>> The tensor product as QQ-modules knows that it is a QQ-algebra, but it
>>> plays it safe and uses its basis as the generating set, which in turn, is a
>>> Cartesian product of the bases of its factors. Subsequently, the keys for
>>> the basis is the Cartesian product of the keys of the factors. So in this
>>> case, the (1,1) corresponds to the keys for the Clifford algebra basis
>>> (more of a by-product of the implementation, but the subsets are natural):
>>>
>>>
>> That sounds fine. But for a newcomer it's really hard to figure out what
>> should he input. I am still not sure myself. Consider this:
>>
>> alpha = PBW.algebra_generators().keys()
>> PBW.basis()[alpha[0]] == PBW.algebra_generators()[alpha[0]]
>>
>>
>>
>> I think this is a bug.
>>
>
> No, it is not. The keys for the basis of the PBW are different than those
> for the algebra generators. See the output:
>
> sage: PBW.basis()
> Lazy family (Term map from Free abelian monoid indexed by {alpha[1],
> alphacheck[1], -alpha[1]} to Universal enveloping algebra of Lie algebra
> of ['A', 1] in the Chevalley basis in the Poincare-Birkhoff-Witt basis(i))
> _{i in Free abelian monoid indexed by {alpha[1], alphacheck[1], -alpha[1
> ]}}
> sage: PBW.algebra_generators()
> Finite family {-alpha[1]: PBW[-alpha[1]], alpha[1]: PBW[alpha[1]],
> alphacheck[1]: PBW[alphacheck[1]]}
>
> It clearly indicates that the basis keys should be an element of a free
> abelian monoid. LBYL. Now in this case, if we did try to convert the input
> into the keys, it should work. See https://trac.sagemath.org/ticket/18750.
> Actually, it is not as bad as I remembered in terms of outright timings,
> but there are some other technical issues.
>
>
>>
>>
>>> sage: C.basis()
>>> Lazy family (Term map from Subsets of {0, 1} to The Clifford algebra of
>>> the Quadratic form in 2 variables over Rational Field with coefficients:
>>> [ 1 0 ]
>>> [ * 1 ](i))_{i in Subsets of {0, 1}}
>>>
>>> So it is expecting subsets and that the user will not input bad data.
>>> There is no reason for it to simplify and not a bug. Granted, we could put
>>> a check on the user input here, but there is a speed penalty as this can be
>>> a well-used code path internally. Moreover, ducktyping can also be useful.
>>> So we are fairly permissive here, but not without due cause IMO.
>>>
>>>
>> Pardon my ignorance, but If there is no simplification then what is all
>> this good for? It does simplify for universal enveloping algebra and so it
>> should do it for Clifford algebras as well. Also I have a big issue with
>> naming convention here. The method basis() does not produce a basis!
>>
>
> it is *bad input*. It does produce a basis, one indexed by *subsets*, not
> words/multisets. In math terms, if you have a sequence (x_i)_{i \in I},
> then want x_j, where j \notin I, then you have an error. With #18750, this
> input might instead raise an error. If you want to do that, then you can do
> this:
>
> sage: Q = QuadraticForm(QQ, 2, [1,0,1])
> sage: C = CliffordAlgebra(Q)
> sage: g = list(C.algebra_generators()); g
> [e0, e1]
> sage: prod(g[i] for i in [0,0,1,0,1,1,0,0])
> -e0*e1
>
> If you took your input and wrapped it with set:
>
> sage: set((1,1,0,1))
> {0, 1}
>
> which would be the other possible outcome with #18750.
>
>
>>  I understand that it might be convenient for implementation details to
>> use tuples of numbers (not subsets!!!) to index elements, but why can I
>> index with E, F and H in the universal enveloping algebra case and not with
>> e and f in the Clifford algebra case?
>>
>> It seems that accessing Clifford algebra elements through basis just
>> messes up with the simplification.
>>
>> x = cb[(1,1,0,1)]
>> print(simplify(x))
>> print(type(x))
>> print(f*f*e*f)
>> print(type(f*f*e*f))
>> print(f*f*e*f == x)
>>
>>
>> Do not confuse a bug with a not-yet-implemented feature: (noncommutative)
>>> polynomial rings are not in AlgebrasWithBasis, so it is not expected that
>>> they work with something like tensor(). However, it would be a good feature
>>> to add. :)
>>>
>>
>> I guess are referring to my complaints about not being able to take
>> tensor product with noncommutative ring. I see the naming convention as a
>> BUG. If the method has "algebra" in it's name, it should produce algebra
>> and not a ring. If a method has "basis" in its name, it should produce
>> basis not a generating set as C.basis() does or a basis and not an algebra
>> as pbw_basis() does.
>>
>
> Remember that we are bound by the facilities of computer science and
> programming within Sage as well, which are usually much stronger
> constraints than mathematics (e.g., consider the set of real numbers). For
> the current implementation of tensor products, we require the algebra to be
> in AlgebrasWithBasis. I would not say limitations of the current framework
> to be a bug. Also, NC poly rings are in the category of algebras, so it
> does produce an algebra.
>
> C.basis() does produce a basis.
>
> sage: list(C.basis())
> [1, e0, e1, e0*e1]
>
> Now pbw_basis() does return an algebra in a particular basis, so in some
> ways, it is returning a basis, just not for the Lie algebra. So now I see
> why you feel it is not completely natural. However, do you have a proposal
> for how to have convenient access to the PBW basis of U(*g*)? IMO, it
> cannot be connected with universal_enveloping_algebra() because that only
> has to return a class modeling the UEA, which should not be required to
> have a PBW basis method. Also, I feel that a PBW basis is really more
> closely connected to the Lie algebra and it is clear to someone working in
> this field what pbw_basis would return.
>
>>
>>
>>>
>>> if you want to access the basis, use the .basis() method.
>>>
>>> Also, how is pbw_basis not an intuitive name for obtaining the PBW basis
>>> (there is also the fully spelled out version too)? If you want to change
>>> the ordering, RTM of "PBW?" to pass in an ordering function to
>>> L.pbw_basis().
>>>
>>>
>> For naming conventions see above. I checked out helpstring for PBW and I
>> am still not sure how to produce e.g. E, F, H ordering. I suggest to move
>> this helpstring to L.pbw_basis().
>>
>
> -1 It is connected with the construction of the PBW class and not handled
> in the pbw_basis() method. However, I do agree that it would be good to
> have an (different) example in the pbw_basis() and a reference to the PBW
> class in the docstring.
>
>
>> Now the fact that you sometimes obtaining random attribute errors when
>>> running that code block is a definite bug. Please submit a trac ticket.
>>>
>>>
>> Submitted as https://trac.sagemath.org/ticket/24822
>>
>
> Great, thank you.
>
>
>> In general, I think it is difficult to determine the tensor product of
>>> two (non commutative, non PBW) algebras over an arbitrary subalgebra. There
>>> is some code for doing smash products somewhere on #15874, but it has
>>> bitrotted and IDK if that will give you what you want. I did write some
>>> code to compute Verma modules via the PBW basis. I had to work somewhat
>>> hard to make it work, and it wasn't apparent to me how to extend that to
>>> more general framework.
>>>
>>>
>> Verma modules (for finite-dimensional semisimple Lie algebras) were
>> exactly what I had in mind. Are they already in Sage somewhere? I haven't
>> seen them.
>>
>
> See https://trac.sagemath.org/ticket/23517. I try to track the overall
> progress of Lie algebras in Sage in essentially metaticket
> https://trac.sagemath.org/ticket/14901.
>
> Best,
> Travis
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "sage-devel" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/
> topic/sage-devel/XK-RxN3_qvY/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> sage-devel+unsubscr...@googlegroups.com.
> To post to this group, send email to sage-devel@googlegroups.com.
> Visit this group at https://groups.google.com/group/sage-devel.
> For more options, visit https://groups.google.com/d/optout.
>

--
You received this message because you are subscribed to the Google Groups
"sage-devel" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to sage-devel+unsubscr...@googlegroups.com.
To post to this group, send email to sage-devel@googlegroups.com.
Visit this group at https://groups.google.com/group/sage-devel.
For more options, visit https://groups.google.com/d/optout.