How would you implement the following in Matlab without loops: $$ \Sigma = \frac{1}{m}\sum_{i=1}^{m}(\mathbf x_i - \mu_{yi})(\mathbf x_i - \mu_{yi})^T $$ Where $\mathbf x \in \mathbb{R}^{m\times n}$ is your input matrix, $\mathbf y \in \{0,1\}$ is your label column vector. Additionally, you need to have already calculated parameters $\mu_0$ and $\mu_1$ which are the means of $\mathbf x$ for samples of class 0 and 1 (according to vector $\mathbf y$). The tricky part is $\mu_{yi}$. In the equation, you cannot simply multiply the input with its mean, since $\mu_{yi}$ is a conditional mean. If class of $\mathbf x_i$ is 0, then $\mu_{yi}=\mu_0$, otherwise $\mu_{yi}=\mu_1$.

How can you do this elegantly in Matlab without loops and checking for $y_i$ at every sample?

  • 2
    $\begingroup$ This is a MATLAB programming question for stackoverflow. $\endgroup$ Oct 25 '16 at 3:02

The two sexy ideas are matrix indexing and bsxfun.

y1_logical = y==1;
u1 = mean(X(y1_logical,:));
u2 = mean(X(~y1_logical,:));

X_demean = zeros(size(X));
X_demean(y1_logical,:)  = bsxfun(@minus, X(y1_logical,:), u1);
X_demean(~y1_logical,:) = bsxfun(@minus, X(~y1_logical,:), u2);

Sigma = X_demean' * X_demean / m;
  • $\begingroup$ FYI: In 2016b, Matlab finally introduced "auto-bsxfun" (a.k.a. "broadcasting"). "In MATLAB® R2016b and later, you can directly use operators instead of bsxfun, since the operators independently support implicit expansion of arrays with compatible sizes." $\endgroup$
    – GeoMatt22
    Oct 25 '16 at 3:29
  • $\begingroup$ @GeoMatt22 Crazy! $\endgroup$ Oct 25 '16 at 3:35
  • $\begingroup$ Good stuff. Thanks! How can I move the question to so? $\endgroup$
    – vega
    Oct 25 '16 at 17:03

Not the answer you're looking for? Browse other questions tagged or ask your own question.