3

Suppose that "r" is a multidimensional array of size [N, N, M] and "tab" is a table of size [N] with values 1..N (e.g. take "tab=randperm(N)"). I'm looking for efficient way to do the following:

    c = ones(M, 1);
    for k=1:N
        c = c .* squeeze(r(tab(k),k,:));
    end

I'd like to do that in matrix notation, using prod, but didn't find a solution, as "r(tab(1:N),1:N,:)" returns an NxNxM matrix rather than N rows.

Any suggestions?

3
  • @DanielR: From question text: "and tab is a table of size [N] with values 1..N" Commented Jan 15, 2014 at 10:44
  • @RobertP. is correct; e.g. take "tab=randperm(N)" Commented Jan 15, 2014 at 10:55
  • @UriCohen: First reading, I expected some data of class table, which was recently introduced to matlab. Commented Jan 15, 2014 at 11:08

2 Answers 2

1

Use sub2ind across dimensions 1, 2; bsxfun to replicate along dimension 3; and then prod:

c = prod(r(bsxfun(@plus, sub2ind([N N], tab, 1:N).', (0:M-1)*N^2))).';
Sign up to request clarification or add additional context in comments.

2 Comments

I don't quite understand the syntax: is the ".'" a valid syntax?
You could remove that final .' if you don't mind obtaining a row vector instead of a line vector
0
%% example data
M=3;
N=4;
r=rand(N,N,M);
tab=randperm(N);

%% original code    

c = ones(M, 1);
for k=1:N
    c = c .* squeeze(r(tab(k),k,:));
end

%% Code is equivalent to:

% rh=r(tab,:,:);
% c2 = ones(M, 1);
% for k=1:N
%     c2 = c2 .* squeeze(rh(k,k,:));
% end
% assert(all(c2==c));

%% second solution: Use sub2ind to index
rh=r(tab,:,:);

ix=sub2ind(size(rh),ceil(1/M:1/M:N),ceil(1/M:1/M:N),repmat(1:M,1,N));
rh2=rh(ix);
rh3=reshape(rh2,M,N);
c3=prod(rh3,2);
assert(all(c3==c));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.