64 Downloads
Updated 24 Jan 2006
No License
Editor's Note: This file was a File Exchange Pick of the Week
This generates m random n-element column vectors of values, [x1;x2;...;xn], each with a fixed sum, s, and subject to a restriction a<=xi<=b. The vectors are randomly and uniformly distributed in the n-1 dimensional space of solutions. This is accomplished by decomposing that space into a number of different types of simplexes (the many-dimensional generalizations of line segments, triangles, and tetrahedra.) The 'rand' function is used to distribute vectors within each simplex uniformly, and further calls on 'rand' serve to select different types of simplexes with probabilities proportional to their respective n-1 dimensional volumes. This algorithm does not perform any rejection of solutions - all are generated so as to already fit within the prescribed hypercube.
Roger Stafford (2020). Random Vectors with Fixed Sum (https://www.mathworks.com/matlabcentral/fileexchange/9700-random-vectors-with-fixed-sum), MATLAB Central File Exchange. Retrieved .
Inspired: portfolio_sortino_ratio
Create scripts with code, output, and formatted text in a single executable document.
L. L. Wong (view profile)
Yu-Hsin Lee (view profile)
SAVED MY DAY
Prasan Srirekam (view profile)
Luis Gualco (view profile)
Mark Kondrla (view profile)
Ido Imanuel (view profile)
Works great, thanks.
Sagnik Mallik (view profile)
How will the distribution change when for each element generated, we consider a certain interval which may not be the same for all?
Niels de Vries (view profile)
nikolaj hansen (view profile)
How do I pick some random numbers in a fixed table or array with a fixed sum?
an example:
array=[1:100];
sum has to be 42 with 5 different numbers
Jake Stroud (view profile)
Beautiful, thank you very much!
Aaron (view profile)
Has anyone written a function like this for a product? Such that A*B*C < some value?
Narayanan Rengaswamy (view profile)
Sultan (view profile)
I want to generate 1x15 dim array v =[v1,...,v15] such that v1+...+v15=1, vi\in [0,1]. The function randfixedsum(n,m,s,a,b) is showing error when I am running [x,v] = randfixedsum(1,15,1,0,1). Following is the error:
Index exceeds matrix dimensions.
Error in randfixedsum (line 95)
x = (b-a)*x(p+repmat([0:n:n*(m-1)],n,1))+a; % Permute & rescale x
tarod13 (view profile)
iryna dovbush (view profile)
I need to adapt this code to generate random positive integers with a fixed sum. I will appreciate any ideas.
Jay Hanuman (view profile)
how to make sum of all element of each row of matrix x will be 1 and all row element has uniform probability i.e. x matrix as follows
0.31 0.34 0.35
0.35 0.32 0.33
0.32 0.36 0.32
so all row has sum 1. how to do it
Will Kinsman (view profile)
Thank you John for truly developing an incredible function for the community. I have so many uses for this and it would have taken me days to make, and I doubt I could have kept it as uniformly random as you have managed to do here.
Beautiful.
Will
Jean-François Fournel (view profile)
Works perfectly.
Jean-François Fournel (view profile)
mohammad (view profile)
Dear John, Thank you for your comment on my opinion. However my opinion is still the same with Juan. If you want to generate a random vectors with fixed sum, each vector that randomly come out of the algorithm has different probability of being chosen. And yes, this file seems to work properly as long as you don't care to examine the probability of each vector coming out of the algorithm. Thank you Juan. You got my point. This problem cannot be solved without using estimations, by the way. This problem can only be solved by discretization of the domain and finding all possible solutions and define a single value for each one and then if you pick one by chance its probability is the same with any other solution (vector). However, it is a stupid solution (Time and Cost). Again, it depends on your purpose. If you just want to produce some vectors with fixed summation this algorithm is a good choice for you. But if you want to use it in an optimization algorithm it is waste of time. For there are some solutions that with the confidence interval of 99.99 % you cannot produce that solution with the algorithm. In other words, if you try infinite number of times to produce them it will happen once. This is a simple and obvious probability problem. See what Juan wrote for you.
juan (view profile)
I think this script is not working good, the histograms of the generated variables are nos uniform, you can easily see that with large m. on the other side, if the sum is very extreme (for example large sum) the distribution is even worst.
On the other side, i think this problem has no solution, based on a very simple calculus:
let x1 x2 and x3 be 3 random variables with U[0 1] distribution subjected to the constraint: x1+x2+x3=1, then:
E(x1+x2+x3)=E(x1)+E(x2)+E(x3)=E(1)=1
so, as x1, x2 and x3 are identically and independent, the conclution is that E(x1)=E(x2)=E(x3)=1/3.
Guillaume (view profile)
Great work!
I am trying to adapt this code so that it generates a vector with random values from the beta distribution.
It should, of course, remain possible to specify sum of the generated vector in advance.
Any suggestions? This is difficult for me.
J.E. Wong (view profile)
may i ask what if i want to produce random numbers with fixed sum following a Gaussian distribution but without limit on the intervals?
i have tried to put a=-inf and b=inf but it ends up with NaN. (may be becoz s = (s-n*a)/(b-a) produces inf/inf?). is the rand generated from this algorithm following Gaussian too? many thx!
John D'Errico (view profile)
I think Mohammad does not understand what this code does. In fact, it does work properly, and it does that job quite well and efficiently.
Besides, one should never just say simply that something does not work. Instead, show what you tried, and explain why you think it did not work. Then others can see either what you misunderstand about the code, or they can see why there may be a problem in the code. In this case, I happen to know the code does work as designed.
mohammad (view profile)
This Function does not work properly. I tried this file several times and I got histogram for the values. The probabilities of the random values are not the same. It may cause serious problem when you are trying to run an optimization problem. However, It is a good job!
vachelard (view profile)
Hi
I try to use the function, but I have a problem when I'm driving.
I have a matrix A (193.1) I would like to create a matrix (193.3) whose sum equals one line to my matrix A.
I tried the following code but I meet an error:
Rhedgefund = Y (:, 1);
cols_to_generate = 3;
for K = 1: length (Y)
Neva (K, :) = randfixedsum (1 cols_to_generate, Y (K), -0.15, 0.15);
end
He told me:
Index EXCEEDS matrix dimensions.
Error in randfixedsum (line 95)
x = (b-a) * x (p + repmat ([0: n: n * (m-1)] n, 1)) + a; % Switches & rescale x
95 x = (b-a) * x (p + repmat ([0: n: n * (m-1)] n, 1)) + a; % Switches & rescale x
I do not know how to solve problem
shatakshi sharma (view profile)
i am trying to generate 6 random nmbrs within given range and sum:
xmin=[10 10 40 35 130 125];
xmax=[125 150 250 210 325 315];
Pg=randfixedsum(1,6,200,xmin, xmax);
it is giving following error:
?? Error using ==> minus
Matrix dimensions must agree.
Error in ==> randfixedsum at 56
s1 = s - (k:-1:k-n+1); % s1 & s2 will never be negative
Error in ==> busdatas at 47
Qg=randfixedsum(30,1,total(8),xmin, xmax);
can sm1 tell wats wrong..i cnt figure it out..
Olga Petrik (view profile)
Matlab2010 (view profile)
excellent! well done
Matlab2010 (view profile)
excellent! well done
Christophe Lauwerys (view profile)
Nice. I'm trying to generate random data within a simplex defined by linear inequality constraints.
Lets say I already have the N vertices of the simplex defined by the inequalities. Is it then correct to first generate a random sample in the interval [0,1] with a sum equal to 1, and then take the inner product of this sample with the vector of vertices?
Something along the lines of:
X = rand(6,2);
k = convhull(X);
plot(X(k,1),X(k,2),'b'), hold on
nv = numel(k)-1; % Nmuber of vertices
X = X(k(1:end-1),:); % Remove repeated first vertex
L = randfixedsum(size(X,1),1000,1,0,1);
Y = L'*X;
plot(Y(:,1),Y(:,2),'r.'), hold off
Maybe I shouldn't trust my vision on this, but the samples don't really look uniformly spread within the simplex. For some reason they only seem to do for a triangle.
Any thoughts?
Thanks
Christophe
Bruno Luong (view profile)
Mate 2u (view profile)
Hi when i try to use the function on a very large a array it gives me the following error...
??? Maximum variable size allowed by the program is exceeded.
Error in ==> randfixedsum at 58
w = zeros(n,n+1); w(1,2) = realmax; % Scale for full 'double' range
Vassilios Vassiliadis (view profile)
Respect....
Florian (view profile)
Exactly what I was looking for!!! Many thanks for the great work!!!
Excellent!
very useful! beautiful code!
This took a bit of work to verify uniformity in a slice of an n-dimensional hypercube. I'm now confident that Roger has done what he claimed, having checked samplings in several different dimensions, as well as having thought through the process he used to generate the sampling.