# Generating 2D different shapes with same mean and covariance matrix

Im trying to reproduce the synthetic data used in this article.

The authors claim the data was generated from densities with the same mean and covariance matrix.

Is there any principled way I to generate such data in matlab? I know the functions to generate random values but I don't know how to make "good guesses" on the covariance matrix to generate this kind of dataset. It's important for me that I keep the same mean and covariance matrix across the examples.

• What do you suppose the covariance matrix of the left hand plot to be? By definition, it will be the same as that of the other three plots, too.
– whuber
Jun 30, 2015 at 21:01
• The covariance is stated above ("identity matrix"), are you asking how to estimate covariance from data? Jul 1, 2015 at 2:40

## 1 Answer

If you can generate data roughly in the shape you want, you can impose your own mean and covariance to match the ones you have in the first sample. This should be similar in any software. Here's an example using MATLAB code to generate data in the shape of an 8 and to give it the desired mean and covariance.

First generate two noisy circles, one on top of the other, not worrying about their means or covariances

% Generate Figure 8
theta = linspace(0,2*pi)';
x1 = [sin(theta),cos(theta)] + randn(length(theta),2)/20;
x2 = [sin(theta),cos(theta)] + randn(length(theta),2)/20;
x1(:,2) = x1(:,2)+1;     % top of figure 8
x2(:,2) = -x2(:,2)-1;    % bottom of figure 8
x = [x1;x2];
subplot(1,2,1)
plot(x(:,1),x(:,2),'b.')


Now standardize. First subtract the column means from X using bsxfun to get Y. Next remove the covariance. Suppose the covariance of Y is $C=cov(Y)$ and it has cholesky factor A, $C=A'A$. Then the covariance of $Z=YA^{-1}$ (written Y/A) is $cov(Z)=A'^{-1}(A'A)A^{-1}=I$, the identity.

% Remove existing mean and covariance
y = bsxfun(@minus,x,mean(x));
z = y / chol(cov(y));


So if I want mean 0 and covariance I, I'm done. But suppose I generated the first set of points and found they have some particular mean M and covariance C, such as

% Mean and covariance I want
M = [9 12];
C = [20 5;5 10];


I can modify my generated points to have the same mean and covariance

% Impose these
y = z*chol(C)            % if A=chol(C), cov(y)=A'*A=C
x = bsxfun(@plus,M,y);   % add column means M to columns of y
mean(x)
cov(x)
subplot(1,2,2)
plot(x(:,1),x(:,2),'r.')


The resulting figure has points roughly in the same of a figure 8, but slanted somewhat to match the desired covariance.

• Could you please explain what you mean by "impose" a mean and covariance? What exactly would that be doing to the data?
– whuber
Jun 30, 2015 at 22:33
• I'm thinking you get the mean and covariance of the blob of points in the first sample, then force the other samples to have the same mean and covariance. If you want zero mean and identity covariance, as in this case, that's a no-op. These of course would be exact sample means and covariances, not random samples from population means and covariances. Jul 1, 2015 at 13:57
• Thanks Tom. What I am looking for is an explanation of what your code does: how does it "force" the other samples to match the first two moments? (There are many ways to accomplish this, some of which will work better than others.) Your non-Matlab readers (who will be in the great majority) will have no idea about your method because it seems to be buried in the workings of the obscurely named bsxfun.
– whuber
Jul 1, 2015 at 13:59
• I tried to clarify by editing the original. Jul 2, 2015 at 18:36