MATLAB Answers

Compute the product of the next n elements in matrix

28 ビュー (過去 30 日間)
Astrik
Astrik 2016 年 9 月 4 日
コメント済み: John 2018 年 8 月 13 日
I would like to compute the product of the next n adjacent elements of a matrix. The number n of elements to be multiplied should be given in function's input. For example for this input I should compute the product of the 3 consecutive elements, starting from 1.
[product, ind] = max_product([1 2 2 1 3 1],3);
This gives (4,4,6,3).
Is there any practical way to do it? Now I do this using
for ii=1:(length(v)-2)
p=prod(v(ii:ii+n-1));
where v is the input vector and n is the number of elements to be multiplied.
Depending whether n is odd or even or length(v) is odd or even, I get sometimes right answer but sometimes the following error
Index exceeds matrix dimensions.
Error in max_product (line 6)
p=prod(v(ii:ii+n-1));.
Is there any correct general way to do it?
  6 件のコメント
John
John 2018 年 8 月 13 日
Input is a Matrix.

サインインしてコメントする。

回答 (6 件)

Walter Roberson
Walter Roberson 2016 年 9 月 4 日
hint: cumprod divided by cumprod
  4 件のコメント
John D'Errico
John D'Errico 2016 年 9 月 4 日
Of course, if the vector is long with elements that are larger than 1, expect this to overflow and turn the result into inf, then when you divide, you have inf/inf, so nans will result.
Or, if the elements are less than 1, then you will get underflows, which become zero. Then 0/0 is also NaN.
As well, even for some cases where overflow does not result, you may experience some loss of precision in the least significant bits, if the intermediate products exceed 2^53-1.
But for short vectors with reasonable numbers in them, this will work.

サインインしてコメントする。


Matt J
Matt J 2016 年 9 月 4 日
編集済み: Matt J 2016 年 9 月 4 日
function prodout = max_product(A,n)
prodout = exp( conv(log(A),ones(1,n),'valid') );
if isreal(A), prodout=real(prodout); end
end
Just to be clear, this will handle input with zeros and negatives, e.g.,
>> prodout=max_product([0 2 2 1 3 -1], 3)
prodout =
0 4.0000 6.0000 -3.0000
  2 件のコメント
Matt J
Matt J 2016 年 9 月 4 日
Thanks, John, but as far as (1) is concerned, note that I gave an example showing it works with non-positive values as well. As for (2), I think you could modify the code to detect integer input and post-round the result in that case.

サインインしてコメントする。


Andrei Bobrov
Andrei Bobrov 2016 年 9 月 4 日
編集済み: Andrei Bobrov 2016 年 9 月 4 日
[prodout, ind] = max_product(A,n)
ii = 1:numel(A);
ind = hankel(ii(1:n),ii(n:end));
prodout = prod(A(ind));
end
or just
max_product = @(A,n)prod(hankel(A(1:n),A(n:end)));

Steven Lord
Steven Lord 2018 年 2 月 19 日
I believe you want to use the movprod function introduced in release R2017a.

Srishti Saha
Srishti Saha 2018 年 3 月 11 日
This should work. has been tested and refined:
function B = maxproduct(A,n)
% After checking that we do not have to return an empty array, we initialize a row vector % for remembering a product, home row and column, and one of four direction codes.
[r,c] = size(A);
if n>r && n>c
B = []; % cannot be solved
return
end
L = [-Inf,0,0,0]; % [product, home-row, home-col, direction]
for i=1:r
for j=1:c-n+1
L = check(A(i,j:j+n-1),[i,j,1],L); % row, right case
end
end
for i=1:r-n+1
for j=1:c
L = check(A(i:i+n-1,j),[i,j,2],L); % column, down case
end
end
for i=1:r-n+1
for j=1:c-n+1
S=A(i:i+n-1,j:j+n-1);
L = check(diag(S),[i,j,3],L); % diagonal, down case
L = check(diag(flip(S,2)),[i,j,4],L); % reverse diagonal, down case
end
end
i=L(2); j=L(3); % reconstruct coordinates
switch L(4)
case 1, B = [ones(n,1)*i,(j:j+n-1)'];
case 2, B = [(i:i+n-1)',ones(n,1)*j];
case 3, B = [(i:i+n-1)',(j:j+n-1)'];
case 4, B = [(i:i+n-1)',(j+n-1:-1:j)'];
end
end
function L = check(V,d,L)
p = prod(V);
if p>L(1) % if new product larger than any previous
L = [p,d]; % then update product, home and direction
end
end

michio
michio 2016 年 9 月 4 日
In the spirit of avoiding for-loops...
x = 1:10; n = 3 % Example
N = length(x);
index = zeros(N-n+1,n);
index(:,1) = 1:N-n+1';
index(:,2) = index(:,1) + 1;
index(:,3) = index(:,1) + 2;
prod(x(index),2)
  2 件のコメント
michio
michio 2016 年 9 月 4 日
Oops. You are exactly correct. The above script works as intended only when n = 3.

サインインしてコメントする。

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by