2014-01-30 3 views
1

У меня есть вектор A = [2 3 1] и матрицуЛогическая индексация с использованием вектора

B = [0 1 2; 
    3 4 5; 
    6 7 8]; 

Я хотел бы, чтобы иметь возможность суммировать значения в B с использованием элементов в качестве логических индексаторов (начало и конечное значение). Более конкретно, я хочу, чтобы мой код, чтобы выполнить эти действия:

sum(B(1:1,1), sum(B(1:2,2), sum(B(1:3,3)), чтобы получить конечный вектор С такой, что

C = [3 12 2] 

у меня есть большое количество данных, так что я бы чтобы избежать использования для циклов, поскольку они, похоже, значительно замедляют работу кода.

Заранее благодарен,

+0

Как вы получаете эти значения ИНГ для 'C'? – horchler

+0

@horchler: Мой ответ подходит, я думаю, что это то, что происходит после OP. Я думаю, что ваш ответ (в целом) лучше моего, поэтому я удалю его, если вы обновите свой. =) (Предполагая, что я прав) –

+0

@RobertP .: Пожалуйста, если хотите. Разве это то, что ОП изменил два индекса? Я просто пытаюсь получить '3' из' sum (B (1: 2,2)) '. – horchler

ответ

1

Я думаю, что это то, что вы после:

t = arrayfun(@(n)sum(B(1:A(n),n),1),1:numel(A)) 
t = 
    11 15  6 

Для ввода:

A = 
    2  3  1 
B = 
    8  1  6 
    3  5  7 
    4  9  2 

Я предполагаю, что вы хотите, чтобы номера столбцов увеличивались, а число строк может отличаться.

2

Во-первых, исправление. A не может использоваться непосредственно для logical indexing, потому что это не вектор логических (булевых) значений. То, что вы имеете в виду, называется linear indexing. Здесь нормальные значения индекса от 1 до числа элементов индексируют массив, как если бы он был вектором.

Вот один из способов вы можете решить вашу проблему, если A на самом деле 1:size(B,1):

B = [0 1 2;3 4 5;6 7 8]; 
C = sum(triu(B),1) 

Для более общем случае for петля может быть довольно быстро при условии, что вы правильно предварительно выделить. Но вы также можете использовать arrayfun, который является только for петлей в маскировке (и даже медленнее, во многих случаях):

A = [2 3 1]; 
B = [0 1 2;3 4 5;6 7 8]; 
C = arrayfun(@(x)sum(B(1:x,x)),A) 

Ничего из этого не использует линейную индексацию, потому что ваши A значений описывают, как индекс в оба ряды и столбцы B. Можно использовать sub2ind легко преобразовать в линейные индексы, но это может быть громоздким в использовании, например:

A = [2 3 1]; 
B = [0 1 2;3 4 5;6 7 8]; 
C = arrayfun(@(x)sum(B(sub2ind(size(B),1:x,x+zeros(1,x)))),A) 
+0

Большое спасибо за быстрый ответ. Я не упомянул, что значения в A не обязательно растут. Например, A может быть [3 1 2] или [2 3 1]. – Souf

+1

@ user3254790: Тогда не ваш пример не так? Кажется, что ваш вывод для 'A = [1 2 3]', а не '[2 3 1]', как вы используете в качестве входных данных. Можете ли вы обновить (если я не ошибаюсь)? –

+0

Yup, извините за то. – Souf

2

Альтернативный ответ, который использует bsxfun создать маску для значений, которые будут подведены:

C = sum(B.*bsxfun(@le, (1:size(B,1)), A(:)).'); 
1
C=cumsum(B); 
    C=C(sub2ind(size(B),A,1:size(B,1)) ), 
Смежные вопросы