tags:

views:

286

answers:

4

What's the best way to generate a number X of random binary vectors of size N with concentration of 1s (or, simmetrically, of 0s) that spans from very low to very high?

Using randint or unidrnd (as in this question) will generate binary vectors with uniform distributions, which is not what I need in this case.

Any help appreciated!

+1  A: 

You could use bit-or operations on uniformly distributed binary vectors, I suspect the exact distributions you would end up with would be a little complicated though.

Autopulated
sounds like a good hunch - would I just randomly run OR operations between adjacent bits? I am happy out if I get a good number of high density rules (for both 1s and 0s), bit with an OR I would guess I'd get mostly 1s on a uniform distribution. I could run ORs on 1/3 of the population, ANDs on another third and leave the rest be? :)
JohnIdol
I was thinking bit-oring two independent uniform distributions, to, for example create a number with 75% 1s, (then you could bit-and with a third independent uniform to get 62.5% 1s, for example). You ought to be able to generate any density reasonably straight-forwardly using a sort of binary-search approach.If the original values aren't really uniformly distributed though this method might be quite unstable.
Autopulated
+2  A: 

I'm no expert on matlab but an approach that should be pretty simple to implement is generating vectors of floating point random numbers (preferably in the range 1 to 0) and then set values above a certain threshold to 1 and below to 0. Let's say you want 30% ones, you set all values above .7 to 1 and the ones below to 0.

Laserallan
the thing is that I'd like the distribution of high/low densities to be random as well across the population
JohnIdol
If you can express the distribution of the higher and lower as a function of x where x is the index of a specific element in the vector you can use that as the threshold for selecting whether the value at position x should be 1 or 0.
Laserallan
+4  A: 

Laserallan's approach is the way to go.

For a vector with 10 elements and 70% ones that are randomly distributed, you write

randVec = rand(10,1)<0.7;

EDIT If you want X vectors of length N, with increasing amount of ones, you write

thresVec = linspace(0,1,X);  %# thresholds go from 0 (all 0) to 1 (all 1)  
randVec = bsxfun(@lt,rand(N,X),threshVec); %# vectors are per column

Note that randVec is a logical array. Depending on what you want to do with it, you may want to convert it to double like so

randVec = double(randVec);
Jonas
the solution with increasing amount of 1s will do just fine Jonas - tnx for helping!
JohnIdol
+2  A: 

Using

rand(N,1)<p   %# 0 < p < 1

will give you a Nx1 vector with on average N*p ones in it (and other places will be zero) - but on some runs you might get a vector that is different than what you expect (it might have all zeros for example... might be a very low chance, but still non zeros chance).

If you want exactly A ones and B zeros, you can do this:

rand_vec = [ones(A, 1); zeros(B, 1)];
rand_vec = rand_vec(randperm(A+B));

Then you can set A and B to match your needs.

EDIT:
Now I understood your question better: Lets say you have a vector p which contains the wanted proportions of 1's in your population, N is the number of elements in each vector.

rand_mat = rand(N, size(p,2)) < repmat(p', [1,N])';

Will give you a Nx(size(p,2)) matrix where column i is a vector with p(i) ones (on average as explained above) and the rest is zeros.

Ofri Raviv

related questions