Compute the product of the next n elements in matrix
Mostrar comentarios más antiguos
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 comentarios
mallavarapu hema saikumar
el 18 de Feb. de 2018
the below will work for sure
function [p,index]=max_product(v,n)
a=length(v);
if(n>a)
p=0;
index=-1;
else
x=[];
for i=1:a-n+1
x(:,i)=prod(v(i:1:i+n-1))
end
p=max(x);
a=(x==p);
n=0;
for k=1:length(a)
if(a(k)==1)
in=k;
break;
end
end
index=in;
end
Auvishek Modak Utsha
el 19 de Feb. de 2018
it shows this when I run it: Feedback: Your function made an error for argument(s) [1 2;3 4], 1
Your solution is _not_ correct.
mallavarapu hema saikumar
el 19 de Feb. de 2018
Editada: mallavarapu hema saikumar
el 19 de Feb. de 2018
In the question itself it was mentioned that input is a vector(either row or column) then how can u give matrix as an input Utsha
Srishti Saha
el 11 de Mzo. de 2018
@ mallavarapu hema saikumar: I think this is an emulator that feeds inputs on its own and tests the code. I don't think Utsha has entered the input here
Srishti Saha
el 11 de Mzo. de 2018
have posted an answer to the question that I used to complete my homework
John
el 13 de Ag. de 2018
Input is a Matrix.
Respuestas (6)
Walter Roberson
el 4 de Sept. de 2016
2 votos
hint: cumprod divided by cumprod
4 comentarios
michio
el 4 de Sept. de 2016
Wow, that's a good one.
Astrik
el 4 de Sept. de 2016
Walter Roberson
el 4 de Sept. de 2016
Consider, for example, X * (X-1) * (X-2) * ... (X-N) for X a positive integer. That can be written as X! / (X-N-1)! which is prod(1:X) / prod(1:X-N-1) . Now if you wanted to vectorize this, to do a "sliding window", you could use cumprod() on the top and bottom, with appropriate sub-array extraction to get the right lengths.
You are not doing factorial, but what happens if you use a vector of values instead of 1:X ?
John D'Errico
el 4 de Sept. de 2016
Editada: John D'Errico
el 4 de Sept. de 2016
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.
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 comentarios
John D'Errico
el 4 de Sept. de 2016
Drat. :) I was going to answer this with the log and conv solution. That is of course, the correct solution (and the one I was going to offer) as long as...
1. The elements are strictly positive. zero or negative values will cause problems with those logs.
2. You don't need an exact product of integers, since logs and exponents will yield subtle errors in the least significant bits.
+1 anyway, since this was going to be my solution.
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
el 4 de Sept. de 2016
Editada: Andrei Bobrov
el 4 de Sept. de 2016
[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
el 19 de Feb. de 2018
1 voto
Srishti Saha
el 11 de Mzo. de 2018
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
el 4 de Sept. de 2016
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 comentarios
Walter Roberson
el 4 de Sept. de 2016
You created index as extending to n columns but only fill 3 of the columns. You would need to fill the rest of the columns and that is probably going to need a for loop.
michio
el 4 de Sept. de 2016
Oops. You are exactly correct. The above script works as intended only when n = 3.
Categorías
Más información sobre Matrix Indexing en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!