2011-05-31 11 views
7

Mam bardzo duży stół w Mathematica ((dimcub-1)^3 elementy) pochodzący z odwrotnej FFT. Muszę użyć okresowej interpolacji w tej tabeli. Ponieważ interpolacja okresowa wymaga, aby pierwsze elementy i ostatnie elementy były równe, ręcznie tworzę nową tabelę elementów dim^3 i używam tego w mojej interpolacji. Działa, ale jest brzydki/powolny, a ze względu na mój zbyteczny stół pośredni, szybciej trafiam w barierę pamięci. Czy ktokolwiek może mi powiedzieć, jak zamienić mój stary stół w jakiś okresowy, dodając elementy lub użyć mojego nieregularnego stołu, aby wykonać funkcję okresowej interpolacji? Oto mój obecny kawałek kodu:Interparyzacja interpolacji dużego stołu Mathematica

mr 1 jest nowa tabela:

mr1 = Table[ 0. , {i, 1, dimcub}, {j, 1, dimcub}, {k, 1, dimcub}]; 

Do[Do[ Do[ 
     mr1[[m, n, k]] = oldtable[[m, n, k]] ; , {m, 1, 
     dimcub - 1}]; , {n, 1, dimcub - 1}]; , {k, 1, dimcub - 1}]; 
Do[Do[  mr1[[m, n, dimcub]] = mr1[[m, n, 1]]; 
    mr1[[m, dimcub, n]] = mr1[[m, 1, n]]; 
    mr1[[dimcub, m, n]] = mr1[[1, m, n]];  , {m, 1, dimcub - 1}]; 
mr1[[n, dimcub, dimcub]] = mr1[[n, 1, 1]]; 
mr1[[dimcub, n, dimcub]] = mr1[[1, n, 1]]; 
mr1[[dimcub, dimcub, n]] = mr1[[1, 1, n]]; , {n, 1, dimcub - 1}]; 
mr1[[dimcub, dimcub, dimcub]] = mr1[[1, 1, 1]]; 

Remove[oldtable]; 

myinterpolatingfunction = 
ListInterpolation[mr1, {{1, dimcub}, {1, dimcub}, {1, dimcub}}, 
    InterpolationOrder -> 1, 
    PeriodicInterpolation -> True]; 

Remove[mr1]; 

myinterpolatingfunction zajmuje znacznie mniej pamięci i działa doskonale raz usunąć starsze tabele. Każda pomoc zostanie bardzo doceniona.

Odpowiedz

4

Dzięki za wszystkie odpowiedzi. Próbowałem sugestii leonida, ale kiedy wydrukowałem swoją starą tabelę, było to nadal (dimcub -1)^3 wymiarowe. Zdefiniowano nowe elementy i widzę je pojedynczo, ale nie wyświetlają się jako część starej tabeli, kiedy drukuję cały stół. Więc skończyło się z czymś podobnym, który robi dokładnie to, co potrzebne:

oldtable= PadRight[oldtable, {dimcub, dimcub, dimcub}]; 
oldtable[[All, All, dimcub]] = oldtable[[All, All, 1]]; 
oldtable[[All, dimcub, All]] = oldtable[[All, 1, All]]; 
oldtable[[dimcub, All, All]] = oldtable[[1, All, All]]; 
oldtable[[All, dimcub, dimcub]] = oldtable[[All, 1, 1]]; 
oldtable[[dimcub, All, dimcub]] = oldtable[[1, All, 1]]; 
oldtable[[dimcub, dimcub, All]] = oldtable[[1, 1, All]]; 
oldtable[[dimcub, dimcub, dimcub]] = oldtable[[1, 1, 1]]; 

Odpowiedź przez Wizard jest zbyt zaawansowany dla mojego poziomu Mathematica ..

+0

Myślę, że wszyscy tęskniliśmy za faktem, że chcieliśmy, aby nowy stół był większy od starego. Zobacz moją odpowiedź: To, co utrzymywało odpowiedź Leonida, odnosi się również do twojej: ostatnie cztery linie są zbędne. –

+0

Chciałem, aby nowy stół był większy niż poprzedni o 1 w każdym wymiarze, ponieważ jest to jedyny sposób, w jaki mogę mieć tabelę z pasującymi punktami końcowymi, aby wprowadzić ją do periodycznej interpolacji listy. Jeśli istnieje sposób na dokonanie okresowej interpolacji bez tego pośredniego kroku, wolałbym go użyć. – Hsn

+0

Czy mógłbyś zmodyfikować swoje rozwiązanie tak, aby okresowe było tylko 2. i 3. wymiary, a nie 1.? [w moim przypadku ostatnie 2 wymiary są współrzędnymi przestrzennymi, a pierwszym jest czas] – Valerio

8

można uzyskać znacznie szybciej i bardziej efektywnie pamięci modyfikując oryginalnej tabeli w następujący sposób:

oldtable[[All, All, -1]] = oldtable[[All, All, 1]]; 
oldtable[[All, -1, All]] = oldtable[[All, 1, All]]; 
oldtable[[-1, All, All]] = oldtable[[1, All, All]]; 
oldtable[[All, -1, -1]] = oldtable[[All, 1, 1]]; 
oldtable[[-1, All, -1]] = oldtable[[1, All, 1]]; 
oldtable[[-1, -1, All]] = oldtable[[1, 1, All]]; 
oldtable[[-1, -1, -1]] = oldtable[[1, 1, 1]]; 

Te zadania zastąpić zagnieżdżone pętle i są znacznie szybsze, plus nie trzeba pamięć do zapamiętywania Kopiuj. Jest to oparte na rozszerzonej wektoryzowanej funkcji polecenia Part (indeksowanie tablicy i ogólnego wyrażenia), w szczególności wektoryzacji. Ważne jest również, aby mieć tablicę liczbową w formularzu Packed array, co często ma miejsce.

+0

Leonid, jesteś rozpalona wykresy w tym tygodniu . # 78 na StackOverflow! –

+0

Pewne nadmiarowe tam; zobacz moją odpowiedź/uwagę. –

+0

@ Mr.Wizard Wow, nie spodziewałem się tego. Dzięki, że dałeś mi znać! Ale zapomniałeś o @belisarius i @yoda, są one wyższe na tej liście. –

5

Tylko dlatego, że jestem trochę Loon, rozwiązanie Leonid można zapisać jako:

a = {0, 1}~Tuples~3~SortBy~Tr // Rest; 

MapThread[ 
    (oldtable[[Sequence @@ #]] = oldtable[[Sequence @@ #2]]) &, 
    {-a, a} /. 0 -> All 
]; 
+0

+1, mniej ogólnego pisania, więc łatwiej jest przedłużyć. Gdybym mógł, dałbym jeszcze +1 za podwójną konstrukcję "a". – rcollyer

+0

Pewne nadmiarowe tam; zobacz moją odpowiedź/uwagę. –

+0

+1. Chciałem pokazać najbliższą współzależność oryginalnemu rozwiązaniu opartemu na pętli, ponieważ jest to łatwiejsze do zrozumienia. Miałem na myśli dodanie czegoś bardzo podobnego do tego, co zrobiłeś, ale było już za późno :). Podwójna infiks naprawdę jest naprawdę dobra! Ale teraz jesteś odpowiedzialny za wyjaśnienie, jak to działa :). –

9

Zarówno Leonid i odpowiedzi Mr.Wizard jest zbyt wiele pracy. W przypadku Leonida potrzebne są tylko pierwsze trzy linie. Aby to pokazać, będę zmieniać ostatnie 4 Set s do Equal s:

In[65]:= len = 4; oldtable = 
Partition[Partition[Range[len^3], len], len] 

Out[65]= {{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 
    16}}, {{17, 18, 19, 20}, {21, 22, 23, 24}, {25, 26, 27, 28}, {29, 
    30, 31, 32}}, {{33, 34, 35, 36}, {37, 38, 39, 40}, {41, 42, 43, 
    44}, {45, 46, 47, 48}}, {{49, 50, 51, 52}, {53, 54, 55, 56}, {57, 
    58, 59, 60}, {61, 62, 63, 64}}} 

In[66]:= oldtable[[All, All, -1]] = oldtable[[All, All, 1]]; 
oldtable[[All, -1, All]] = oldtable[[All, 1, All]]; 
oldtable[[-1, All, All]] = oldtable[[1, All, All]]; 
oldtable[[All, -1, -1]] == oldtable[[All, 1, 1]] 
oldtable[[-1, All, -1]] == oldtable[[1, All, 1]] 
oldtable[[-1, -1, All]] == oldtable[[1, 1, All]] 
oldtable[[-1, -1, -1]] == oldtable[[1, 1, 1]] 

Out[69]= True 

Out[70]= True 

Out[71]= True 

Out[72]= True 

Co Leonid przedstawiono na poniższych rysunkach. Linie 4-6 jego kodu robią coś, jak pokazano na panelu po lewej: kopiowanie linii (ciemniejszy kolor) już skopiowanej płaszczyzny (jasne kolory). Linia 7 jest ilustrowana przez prawy panel. Jest to kopia komórki na komórkę przeciwnych pozycji po przekątnej, a jej działanie nie jest uwzględnione w żadnej z pierwszych trzech akcji kopiowania osobno, ale jest wynikiem ich kolejnego działania.

enter image description here

+0

Dzięki za ilustrację. Rozumiem twój punkt widzenia i zgadzam się z tobą. Sposób, w jaki Leonid kopiuje, pozostaje z pierwotnego pytania, w którym tworzyłem nadmiarową kopię tabeli, aby zwiększyć rozmiar o 1. Pozbycie się redundantnej tabeli pośredniej już zaoszczędziło mi wystarczającej ilości pamięci/czasu. – Hsn

+2

@Sjoerd +1 dla miłej i wizualnej analizy. –

+0

+1 za podłączenie flagi: – abcd