Główna kolejność wierszy i kolumn - Row- and column-major order
W komputerowych, wiersz znaczne zamówienie i kolumny głównym celu są sposoby przechowywania wielowymiarowych tablic w pamięci liniowej, takich jak pamięci o dostępie swobodnym .
Różnica między zamówieniami polega na tym, które elementy tablicy są ciągłe w pamięci. W kolejności wiersz-główny, kolejne elementy wiersza znajdują się obok siebie, podczas gdy to samo dotyczy kolejnych elementów kolumny w kolejności kolumnowej-głównej. Podczas gdy terminy nawiązują do wierszy i kolumn tablicy dwuwymiarowej, tj. macierzy , rzędy można uogólnić na tablice o dowolnym wymiarze, zauważając, że terminy wiersz-major i kolumna-major są równoważne rzędom leksykograficznym i koleksykograficznym , odpowiednio.
Układ danych ma kluczowe znaczenie dla prawidłowego przekazywania tablic między programami napisanymi w różnych językach programowania. Jest to również ważne dla wydajności podczas przechodzenia przez tablicę, ponieważ nowoczesne procesory przetwarzają dane sekwencyjne wydajniej niż dane niesekwencyjne. Wynika to przede wszystkim z buforowania procesora, które wykorzystuje przestrzenną lokalizację odniesienia . Ponadto ciągły dostęp umożliwia korzystanie z instrukcji SIMD operujących na wektorach danych. W przypadku niektórych nośników, takich jak taśma lub pamięć flash NAND , dostęp sekwencyjny jest o rząd wielkości szybszy niż dostęp niesekwencyjny.
Wyjaśnienie i przykład
Terminy wiersz-dur i kolumna-dur wywodzą się z terminologii związanej z porządkowaniem obiektów. Ogólnym sposobem porządkowania obiektów z wieloma atrybutami jest najpierw pogrupowanie i uporządkowanie według jednego atrybutu, a następnie, w ramach każdej takiej grupy, pogrupowanie i uporządkowanie według innego atrybutu itd. Jeśli w porządkowaniu uczestniczy więcej niż jeden atrybut, pierwszy nazywać się major i ostatni minor . Jeśli w porządkowaniu uczestniczą dwa atrybuty, wystarczy nazwać tylko główny atrybut.
W przypadku tablic atrybutami są indeksy wzdłuż każdego wymiaru. Do matryc w notacji matematycznej, pierwszy wskaźnik wskazuje rząd , a drugi oznacza kolumnę , na przykład, biorąc pod uwagę macierz , jest w pierwszym rzędzie i drugiej kolumnie. Konwencja ta została przeniesiona do składni w językach programowania, chociaż często indeksy zaczynają się od 0 zamiast 1.
Mimo że wiersz jest wskazywany przez pierwszy indeks, a kolumna przez drugi indeks, nie wynika z tego kolejność grupowania między wymiarami. Wybór sposobu grupowania i porządkowania indeksów, czy to metodą wierszową, czy kolumnową, jest więc kwestią umowną. Tę samą terminologię można zastosować do tablic o jeszcze wyższych wymiarach. Row-major grupowanie rozpoczyna się od skrajnej lewej indeksu i kolumny-dur z prawej skrajnej indeksu, prowadzące do leksykograficznego i colexicographic (lub Colex) zamówień , odpowiednio.
Na przykład tablica
można przechowywać na dwa sposoby:
Adres | Wiersz-główne zamówienie | Kolumna-główne zamówienie |
---|---|---|
0 | ||
1 | ||
2 | ||
3 | ||
4 | ||
5 |
Różne języki programowania radzą sobie z tym na różne sposoby. W języku C tablice wielowymiarowe są przechowywane w kolejności wiersz-główny, a indeksy tablicy zapisywane są od pierwszego wiersza (kolejność dostępu leksykograficznego):
Adres | Dostęp | Wartość |
---|---|---|
0 |
A[0][0]
|
|
1 |
A[0][1]
|
|
2 |
A[0][2]
|
|
3 |
A[1][0]
|
|
4 |
A[1][1]
|
|
5 |
A[1][2]
|
Z drugiej strony w Fortranie tablice są przechowywane w kolejności kolumnowej, podczas gdy indeksy tablic są nadal zapisywane w kolejności od pierwszego wiersza (koleksykograficzna kolejność dostępu):
Adres | Dostęp | Wartość |
---|---|---|
1 |
A(1,1)
|
|
2 |
A(2,1)
|
|
3 |
A(1,2)
|
|
4 |
A(2,2)
|
|
5 |
A(1,3)
|
|
6 |
A(2,3)
|
Zwróć uwagę, jak użycie A[i][j]
z indeksowaniem wieloetapowym, jak w C, w przeciwieństwie do neutralnej notacji, jak A(i,j)
w Fortranie, prawie nieuchronnie implikuje porządek wiersz-główny ze względów składniowych, że tak powiem, ponieważ można go przepisać jako (A[i])[j]
, a A[i]
wiersz część można nawet przypisać do zmiennej pośredniej, która jest następnie indeksowana w oddzielnym wyrażeniu. (Nie należy zakładać żadnych innych implikacji, np. Fortran nie jest kolumną główną po prostu ze względu na jej notację, a nawet powyższa implikacja może zostać celowo ominięta w nowym języku.)
Aby użyć porządku kolumna-główna w środowisku wiersza-głównego lub odwrotnie, z jakiegokolwiek powodu, jednym obejściem jest przypisanie niekonwencjonalnych ról do indeksów (używając pierwszego indeksu dla kolumny i drugiego indeksu dla wiersza), a innym jest ominięcie składni języka poprzez jawne obliczenie pozycji w jednowymiarowej tablicy. Oczywiście odejście od konwencji wiąże się zapewne z kosztem, który wzrasta wraz ze stopniem niezbędnej interakcji z konwencjonalnymi funkcjami języka i innym kodem, nie tylko w postaci zwiększonej podatności na błędy (zapominając także o odwróceniu kolejności mnożenia macierzy, powrót do konwencji podczas kodu konserwacja itp.), ale także w postaci konieczności aktywnego przestawiania elementów, z których wszystkie muszą być brane pod uwagę w stosunku do pierwotnego celu, takiego jak zwiększenie wydajności. Uruchamianie pętli w wierszach jest preferowane w językach z głównymi wierszami, takich jak C i na odwrót w przypadku języków z głównymi kolumnami.
Języki programowania i biblioteki
Języki programowania lub ich standardowe biblioteki, które obsługują tablice wielowymiarowe, zazwyczaj mają dla tych tablic natywną kolejność przechowywania głównych wierszy lub kolumn.
Porządek rzędów głównych jest używany w językach C / C++ / Objective-C (dla tablic w stylu C), PL/I , Pascal , Speakeasy , SAS i Rasdaman .
Porządek główny kolumna jest używany w Fortran , MATLAB , GNU Octave , S-Plus , R , Julia i Scilab .
Ani wiersz-główny, ani kolumna-główny
Typową alternatywą dla gęstego przechowywania tablic jest użycie wektorów Iliffe , które zazwyczaj przechowują wskaźniki do elementów w tym samym wierszu w sposób ciągły (jak wiersz główny), ale nie same wiersze. Są one używane w (uporządkowanych według wieku): Java , C# / CLI / .Net , Scala i Swift .
Nawet mniej gęsta jest użycie list list, na przykład w Pythonie , aw Wolfram Języka od Wolfram Mathematica .
Alternatywne podejście wykorzystuje tabele tabel, np. w Lua .
Biblioteki zewnętrzne
Wsparcie dla tablic wielowymiarowych mogą być również zapewniane przez biblioteki zewnętrzne, które mogą nawet obsługiwać dowolne porządkowanie, gdzie każdy wymiar ma wartość kroku, a wiersz-major lub column-major to tylko dwie możliwe interpretacje wynikowe.
Kolejność rzędów głównych jest domyślna w NumPy (dla Pythona).
Kolumna-główna kolejność jest domyślna w Eigen i Armadillo (oba dla C++).
Szczególnym przypadkiem byłby OpenGL (i OpenGL ES ) do przetwarzania grafiki. Ponieważ „ostatnie zabiegi matematyczne dotyczące algebry liniowej i powiązanych pól niezmiennie traktują wektory jako kolumny”, projektant Mark Segal postanowił zastąpić to konwencją w poprzedniku IRIS GL , która polegała na zapisaniu wektorów jako wierszy; ze względu na zgodność, macierze transformacji nadal byłyby przechowywane w kolejności wektora-głównego (=wiersz-główny), a nie współrzędnej-głównej (=kolumna-główna), a następnie użył sztuczki „[że] powiedzieć, że macierze w OpenGL są przechowywane w kolumna-główny porządek". Było to tak naprawdę istotne tylko w przypadku prezentacji, ponieważ mnożenie macierzy było oparte na stosie i nadal można je interpretować jako post mnożenie, ale, co gorsza, rzeczywistość wyciekła przez API oparte na C, ponieważ dostęp do poszczególnych elementów byłby możliwy jako M[vector][coordinate]
lub, w rzeczywistości, M[column][row]
, który niestety pomyliła konwencję, którą projektant chciał przyjąć, i została ona nawet zachowana w dodanym później języku cieniowania OpenGL (chociaż umożliwia to również dostęp do współrzędnych po nazwie, np M[vector].y
. ). W rezultacie wielu programistów po prostu zadeklaruje teraz, że posiadanie kolumny jako pierwszego indeksu jest definicją kolumny głównej, chociaż wyraźnie nie jest tak w przypadku prawdziwego języka głównego kolumny, takiego jak Fortran.
Pochodnia (dla Lua) zmieniona z domyślnej kolejności kolumna-główna na wiersz-główna.
Transpozycja
Ponieważ wymiana indeksów tablicy jest istotą transpozycji tablicy , tablica przechowywana jako wiersz-główny, ale odczytywana jako kolumna-główna (lub odwrotnie) będzie wyświetlana jako transponowana (o ile macierz jest kwadratowa). Ponieważ faktycznie przeprowadzanie tego przegrupowania w pamięci jest zazwyczaj kosztowną operacją, niektóre systemy zapewniają opcje określania poszczególnych macierzy jako przechowywanych transponowanych. Programista musi następnie zdecydować, czy zmienić kolejność elementów w pamięci, na podstawie rzeczywistego użycia (w tym liczby ponownego użycia tablicy w obliczeniach).
Na przykład, funkcje podstawowych podprogramów algebry liniowej otrzymują flagi wskazujące, które tablice są transponowane.
Ogólne obliczanie adresu
Koncepcja uogólnia się na tablice o więcej niż dwóch wymiarach.
Dla d- wymiarowej tablicy o wymiarach N k ( k =1... d ), dany element tej tablicy jest określony przez krotkę indeksów d ( liczonych od zera) .
W porządku wiersz-główny ostatni wymiar jest ciągły, tak że przesunięcie pamięci tego elementu jest określone przez:
W porządku kolumnowym, pierwszy wymiar jest ciągły, tak że przesunięcie pamięci tego elementu jest określone wzorem:
gdzie pusty produkt jest multiplikatywnym elementem tożsamości , czyli .
Dla danego zamówienia krok w wymiarze k jest podany przez wartość mnożenia w nawiasach przed indeksem n k w podsumowaniach po prawej stronie powyżej.
Ogólnie rzecz biorąc, istnieje d! możliwe porządki dla danej tablicy, po jednym dla każdej permutacji wymiarów (z wierszami-głównymi i kolumnowymi tylko 2 przypadkami specjalnymi), chociaż listy wartości kroków niekoniecznie są permutacjami siebie nawzajem, np. w 3 przykład powyżej, kroki to (3,1) dla wiersza-głównego i (1,2) dla kolumny-głównej.
Zobacz też
- Tablica struktury danych
- Reprezentacja macierzowa
- Wektoryzacja (matematyka) , odpowiednik zamiany macierzy na odpowiedni wektor kolumny-główny
- Format CSR , technika przechowywania rzadkich macierzy w pamięci
- Porządek Mortona , inny sposób mapowania danych wielowymiarowych na indeks jednowymiarowy, przydatny w drzewiastych strukturach danych
Bibliografia
- ^ „Pamięć podręczna” . Peter Lars Dordal . Pobrano 2021-04-10 .
- ^ „Tablice i sformatowane we/wy” . Samouczek FORTRAN . Źródło 19 listopada 2016 .
- ^ "Dlaczego numeracja powinna zaczynać się od zera" . Archiwum EW Dijkstry . Źródło 2 lutego 2017 .
-
^ „Wersja odniesienia językowego 4 wydanie 3” (PDF) . IBM . Źródło 13 listopada 2017 .
Wartości początkowe określone dla tablicy są przypisywane do kolejnych elementów tablicy w kolejności wiersz-główny (końcowy indeks dolny zmieniający się najszybciej).
-
^ „ISO/IEC 7185: 1990(E)” (PDF) .
Typ tablicy, który określa sekwencję dwóch lub więcej typów indeksów, powinien być notacją skróconą dla typu tablicy określonego tak, aby jako typ indeksu miał pierwszy typ indeksu w sekwencji i aby miał typ komponentu, który jest typ tablicy określający sekwencję typów indeksów bez pierwszego typu indeksu w sekwencji i określający ten sam typ komponentu, co oryginalna specyfikacja.
-
^ „SAS® 9.4 Język odniesienia: Koncepcje, wydanie szóste” (PDF) . SAS Institute Inc. 6 września 2017 r. s. 573 . Źródło 18 listopada 2017 .
Od prawej do lewej, prawy wymiar reprezentuje kolumny; następny wymiar reprezentuje rzędy. [...] SAS umieszcza zmienne w wielowymiarowej tablicy, wypełniając wszystkie wiersze w kolejności, zaczynając od lewego górnego rogu tablicy (tzw. row-major order).
- ^ "Wewnętrzna reprezentacja tablicowa w rasdamanie" . rasdaman.org . Źródło 8 czerwca 2017 .
- ^ Dokumentacja MATLAB, MATLAB Data Storage (pobrana z Mathworks.co.uk, styczeń 2014).
- ^ Spiegelhalter i in. (2003 , s. 17): Spiegelhalter, David ; Tomasz, Andrzej; Najlepsza, Nicky ; Lunn, Dave (styczeń 2003), „Formatowanie danych: format S-Plus”, Podręcznik użytkownika WinBUGS (PDF) (wersja 1.4 ed.), Cambridge, Wielka Brytania: MRC Biostatistics Unit, Institute of Public Health, zarchiwizowane z oryginału ( PDF) dnia 2003-05-18
- ^ Wprowadzenie do R , Sekcja 5.1: Tablice (pobrano marzec 2010).
- ^ "Wielowymiarowe tablice" . Julia . Źródło 9 listopada 2020 .
-
^ „FFT z danymi wielowymiarowymi” . Scilab Wiki . Źródło 25 listopada 2017 .
Ponieważ Scilab przechowuje tablice w formacie głównym kolumny, elementy kolumny sąsiadują ze sobą (tj. oddzielenie 1) w formacie liniowym.
- ^ „Specyfikacja języka Java” . Wyrocznia . Źródło 13 lutego 2016 .
- ^ „tablica obiektów” . Biblioteka standardowa Scala . Źródło 1 maja 2016 .
- ^ „Biblioteka standardowa Pythona: 8. Typy danych” . Źródło 18 listopada 2017 .
- ^ „Wektory i macierze” . Wolfram . Źródło 12 listopada 2017 .
- ^ „11,2 – Macierze i tablice wielowymiarowe” . Pobrano 6 lutego 2016 .
- ^ „N-wymiarowa tablica (ndarray)” . SciPy.org . Źródło 3 kwietnia 2016 .
-
^ „Eigen: Zamówienia magazynowe” . eigen.tuxfamily.org . Pobrano 23.11.2017 .
Jeśli kolejność przechowywania nie jest określona, Eigen domyślnie przechowuje wpis w kolumnie głównej.
- ^ „Wektory kolumnowe a wektory rzędowe” . Źródło 12 listopada 2017 .
- ^ „Tensor” . Pobrano 6 lutego 2016 .
- ^ „Tensor” . Instrukcja obsługi pakietu palnika . Pobrano 8 maja 2016 .
- ^ "BLAS (podprogramy algebry liniowej)" . Źródło 2015-05-16 .
Źródła
- Donald E. Knuth, The Art of Computer Programming Tom 1: Fundamental Algorithms , wydanie trzecie, sekcja 2.2.6 (Addison-Wesley: New York, 1997).