[Matlab] Przekształcenia macierzowe

jeth
Użytkownik
Użytkownik
Posty: 41
Rejestracja: 20 mar 2010, o 12:56
Płeć: Mężczyzna
Lokalizacja: Wrocław
Podziękował: 9 razy

[Matlab] Przekształcenia macierzowe

Post autor: jeth »

Witam,

Mam dużą macierz rozmiaru np. 1280x800 = 960 000 elementów z wartościami z przedziału [0,255] jednak ułożonymi w tej macierzy bardzo nieregularnie. Chciałbym zrobić przekształcenie tej macierzy w następujący sposób: 64 najmniejszych wartości w tej macierzy zamienić na 100; kolejnych 64 zamienić na 200; kolejnych 64 zamienić na 300 i tak dalej aż do "wyczerpania" wszystkich elementów macierzy. A więc celem jest zrobienie tak, aby zamienić istniejące wartości na jakieś nowe w sposób jednostajny (tutaj 960 000/64 = 15 000, a więc byłoby 15 000 takich "bloków").

Myślę, że bardziej obrazowo będzie to widać na przykładzie. Załóżmy, że mamy macierz A rozmiaru 3x3 i chcemy zamienić elementy co 3.
\(\displaystyle{ A= \left[
\begin{array}{ccc}
0 & 1 & 2\\
2 & 0 & 2\\
9 & 4 & 7
\end{array}
\right]
\qquad}\)


Zamieniamy pierwsze trzy najmniejsze elementy, czyli 0, 0 i 1 na 100; potem trzy kolejne (2, 2 i 2) zamieniamy na 200 i na końcu zostaje 4, 7 i 9 - zamieniamy na 300. A więc końcowa macierz to \(\displaystyle{ A_{przekszt}= \left[
\begin{array}{ccc}
100 & 100 & 200\\
200 & 100 & 200\\
300 & 300 & 300
\end{array}
\right]
\qquad}\)
.

Nie bardzo mam pomysł, jak się za to zabrać. Gdyby macierz była mała (jak chociażby powyżej w przykładzie), to od biedy można by to rozpisać ręcznie if'ami, ale w przypadku tak dużej macierzy opcja taka zdecydowanie odpada. Funkcja find() wydaje mi się, że też odpada, bo ona wymaga poadania, jakiego konkretnie elementu chcę szukać, a ja tego nie wiem. Czy ktoś ma może jakiś pomysł, jak to ruszyć?

Pozdrawiam
Afish
Moderator
Moderator
Posty: 2828
Rejestracja: 15 cze 2008, o 15:45
Płeć: Mężczyzna
Lokalizacja: Seattle, WA
Podziękował: 3 razy
Pomógł: 356 razy

[Matlab] Przekształcenia macierzowe

Post autor: Afish »

Tworzysz macierz pomocniczą, w której każdy element będzie oznaczał ranking elementu z oryginalnej macierzy. Potem tylko przelatujesz i podmieniasz.

Do stworzenia macierzy z rankingami możesz użyć na przykład naiwnych zagnieżdżonych pętli, sortowania, drzew BST.
jeth
Użytkownik
Użytkownik
Posty: 41
Rejestracja: 20 mar 2010, o 12:56
Płeć: Mężczyzna
Lokalizacja: Wrocław
Podziękował: 9 razy

[Matlab] Przekształcenia macierzowe

Post autor: jeth »

Bardzo dziękuję, propozycja przybliżyła mnie do rozwiązania, ale tym razem na przeszkodzie stanęły skromne umiejętności programistyczne... ;) Chyba najłatwiejszy do realizacji jest pomysł z sortowaniem i indeksami elementów.

Kod: Zaznacz cały

A = [23 1 90 6 6 89; 4 0 11 11 3 90; 29 4 5 10 4 21; 58 29 4 12 12 111]

target = 100:100:900;

[Y,I] = sort(A) 
c = size(A); 
d = length(target);

for i=1:c(1)
    for j=1:c(2)
        for k=1:d
            if I(i,j) == k
                A(i,j) = target(k);
            end           
        end
    end
end

disp('Macierz po transformacji: '); disp(A);

Mamy prostokątną macierz A:
\(\displaystyle{ A= \left[
\begin{array}{cccccc}
23&1&90&6&6&89\\
4&0&11&11&3&90\\
29&4&5&10&4&21\\
58&29&4&12&12&111

\end{array}
\right]
\qquad}\)

oraz wektor target z wartościami, które będziemy podmieniać w macierzy A. Chodzi o to, aby podmienić wartości z danego indeksu, czyli np. w macierzy jest 6 elementów z indeksem 1 - podmieniamy je na 100 itd. Problem jednak w tym, że Matlab zwraca te indeksy tylko w odniesieniu do danej kolumny, a nie całej macierzy:

Macierz indeksów:
\(\displaystyle{ I= \left[
\begin{array}{cccccc}
2&2&4&1&2&3\\
1&1&3&3&3&1\\
3&3&2&2&1&2\\
4&4&1&4&4&4

\end{array}
\right]
\qquad}\)

Czyli np. element A(2,6) = 90 otrzymał indeks 1, podczas gdy A(1,2) = 1 ma już indeks 2.

Macierz po przekształceniu wygląda następująco:

\(\displaystyle{ A_{trans}= \left[
\begin{array}{cccccc}
200&200&400&100&200&300\\
100&100&300&300&300&100\\
300&300&200&200&100&200\\
400&400&100&400&400&400

\end{array}
\right]
\qquad}\)


Czy da się zrobić, żeby indeksy ponumerować nie tylko dla kolumn, ale dla całej macierzy?

PS. Pomińmy na razie kwestię złożoności :)
Afish
Moderator
Moderator
Posty: 2828
Rejestracja: 15 cze 2008, o 15:45
Płeć: Mężczyzna
Lokalizacja: Seattle, WA
Podziękował: 3 razy
Pomógł: 356 razy

[Matlab] Przekształcenia macierzowe

Post autor: Afish »

Zamień macierz w wektor, przesortuj i podmień, potem zamień w macierz.

Kod: Zaznacz cały

https://nl.mathworks.com/matlabcentral/
... gle-column

Kod: Zaznacz cały

https://nl.mathworks.com/help/matlab/ref/reshape.html
jeth
Użytkownik
Użytkownik
Posty: 41
Rejestracja: 20 mar 2010, o 12:56
Płeć: Mężczyzna
Lokalizacja: Wrocław
Podziękował: 9 razy

[Matlab] Przekształcenia macierzowe

Post autor: jeth »

Dziękuję, na takie rozwiązanie chyba bym nie wpadł
ODPOWIEDZ