2015-03-25 3 views
0

У меня есть следующий пример (это не работает!)подставляя матрицы на основе условия

a(1, 1:2, 1:2) = [1 2; 3 4]; 
a(2, 1:2, 1:2) = [5 6; 7 8]; 

b=a; 

for i=1:2 
    b(a(i,:,:).*b(i,:,:) < 5.0) = 3*circshift(a(i,:,:), [1 0]); 
end 

Таким образом, идея в том, что все места, где a(i,:,:).*b(i,:,:) меньше, чем пять, b(i,:,:) должны получить значение 3*circshift(a, [1 0]) в этом месте. Это возможно?

Я могу, конечно, сделать это с кучей for -loops, но это не похоже на наиболее оптимальное решение.

ответ

2

Это возможно с помощью следующих действий:

b((a.*b)<5) = [value you want]; 

Прикладной к коду:

a(1, 1:2, 1:2) = [1 2; 3 4]; 
a(2, 1:2, 1:2) = [5 6; 7 8]; 

b=a; 

c = 3*circshift(a((a.*b)<5), [1 0]); % first change a 

b((a.*b)<5) = c((a.*b)<5); % then store c where (a.*b)<5 in b where (a.*b)<5 

Примечание Я использую (a.*b)<5 в a((a.*b)<5). Команда типа x(condition) = value; может использоваться, чтобы сообщить MATLAB, чтобы x был value, где condition является истинным. Это называется логической индексацией.

Такой же эффект может быть достигнут с помощью цикла for, который может быть проще читать для людей, которые знают некоторые языки программирования, но не MATLAB, но for-loops обычно медленнее, чем логическое индексирование. Другой метод будет использовать функцию find, чтобы сначала найти индексы b, где условие (a.*b)<5 истинно, а затем заменяя эти индексы на требуемое значение. Это слишком медленнее, чем логическое индексирование, и ему нужен больше кода.

+0

См. Мое редактирование, я имел в виду 'a (i,:,:). * B (i,:, :)', а не 'b (i,:, :)' ... извините – BillyJean

+0

@BillyJean - Я отредактировал свой ответ, надеюсь, он ответит на ваш вопрос! – Erik

+0

Я верю, что в коде есть ошибка, или вы, возможно, неправильно поняли меня. 'b' должно получить значение' 3 * circshift (a, [1 0]) '* в этом месте * – BillyJean