1

I am quite novice to MATLAB and I am struggling to find a solution to this equation.

enter image description here

Where the matrices' dimensions are {λ} = N×K, {Y} = N×D, {π} = 1×K, and {μ} = D×K.

What I have created looks more like a monstrosity than an efficient MATLAB code, and that is due to a serious lack of MATLAB skills.

Actually, I decided to solve this step by step, in order to get myself familiarised with how MATLAB works. I ended up with an ultra inefficient code that I cannot even combine it. Even the final result is wrong, as I want to create a NxK matrix. Any guidance would be much appreciated.

%Dimensions:
nn = 10;
dd = 7;
kk = 5;

%Initial variables:
lambda0 = rand(nn,kk);
sigma = rand(1);
Y = rand(nn,dd);
mu = rand(dd,kk);

%Calculate pies:
First_part = log(pie(:)./(1.-pie(:))); % Kx1 vector

%Calculate Second part:
for n = 1:nn
for d = 1:dd
lambda_mu(d,:) = lambda0(n,:).*mu(d,:); %lambdamu is a DxK matrix
end
lambda_mu2(n,:) = sum(lambda_mu,2); %This is a NXD matrix
end

%Y-lambdamu2:
for n = 1:nn
YY(n,:) = Y(n,:)-lambda_mu2(n,:); % This is a NxD vector
end

%YY*mu:
Second = (YY*mu)./sigma^2; % NxK

%Third:
Third = (mu'*mu)./2*sigma^2; % KxK

%Final:
for n=1:nn
Final_part = transpose(First_part(:))+Second(n,:)-Third;
end

Update1: Ok, I owe myself a beer. So, I made some progress to create a {λ} = N×K matrix by modifying my code as follows:

Update[2]: Spending too much time programming and you miss details. I fixed the error as I had set {Y} = D×K, instead of {Y} = D×N.

%Dimensions:
nn = 10;
dd = 7;
kk = 5;

%Initial variables:
lambda0 = rand(nn,kk);
sigma = rand(1);
Y = rand(dd,nn);
mu = rand(dd,kk);
pie = rand(1,kk);
sigma = rand(1);

%Calculate the equation.
for n = 1:nn
for k = 1:kk
    lambda(n,k) = log(pie(k)/(1-pie(k))) + (transpose(Y(:,n)-... 
        (sum(lambda0(n,1:end ~= k).*mu(:,1:end ~= k),2)))*mu(:,k))/...
        sigma^2 - transpose(mu(:,k))*mu(:,k)/2*sigma^2;
end
end

But, now the problem is that it goes only up to n=5, when I try to loop for n=6 for example I get this message: "Index exceeds matrix dimensions", so practically I only get a 5×5 matrix. Suggestions please?

P.S: I even tried to change the lambda from lambda(n,k) to lambda(k,n) but yet the result is the same.

Jespar
  • 1,017
  • 5
  • 16
  • 29
  • Thanks for a well-posed question, I don't understand why someone downvoted it -- undeserved. Unfortunately, I'm not currently able to help, but hang in there, someone will come. – Rody Oldenhuis Dec 08 '16 at 08:25
  • 1
    Are you sure about the dimensions you have specified? It doesn't seem to make a lot of sense like this to me. Can you give some source as to what the equation is? I'd like to help, but what's going on in the background is a bit of a mystery to me without some background. – Franz Hahn Dec 08 '16 at 11:18
  • Hey @RodyOldenhuis thanks for the edit! – Jespar Dec 08 '16 at 11:44
  • @FranzHahn a similar problem can be found here: http://mlg.eng.cam.ac.uk/zoubin/course04/lect7var.pdf (page 9), and the extension I am trying to solve is on page 10 at the very bottom. The dimensions are right but I am struggling mainly because there are matrices with different dimensions that I have to combine within a single calculation. Anyhow, still working on it and I will post my progress. – Jespar Dec 08 '16 at 11:47
  • You cannot add/subtract Kx1, NxK and KxK parts. That does neither make sense in Matlab nor in maths (or am I missing something). – Solstad Dec 08 '16 at 13:03
  • As I read the equation, λ_i^(n) is a scalar, so **λ^(n)** is a vector. `First_part` is `log` of something (therefore scalar). Thus (from `Third_part`) **µ_i** must be Kx1; and (from `Second_part`) **y^(n)** is Kx1 as well. – Solstad Dec 08 '16 at 13:09
  • @Solstad That's why I feel so confused. Actually, it's not λ_i^n; λ is a matrix with dimensions N×K with n rows and i columns. If you check the link that I posted to Franz you will see the original equation at page 9, but I am trying to figure out how to solve the equation on bottom of page 10 (E-step to find λ). – Jespar Dec 08 '16 at 13:26
  • I did check the link, but the slides do not add much more info. But I think, I get the idea. The eq. describes each element in **λ**, so e.g. `First_part` needs to be multiplied by `ones(1,kk)`. – Solstad Dec 08 '16 at 13:46
  • @Solstad hahaha tell me about it. I know, the slides are not perfect and I'm trying to figure out a solution. You know, as the final λ should have the form of a N×K matrix I am thinking, instead of keeping n fixed and loop though K's to do the opposite and see if it works. The fact that you have to compute matrices that they have also D dimensions do not make it any easier. I will try to implement a solution for the equation at page 9, the "the simple" one, and then move to higher dimensions. – Jespar Dec 08 '16 at 13:49
  • And `ones(nn,kk)` needs to be multiplied with `Third_part` and the new KxK `First_part`. Thus giving NxK matrices to add/subtract. – Solstad Dec 08 '16 at 13:50

1 Answers1

0

In order to get dimensions working, multiply by ones(nn,kk) and ones(1,kk)

nn = 10;
dd = 7;
kk = 5;

%Initial variables:
lambda0 = rand(nn,kk);
sigma = rand(1);
Y = rand(nn,dd);
mu = rand(dd,kk);
pie = rand(kk,1);

%Calculate pies:
First_part = ones(nn,kk)*log(pie./(1.-pie))*ones(1,kk); % Kx1 vector

%Calculate Second part:
for n = 1:nn
    for d = 1:dd
        lambda_mu(d,:) = lambda0(n,:).*mu(d,:); %lambdamu is a DxK matrix
    end
    lambda_mu2(n,:) = sum(lambda_mu,2); %This is a NXD matrix
end

%Y-lambdamu2:
for n = 1:nn
    YY(n,:) = Y(n,:)-lambda_mu2(n,:); % This is a NxD vector
end

%YY*mu:
Second_part = (YY*mu)./sigma^2; % NxK

%Third:
Third_part = ones(nn,kk)*(mu'*mu)./2*sigma^2; % KxK


%Final:
for n=1:nn
    Final_part(n,:) = First_part(n,:)+Second_part(n,:)-Third_part(n,:);
end

EDIT: I was thinking more like:

%Initial variables:
lambda = rand(nn,kk);
sigma = rand(1);
y = rand(nn,1);
mu = rand(nn,kk);
pie = rand(1,kk);

%Calculate pies:
First_part = ones(nn,1)*log(pie./(1-pie)); % NxK vector

to avoid loops.

Maybe use something like:

ones(kk)-diag([ones(kk,1)])

when doing the sum over i not equal to j, or rather use a third dimension to represent j.

Solstad
  • 285
  • 1
  • 9
  • I just noted, that something is wrong with `lambda0(n,:).*mu(d,:); %lambdamu is a DxK matrix`. You elementwise multiply NxK with DxK matrices. – Solstad Dec 08 '16 at 14:24
  • Can you explain what the D (`dd`) dimension is in the equation? – Solstad Dec 08 '16 at 14:29
  • I would rewrite it all, more systematically with `n` being the first dimension, `i` being the second, and `j` being the third, consistently. Furthermore I would do matrix algebra rather than looping (to improve the performance of the code). – Solstad Dec 08 '16 at 14:33
  • Thanks @Solstad, after an inefficiently high volume of try & errors I managed to create the code with as less lines as possible. Please check it out and let me know your opinion. – Jespar Dec 08 '16 at 19:38
  • Now you only do looping, so it might not be as efficient, but is probably easier to check. Do you know whether you get the right answer or not? – Solstad Dec 13 '16 at 13:53