2011-08-15 15 views
5

Wszystkie funkcje ..Values mają nieudokumentowane opcję Sort:Co "Sortuj" opcja ... Wartości?

In[1]:= Options /@ {OwnValues, DownValues, UpValues, SubValues, 
    DefaultValues, FormatValues, NValues} 

Out[1]= {{Sort -> True}, {Sort -> True}, {Sort -> True}, {Sort -> 
    True}, {Sort -> True}, {Sort -> True}, {Sort -> True}} 

Co ta opcja jest i do jakich celów może być przydatna?

Odpowiedz

8

Po wprowadzeniu definicji funkcji, wprowadzasz je w określonej kolejności. W przypadku, gdy twoje definicje nie zawierają wzorów, są one przechowywane wewnętrznie w tabeli mieszającej. Gdy ich zażądasz, zostaną one domyślnie posortowane:

In[11]:= 
Clear[g]; 
g[5]=1; 
g[4]=2; 
g[3]=3; 

In[15]:= DownValues[g] 
Out[15]= {HoldPattern[g[3]]:>3,HoldPattern[g[4]]:>2,HoldPattern[g[5]]:>1} 

Jednak często możesz chcieć zobaczyć oryginalną kolejność, w której zostały przypisane wartości. Oto jak:

In[16]:= DownValues[g,Sort->False] 
Out[16]= {HoldPattern[g[5]]:>1,HoldPattern[g[4]]:>2,HoldPattern[g[3]]:>3} 

Przykładem jednej instancji, gdzie może chcesz go używać, to kiedy trzeba zaimplementować cache (moja próba zrobienia, że ​​na podstawie tej opcji można znaleźć here). Jednak w przypadku dużej liczby definicji prawdopodobnie nie ma pewności, że definicje zostaną zastosowane w pierwotnej kolejności, ponieważ wewnętrzne tablice skrótów będą prawdopodobnie rozbudowywane i ponownie uruchamiane kilka razy. Zasadniczo implementacja tabeli mieszania nie gwarantuje kolejności, w której są przechowywane pary klucz-wartość. Więc, co osiągniesz ustawiając Sort->False, to, że ...Values nie są posortowane przez Mathematica, zanim zostaną ci zwrócone, więc otrzymujesz je w kolejności, w jakiej Mathematica aktualnie je przechowuje.

Innym przypadkiem, gdy może chcesz, jest to, kiedy chcesz zbudować strukturę podobną do słownika przy użyciu DownValues - w tym przypadku ekstrakcja klucza będzie znacznie szybsza z Sort->False, ponieważ nie trzeba sortować na zestawie kluczy (ma znaczenie dla dużych zestawów kluczy):

In[31]:= 
Clear[gg]; 
(gg[#]:=200000-#)&/@Range[200000]; 

In[33]:= DownValues[gg][[All,1,1,1]]//Short//Timing 
Out[33]= {4.867,{1,2,3,<<199994>>,199998,199999,200000}} 

In[34]:= DownValues[gg,Sort->False][[All,1,1,1]]//Short//Timing 
Out[34]= {2.103,{95090,102286,<<199996>>,38082,26686}} 

Można znaleźć przykład takiego zastosowania, np. here.

O ile mi wiadomo, opcja Sort wpływa tylko nie w oparciu o wzorce DownValues (i inne ...Values), bo w oparciu o wzorce DownValues Mathematica w każdym razie próbuje uporządkować je w kolejności ich ogólności, jak to rozumie że. OTOH, w przypadku wzorcowania DownValues, możesz wykonać ręczne ponowne zamawianie reguł, a Mathematica zachowa zmiany, natomiast w przypadku definicji bez wzorów próby ręcznej zmiany definicji po tym, jak zostały pierwotnie podane, nie mają na nie wpływu (być może, ponieważ są mieszane wewnętrznie, a tabele mieszające nie generalnie dbają o porządek).

+1

czy możesz rozwinąć nieco na "... ponieważ wewnętrzne tablice mieszające zostaną prawdopodobnie rozszerzone i ponownie uruchomione kilka razy"? – acl

+2

@ acl Typowy tablica hash ma określoną pojemność - wiele elementów może efektywnie mieszać, a prawdopodobieństwo kolizji nie jest zbyt wysokie. Gdy dodamy definicje, w pewnym momencie tablica haszowania prawdopodobnie wykona dynamiczną zmianę rozmiaru, zwiększając jej pojemność. Może, ale nie musi, ponownie haszować istniejące wpisy, w zależności od implementacji. Te rzeczy są bardzo ładnie wyjaśnione tutaj: http://en.wikipedia.org/wiki/Hash_table. Większość tabel mieszania nie obsługuje kolejności kluczy, ale istnieją pewne (np. 'LinkedHashMap' w Javie), które mają. –

+0

dzięki. Sądzę, że bardziej pytałem, czy zaobserwowałeś to robiąc MMA, a jeśli tak, to jak. – acl