Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Loop for nested matrix multiplication

Asked by Kevin van Berkel on 27 Apr 2013

Hello guys,

My problem is the following.

I have two matrices: a 155*3 matrix and a 465*3 matrix. I have to multiply each 1x3 row (from the 155*3 matrix) with each consecutive 3x3 matrix from the 465*3 matrix.

Now the loop I tried did not work out and I just can't get my thought's around it.

Here's my code:

m = size(A,2);
n = B(D:E);
D = B(1,:);
E = B(1:3,:); 
C = zeros(m,n);
for ii = 1:m
    for jj = 1:n
         C(ii,jj) = sum(A(ii,:).*B(:,jj).');
    end
end

Where matrix A is the 155*3 matrix and matrix B is the 465*3 matrix.

Any suggestions how to adjust the loop?

Thanks a million.

Kevin

2 Comments

the cyclist on 27 Apr 2013

This code will not get past the line

n = B(D:E)

unless D and E were already define previously. Can you post the entire code?

What do you want the shape of the final output to be? 155*3?

Is this a school assignment?

Kevin van Berkel on 27 Apr 2013

Hi Cyclist,

thank you for your response.

I tried to define D and E as integers but did not work out.

my code looks like this now:

d = [19261103; 20121231];  
ddte = datenum(num2str(d),'yyyymmdd');
ndte = (ddte(1):ddte(2))';
t = weekday(ndte);
ndte = ndte(t ~= 1 & t ~= 7);
yourdata = [date,mkt,hml,mom]; 
[yy,mm,dd] = datevec(yourdata(:,1));
ymd = [yy,mm,dd];
im = mm == 11 & dd >= 3;
ii = strfind([~im(1),im(:)'],[0 1]);
sb = zeros(numel(ndte),1);
sb(ii) = 1;
sbc = cumsum(sb);
t = sbc > 0 & sbc ~= max(sbc);
sbb = sbc(t);
sb1 = find(sb(t));
wdta = yourdata(t,:);
[r, c] = ndgrid(sbb,1:size(wdta,2)-1);
out1 = accumarray([r(:) c(:)],reshape(wdta(:,2:4),[],1),[],@mean);
means = [ymd(ii(1:end-1),:),out1] ;
d = [19261103; 20121231];  
ddte = datenum(num2str(d),'yyyymmdd');
ndte = (ddte(1):ddte(2))';
t = weekday(ndte);
ndte = ndte(t ~= 1 & t ~= 7);
yourdata = [date,mkt,hml,mom];
[yy,mm,dd] = datevec(yourdata(:,1));
ymd = [yy,mm,dd];
im = mm == 11 & dd >= 3;
ii = strfind([~im(1),im(:)'],[0 1]);
sb = zeros(size(yourdata,1),1);
sb(ii) = 1;
sbc = cumsum(sb);
t = sbc > 0 & sbc ~= max(sbc);
sb1 = diff(find([sb(t);1]));
wdta = yourdata(t,:);
s = size(wdta,2) - 1;
ydcell = mat2cell(wdta(:,2:end),sb1,s);
invcov = cellfun(@(x)cov(x)\eye(s),ydcell,'un',0);
*m = size(A,2);
D = B(1,:);
E = B(1:3,:); 
n = B(D:E);
C = zeros(m,n);
for ii = 1:m
  for jj = 1:n
       C(ii,jj) = sum(B(ii,:).*A(:,jj).');
  end
end*

Where the latter part is where I got stuck.

This is no school assignment but I need to determine portfolio weights to do further research. I am quite new to matlab so still have to get familiar with certain parts of it..

Thanks anyway for your help!

The final shape should indeed be 155*3!

Kevin van Berkel

Products

No products are associated with this question.

5 Answers

Answer by Andrei Bobrov on 28 Apr 2013
Accepted answer

eg:

A = randi(4,155,3);
B = randi(8,455,3);% your matrices A and B

one variant;

s = size(A);
C = zeros(s);
for j1 = 1:s(1)
    C(j1,:) = A(j1,:)*B((j1-1)*s(2)+1:j1*s(2),:);
end

other variant

s = size(A);
C = zeros(s);
for j1 = 1:s(1)
    C(j1,:) = B((j1-1)*s(2)+1:j1*s(2),:)*A(j1,:)';
end

0 Comments

Andrei Bobrov
Answer by Matt J on 27 Apr 2013
Edited by Matt J on 27 Apr 2013

Here's a way with very short loops, using my DOWNSAMPN utility below

a=reshape(A.',[],1);
C=bsxfun(@times,a,B);
C=downsampn(C,[3,1]);
function M=downsampn(M,bindims)
%DOWNSAMPN - simple tool for downsampling n-dimensional nonsparse arrays
%
%  M=downsampn(M,bindims)
%
%in:
%
% M: an array
% bindims: a vector of integer binning dimensions
%
%out:
%
% M: the downsized array
nn=length(bindims);
[sz{1:nn}]=size(M); %M is the original array
sz=[sz{:}];
newdims=sz./bindims;
args=num2cell([bindims;newdims]);
M=reshape(M,args{:});
for ii=1:nn
   M=mean(M,2*ii-1);
end
M=reshape(M,newdims);

2 Comments

Matt J on 28 Apr 2013

Kevin van Berkel Commented:

Hello Matt,

Thank you for your response.

I tried your code but Matlab yields some errors. The first error is that the

function M=downsampn(M,bindims) is wrong. Matlab does not know what to do with the "function" part. The next error I get is:

Error using bsxfun Non-singleton dimensions of the two input arrays must match each other.

Error in mult (line 2) C=bsxfun(@times,a,B);.

Do you have any clue how to resolve this?

Cheers.

Matt J on 28 Apr 2013

function M=downsampn(M,bindims) is wrong. Matlab does not know what to do with the "function" part.

You were supposed to put the code for downsampn in its own mfile. If that's not the problem, I need to see copy/pastes of the error messages.

Error using bsxfun Non-singleton dimensions of the two input arrays must match each other.

I don't receive this error. In all likelihood, it means that A is not 155x3 or B is not 465x3 like you posted. Here is the output of WHOS when I run. You should examine your matrix sizes in a similar way.

 >> whos
  Name        Size            Bytes  Class     Attributes
A         155x3              3720  double              
B         465x3             11160  double              
C         155x3              3720  double              
a         465x1              3720  double  
Matt J
Answer by Kevin van Berkel on 28 Apr 2013
Edited by Matt J on 28 Apr 2013

Relocated to Comment by Matt J

0 Comments

Kevin van Berkel
Answer by Kevin van Berkel on 29 Apr 2013

Hello Matt, thanks for your effort but Andrei's solution is more suitable to me.

Andrei, thanks again, got it running perfectly now.

0 Comments

Kevin van Berkel
Answer by Matt J on 29 Apr 2013
Edited by Matt J on 29 Apr 2013

Another loopless way. Note that it would all be much simpler/faster (i.e., no transposes) if the data were organized in columns instead of rows

      Ar=reshape(A.',1,3,[]);
      Br=reshape(B.',3,3,[]);
      Cr=sum(bsxfun(@times,Ar,Br),2);
      C=squeeze(Cr);

One could also use FEX: mtimes for part of the above

   Cr=mtimesx(Ar,Br,'t'); 

0 Comments

Matt J

Contact us