2014-01-15 3 views
3

Привет У меня есть 4x4 двойной матрицаКак классифицировать значения в группы (по их квадрантам в комплексной плоскости)?

1+2i 2-1i -3-2i -1+4i 

3-1i -3+2i 1-3i -1-3i 

4+3i 3+5i 1-2i -1-4i 

4+2i -5-2i 2+3i 2-1i 

Как я сгруппировать их в отдельные группы в 1 + 1i, 1-1i, -1 + 1i, -1-1i категория в MATLAB?

E.g. 1 + 1i группа: 1 + 2i, 4 + 3i, 3 + 5i, 4 + 2i, 2 + 3i 1-1i группа: 2-1i, 3-1i, 1-3i, 1-2i, 2-1i -1 + 1i группа: 1 + 4i, -3 + 2i -1-1i группа: -3-2i, -1-3i, -1-4i, -5-2i

ответ

4

насчет:

% example matrix 
Z = [ 1+2i 2-1i -3-2i -1+4i ; 
     3-1i -3+2i 1-3i -1-3i ; 
     4+3i 3+5i 1-2i -1-4i ; 
     4+2i -5-2i 2+3i 2-1i ] 

перебором подход, если вы не заботитесь о порядке групп:

classification = ceil(angle(Z)*4/(2*pi)) + 2 

quadrant1 = Z(classification == 3) 
quadrant2 = Z(classification == 4) 
quadrant3 = Z(classification == 1) 
quadrant4 = Z(classification == 2) 

изменить порядок по желанию. Конечно, вы также можете использовать loop/cellfun снизу.


Или с автоматическим порядке:

Имейте в виду, что я выбрал значимый заказ в соответствии с гауссовой комплексной плоскости, так как один предложенный вами не имеет смысла с точки зрения математики/phyisics.

classification = ceil(angle(Z)*4/(2*pi)); 
classification(classification < 1) = classification(classification < 1) + 4; 
for ii = 1:4; 
    quadrant{ii,:} = Z(classification == ii); 
end 

или заменить петлю с:

quadrant = cellfun(@(x) Z(classification == x), num2cell(1:4),'Uni',0)' 

возвращает массив ячеек с 4-х клеток, по одному для каждого квадранта в правильном порядке, содержащей все в соответствии с комплексными числами:

>> quadrant{:} 

ans = 

    1.0000 + 2.0000i 
    4.0000 + 3.0000i 
    4.0000 + 2.0000i 
    3.0000 + 5.0000i 
    2.0000 + 3.0000i 


ans = 

    -3.0000 + 2.0000i 
    -1.0000 + 4.0000i 


ans = 

    -5.0000 - 2.0000i 
    -3.0000 - 2.0000i 
    -1.0000 - 3.0000i 
    -1.0000 - 4.0000i 


ans = 

    3.0000 - 1.0000i 
    2.0000 - 1.0000i 
    1.0000 - 3.0000i 
    1.0000 - 2.0000i 
    2.0000 - 1.0000i 

Don't punch me Rody - но тогда я бы предпочел написать его следующим образом:

Im = imag(Z) >= 0; 
Re = real(Z) >= 0; 

quadrant = { 
    Z( Re & Im) 
    Z(~Re & Im) 
    Z(~Re & ~Im) 
    Z( Re & ~Im) 
}; 

... потому что я намеревался избежать всех этих 8 логических сравнений. Это действительно быстрее?

+0

Ну, 'angle' предполагает' atan', а не встроенный. Использование 'cellfun' с анонимной функцией может быть медленным. Вы правы в том, что ваша реализация должна быть еще быстрее :) Но моя нотация ближе к тому, как вы пишете вещи в математическом контексте, улучшая читаемость посредством самодокументации, но преимущества этого можно обсуждать, поскольку они более вопрос вкуса. –

+0

@RodyOldenhuis Правильно, ваши записи могут быть скопированы из математического формуляра с некоторыми фигурными скобками. : p Дело в том, что вы делаете 8 раз, что мой подход грубой силы (аналогичный вашему) просто выполняет 4 раза, и нет дополнительной операции '&'. Я не знаю, существуют ли различия между операторами '<,>, ==, &' performance wise, но у вас, похоже, гораздо больше реляционных операций. +1 в любом случае для вашего решения, это действительно просто вопрос вкуса;) – thewaywewalk

3

быстрый и интуитивный ИМХО:

Im = imag(Z); 
Re = real(Z); 

quadrant = { 
    Z(Im > 0 & Re > 0) 
    Z(Im > 0 & Re <= 0) 
    Z(Im <= 0 & Re > 0) 
    Z(Im <= 0 & Re <= 0) 
}; 
Смежные вопросы