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

[p, ind] = max_product([1 2 2 1 3 1],3);

Это дает [1*2*2, 2*2*1, 2*1*3, 1*3*1] = [4,4,6,3].

Есть ли какой-нибудь практический способ это сделать? Теперь я использую:

for ii = 1:(length(v)-2)
    p = prod(v(ii:ii+n-1));
end

Где v - входной вектор, а n - количество элементов, которые нужно перемножить.

В этом примере n=3, но может принимать любое положительное целочисленное значение.

В зависимости от того, является ли n нечетным или четным или length(v) нечетным или четным, я иногда получаю правильные ответы, а иногда - ошибку.
Например, для аргументов:

v = [1.35912281237829 -0.958120385352704 -0.553335935098461 1.44601450110386 1.43760259196739 0.0266423803393867 0.417039432979809 1.14033971399183 -0.418125096873537 -1.99362640306847 -0.589833539347417 -0.218969651537063 1.49863539349242 0.338844452879616 1.34169199365703 0.181185490389383 0.102817336496793 0.104835620599133 -2.70026800170358 1.46129128974515 0.64413523430416 0.921962619821458 0.568712984110933] 
n = 7

Я получаю сообщение об ошибке:

Index exceeds matrix dimensions.
Error in max_product (line 6)  
p = prod(v(ii:ii+n-1));

Есть ли какой-нибудь правильный общий способ сделать это?

4
esem 4 Сен 2016 в 17:21

4 ответа

Ваш подход правильный. Вам просто нужно изменить цикл for на for ii = 1:(length(v)-n+1), и тогда он будет работать нормально.

Если вы не собираетесь иметь дело с большими объемами ввода, другой подход заключается в использовании gallery, как описано в ответе @ thewaywewalk .

2
Community 23 Май 2017 в 12:00

Думаю, проблема может быть связана с вашей индексацией. Строка, в которой указано for ii = 1:(length(v)-2), не обеспечивает правильный диапазон ii.

Попробуй это:

function out = max_product(in,size)
    size = size-1;                 % this is because we add size to i later
    out = zeros(length(in),1)      % assuming that this is a column vector
    for i = 1:length(in)-size
        out(i) = prod(in(i:i+size));
    end

Ваш код работает, если переформулировать так:

for ii = 1:(length(v)-(n-1))
    p = prod(v(ii:ii+(n-1)));
end

Это должно решить проблему индексации.

2
Adriaan 15 Сен 2016 в 12:27

Используя bsxfun, вы создаете матрицу, каждая строка которой содержит 3 последовательных элемента, а затем берется значение 2-го измерения матрицы. Думаю, это наиболее эффективный способ:

max_product = @(v, n) prod(v(bsxfun(@plus, (1 : n), (0 : numel(v)-n)')), 2);
p = max_product([1 2 2 1 3 1],3)

Обновить: обновлены некоторые другие решения, а некоторые, такие как ответ @ Dev-iL, превосходят другие, я могу предложить fftconv, что в Octave превосходит conv

1
rahnema1 6 Сен 2016 в 21:53

Если вы можете выполнить обновление до R2017a, вы можете использовать новую функцию movprod для вычисления оконного продукта.

1
CKT 9 Мар 2017 в 16:02