MATLAB Answers

Normally distributed random numbers with fixed sum

11 views (last 30 days)
Richard Ott
Richard Ott on 26 Jul 2021
Commented: Matt J on 27 Jul 2021
Hi everybody,
I am looking for a way to create normally distributed numbers with a fixed sum.
I know the random fixed sum numer generator from FileExchange https://de.mathworks.com/matlabcentral/fileexchange/9700-random-vectors-with-fixed-sum.
However, I wasn't able to easily adjust it to my needs.
Basically, I want the same as randfixedsum with the addition that the function recevies values for mu and sigma as a vector of length n. I understand that using different standard deviations for n-different values will lead to unequal pairwise corrrelations between the generated values, but that's ok.
I understand it's maybe not a trivial problem. Any ideas?
Thanks
  1 Comment
Jeff Miller
Jeff Miller on 27 Jul 2021
Just a comment that this isn't possible in general. With two X's, for example, you can't let them both have mu=0 yet have them produce a fixed sum of 1. Likewise, you can't let them have different sigmas if they produce a fixed sum--in that case they must have equal sigmas as well as a perfect negative correlation. With larger numbers of X's the constraints are more complicated, but I would guess that there are a lot more sets of impossible mus & sigmas than of possible ones.

Sign in to comment.

Answers (2)

Matt J
Matt J on 26 Jul 2021
Edited: Matt J on 26 Jul 2021
Why not simply,
x(1:N-1)=randn(1,N-1);
x(N)=fixedValue-sum(x(1:N-1))
  2 Comments
Matt J
Matt J on 27 Jul 2021
It's not so much a gaussian distribution with a fixed sum so much as it is a gaussian distribution with an another number in the same vector that offsets the sum.
I don't really see the distinction. It is clearly a Gaussian random vector and the sum is unvarying, as the test below shows
N = 10000;
fixedValue = 50;
for i=1:4
x(1:N-1)=randn(1,N-1);
x(N)=fixedValue-sum(x(1:N-1));
s=sum(x)
end
s = 50
s = 50
s = 50
s = 50

Sign in to comment.


Richard Ott
Richard Ott on 27 Jul 2021
I tried this approach below that I translated from a post I found in an R forum
It seems to be doing what I want, but I can't figure out how the covariance matrix was determined from the variances... Any ideas? I wanted to try corr2cov but don't have the financial toolbox.
mu = [10,20,30,40];
variances = [2,3,5,6];
% somehow the user uses these variances to built the following covariance
% matrix
sigma =[3.7838,-0.4865,-1.3514,-1.9459...
;-0.4865,7.9054,-3.0405,-4.3784...
;-1.3514,-3.0405,16.5541,-12.1622;...
-1.9459,-4.3784,-12.1622,18.4865];
n = length(mu);
[u,s,v] = svd((sigma + sigma')/2);
s = round(s,2);
m = sum(sum(s > 0));
% Generate normals in the lower dimension
nsample = 1e3;
x = normrnd(0,1,m,nsample);
% Embed in the higher dimension and apply square root
% of sigma obtained from its SVD
x = [x; zeros(1,nsample)];
xmu = nan(length(mu),nsample);
for i = 1:nsample
xmu(:,i) = x(:,i) + mu';
end
y = u * sqrt(s) * x;
for i = 1:nsample
y(:,i) = y(:,i) + mu';
end
sum(y(:,1))
histogram(y(1,:))
hold on
histogram(y(2,:))
histogram(y(3,:))
histogram(y(4,:))

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by