2012/12/13, Nicolas M. Thiery <nicolas.thi...@u-psud.fr>:
>       Hi Andrew!
>
> On Wed, Dec 12, 2012 at 05:37:19PM -0800, Andrew Mathas wrote:
>>    I have being trying to find the right idiom for look-up and reverse
>> look
>>    ups in large enumerated sets. Prior to sage, I simply would have made
>> a
>>    large list of the elements in the enumerated set and then just used
>>    __getitem__ (implictly) and index().
>>
>>    I thought that in sage here might be an approved and efficient way of
>>    doing this but instead I have been surprised. Consider:
>>    sage: parts=Partitions(50)
>>    sage: parts.category()
>>    Category of finite graded enumerated sets
>>    sage: mu=parts.unrank(204225);mu
>>    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
>> 1,
>>    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
>> 1,
>>    1]
>>    sage: parts.rank(mu)
>>    204225
>>    which looks fine except that unrank is very quick whereas rank is very
>>    slow. Certainly, rank() could be made more efficient by caching the
>> result
>>    )although what to do if the object has multiple parents), but I don't
>> see
>>    any way of making unrank() faster until you create a list of elements.
>>    Here are the timing for this example:
>>
>>    sage: %timeit Partitions(50).unrank(204225)
>>    625 loops, best of 3: 13.7 Aus per loop
>>    sage: %timeit Partitions(50).rank(mu)
>>    5 loops, best of 3: 3.66 s per loop
>>    Actually, this is a slight lie: initially, rank and unrank both just
>> run
>>    through the iterator until they hit their match -- and this is slow --
>> but
>>    after doing something like Partitions(50)[50], in the background
>>    Partitions(50)._list has been created and unrank() has been replaced
>> by
>>    _list[ rank] whereas rank() is still using the iterator. The culprit
>> seems
>>    to be __getitem__ which is initially defined as
>>
>>    try:
>>        return super(Parent, self).__getitem__(n)
>>     except AttributeError:
>>        return self.list()[n]
>>
>>    With other (ungraded?) enumerated sets such as StandardTableaux(10)
>> the
>>    iterator is always used, and this is slow.
>>
>>    I think that the behaviour of Partitions(n) above is a bug, but I am
>>    getting side-tracked.
>>
>>    The question that is want to ask is:
>>
>>    If I have a (large but not hugely large) enumerated set for which I
>> will
>>    be doing frequent rank() and unrank() calls what is the recommended way
>> of
>>    playing with it?
>>
>>    My inclination now is just to turn the enumerated set into a list, as
>>    _list[2832] and _list.index(mu) are as efficient as you get. Does
>> anyone
>>    know of a better way?
>
> Short answer for now: if you have a finite enumerated set S and you do
> S.list(), then this list is cached and used for most other operations
> (counting, unranking, and probably random generation as a side
> effect). It would be natural to extend this feature to ranking by
> building a reverse dictionary (possibly with some level of lazyness,
> so that the dictionary only gets built if unranking is actually used).

I actually did it in #8920 and removed as it appears that it slows
down everything as to test
  my_object in my_dictionnary
the object my_object needs to be hashable and you have to catch the
error. Perhaps I did it the wrong way... any advice is welcome.

Best,
Vincent

-- 
You received this message because you are subscribed to the Google Groups 
"sage-combinat-devel" group.
To post to this group, send email to sage-combinat-devel@googlegroups.com.
To unsubscribe from this group, send email to 
sage-combinat-devel+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sage-combinat-devel?hl=en.

Reply via email to