>  
>>
>>> 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.
>>>
>>
>> No, they are just have the same names. A good parallel would be the 
>> polynomial ring R = ZZ[x,y] in the natural basis. Here, R is the ZZ-algebra 
>> of the abelian monoid A = <x,y>, and subsequently, the basis elements are 
>> indexed by elements in A. We can call the elements in the monoid <c,d>, but 
>> that induces undue overhead on the programmer. For the PBW case, granted it 
>> is not a monoid algebra, so we cannot simply *coerce* in things from the 
>> indexing monoid (but of course, conversion is allowed), but the design is 
>> there. I would just be taking products of the algebra generators anyways 
>> and not worrying about constructing elements via the basis.
>>  
>>
>
> Thank you for clarification. I checked and they are different objects. 
> They just have the same _repr_ string. Probably nothing to be done about 
> that.
>

The reason for that is somewhere between being natural and being lazy. The 
easiest way to implement the PBW basis was to pass the prefix to the 
underlying basis indexing set and not do any string parsing and replacing 
in the subclass of CombinatorialFreeModule. I also felt it was natural as I 
outlined above.

>  
>
>> I looked at the ticket and I have no idea what it is about. 
>>>
>>
>> Right now, if we are trying to construct a monomial, we do not convert it 
>> into the indexing set of the basis and instead trust the user to do it. The 
>> ticket #18750 is about changing that. 
>>
>
> OK. I don't really understand the wording of the ticket. I checked the 
> example given there and it works and as far as I can tell it works as it 
> should. In my opinion, Sage should give errors when the user tries to input 
> something like 
>
> C.basis()[(1,0)]
>

Not if the basis is indexed by tuples or the indexing set that takes tuples 
as input? You then put the burden on the user and double create the 
indexing elements (or worse, you force a containment test). Also, there is 
no reason why we should force the indexing set to be a subclass of Parent 
or be a callable object.

>
> I don't know enough about implementation details to see why any 
> performance hit there would matter. In case the speed is really needed 
> perhaps we could have another (private) method without the checks that 
> would be used in heavy calculations? Waiting few hours more for some 
> extensive calculations is definitely better than risking a worng output 
> because you somewhere made a transposition error (0, 1) -> (1, 0).
>

It is used in a tight loop (which this code can be), that can a few hours 
can actually be double the time it used to take.
 

> 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()?
>>>
>>
>> Here we get into implementation details, and given your previous 
>> complaint about index sets, you are not going to like it. The object used 
>> to model the subsets are tuples.]
>>
>
> And right there is the problem I have. Why do I, as a user, should know 
> anything about the implementation details? Example of usage would bring me 
> a long way. (Hence I propose to create a ticket for adding more examples 
> into docstrings.)
>

+1 Go ahead and create it. I will be happy to review it.
 

> Perhaps even better would be to have a more descriptive docstring for  
> SubsetsSorted that would explain that the objects are actually ordered 
> tuples. Or at least that the objects are SortedSets.
>

Sometimes we need to make tradeoffs for ease of programming maintenance and 
speed. Now we can check the user input to put it into correct form, but IMO 
it is needless technical debt and wasted CPU cycles to use a more 
complicated class than Python's tuple.

>
>> sage: C.basis().keys()
>> Subsets of {0, 1}
>> sage: list(_)
>> [(), (0,), (1,), (0, 1)]
>>
>> However, we do require an explicit total order on the generators to have 
>> a well-defined representative of a monomial.
>>  
>>
>>> 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).
>>>
>>
>> You can always do tensor([x,y]), and you do not need to explicitly create 
>> the parent that way as well.
>>
>>
> That's awesome! Great. It would be nicer if it worked even without the 
> square brackets but that's just nitpicking. More importantly -- where are 
> these features documented?
>

It is in CombinatorialFreeModule_tensor. I was thinking there was an 
example in "tensor()", but there is not. We should add one to tensor().

>  
>
>>
>>>> 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? 
>>>
>>
>> foo.category()
>>
>>  
>>>
>>>> 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.
>>>
>>
>> Perfect bases (the q=1 version of a crystal basis) are equally good. Just 
>> having the existence of the UEA can allow you to do a fair bit of the 
>> representation theory. Also, there is no reason why we should limit someone 
>> doing a Lie algebra implementation to having the UEA be in the PBW basis. 
>> Also, for the free Lie algebra, its UEA is the free algebra, which has a 
>> natural basis you can work with.
>>
>> I agree that the (NC) poly rings should be in the category of 
>> AlgebrasWithBasis as they are given with a distinguished basis, but there 
>> are methods that need to be implemented and some inconsistencies to resolve 
>> IIRC.
>>
>
> Perhaps a topic for SageDays94?
>

+1 <shameless plug>You should also apply for funding as a participant for 
SageDays@ICERM too.</shameless plug>

>  
>
>>  
>>
>>> 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 agree that it is not the best that it does not return a basis *of L*, 
>> but there is fundamentally no difference between a basis of the UEA and the 
>> UEA in a distinguished basis (other than possibly the interface).
>>
>
> There is a big conceptual difference between algebra and a basis of an 
> algebra. For all practical purposes, pbw_basis() returns an object that 
> behaves and is used, as far as I can see, as an algebra. I showed the 
> current behavior to participants of SageDays93 and we all agreed that the 
> current behavior of universal_enveloping_algebra() and pbw_basis() is 
> confusing.
>

I do not know how you presented it, but I feel that it a bit unfair to say 
because you yourself had said you are confused by it. Also, the pbw_basis() 
is not an algebra in the abstract concept but a class modeling a chosen PBW 
basis of the UEA. So there is a lot more structure (and limitations).

>   
>
>>  
>>
>>> I propose to get rid of pbw_basis method and introduce optional argument 
>>> pbw_basis_ordering to universal_enveloping_algebra method.
>>>
>>
>> Very strong -1. I do not believe the UEA should be forced to be in the 
>> PBW basis, which is what you are effectively making it do. Either that or 
>> you do cannot impose the behavior of a PBW basis. It also imposes much 
>> stronger restrictions on universal_enveloping_algebra(). In your proposal 
>> as well, the code is suggesting that it should be two separate methods and 
>> there is no easy way to construct the UEA in some PBW basis. I am open to 
>> changing the name of the method pbw_basis(), but I oppose merging it with 
>> universal_enveloping_algebra().
>>
>>
> Sorry, I don't understand. What restrictions are you talking about here? 
> PBW basis always  exists. Is it not true that all Lie algebras in Sage have 
> one basis or another? 
>

Mathematical abstraction versus concrete computation. *Abstractly*, you 
always have a PBW basis, so *abstractly* you always have an isomorphism 
with any other class modeling a basis of the UEA. However, you may not know 
what that isomorphism is *concretely*. Hence, it is impossible to define a 
coercion between a PBW basis and a generic basis of the UEA. However, by 
attaching a pbw_basis() to any UEA (which, as I said above, is wholly 
impractical to do), you are tacitly saying there should be a way to go from 
that UEA implementation to the object returned by the pbw_basis (I would 
certainly object).

Also, I believe it is possible to define a Lie algebra from an associative 
algebra that does not have a (distinguished) basis, and so this Lie algebra 
would not have a (distinguished) basis. At least, I do not believe there 
are any technical limitations to this. You can also define an object in Lie 
algebras as being a set of matrices satisfying certain conditions closed 
under commutators and not know what an explicit basis is. While it does not 
afford you much in the way of features currently, its not to say that there 
might be enough structure there to do something useful with it. There is no 
reason to limit the future.

>  
> In my opinion, the object coming from pbw_basis() is much more useful and 
> will be used by more people than the one coming from 
> universal_enveloping_algebra().
>

That is great for your applications. What if you want to look at certain 
ideals of the UEA and, say, compute its syzygy module:

sage: L = lie_algebras.sl(QQ,2)
sage: UEA = L.universal_enveloping_algebra()
sage: e,h,f = UEA.gens()
sage: I = UEA.ideal(e^2-h, f^2-h, side='twosided')
sage: I.syzygy_module()

Being fair, I don't know if people actually look at such things, but I know 
there are ways to compute Gröbner bases of NC ideals in Singular (Plural?); 
this was the first hit on Google "noncommutative groebner basis, singular"

https://www.ricam.oeaw.ac.at/specsem/srs/groeb/download/Levandovskyy_ncgb.pdf

So it might just be a matter of exposing Singular features in Sage to do 
things like quotients in NC rings, whereas it do similar computations with 
the PBW basis would require a significant amount of work currently.
 

> Somebody actually proposed the same thing as Sebastian. Since, as you say, 
> there are implementation difficulties with that approach, what about: 
> universal_enveloping_algebra -> abstract_universal_enveloping_algebra & 
> pbw_basis -> universal_enveloping_algebra? Another suggestion was pbw_basis 
> -> universal_enveloping_algebra_with_pbw_basis.
>

I believe that is completely unmanageable unless I am misunderstanding 
something about your approach. You would require a (sub)class for each Lie 
algebra that wanted to implement a different UEA that the PBW basis. Let me 
say again that mathematics has a lot more freedom than computer 
implementations; the canonical being the real numbers and formal power 
series.

Here is an idea based on one of your suggestions for how to have 
universal_enveloping_algebra() be more, ahem, universal.

def universal_enveloping_algebra(self, implementation=None, **kwds):
    if implementation is None:
        return self.lift.codomain()
    elif implementation is "PBW":
        return self.pbw_basis(**kwds)
    else:
        raise ValueError("invalid implementation")

This way you can specify the implementation with having a default being the 
(distinguished) one from _construct_UEA() and you get the PBW basis. (Well, 
technically this would go in the LieAlgebrasWithBasis category and the one 
in LieAlgebras would not have the extra PBW implementation elif.)

Best,
Travis

-- 
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.

Reply via email to