Generate matrix based on row probability

how can i generate the matrix below?

given matrix 
1 1 1

2 2 2

3 3 3

and probability that row is selected

1 1 1 = 50%

2 2 2 = 25%

3 3 3 = 25%

generate matrix 

1 1 1

1 1 1

2 2 2

3 3 3

H Ben,

You could map the probabilities to a cumulative density function and draw a uniform variable to get your index, then append the original matrix

m:(1 1 1;2 2 2;3 3 3)

probs:.5 .25 .25

m@sums[0f, probs] bin 1?1f

The distribution can be verified using

q)count each group sums[0f, probs] bin 10000?1f
0| 5044
1| 2494
2| 2462

Hey Ben,

Not sure to how many decimals your probabilities can be but you have some control over your result here. Larger matrix returned can give more accuracy but if not necessary you can negate by increasing prc.

q)prb:.5 .25 .25

q)mtx:(1 1 1;2 2 2;3 3 3)

q)

q)res:raze{cnt;row;prc#enlist row}[;;.01]'[prb;mtx]

q)count each group res

1 1 1| 50

2 2 2| 25

3 3 3| 25

q)

q)res:raze{cnt;row;prc#enlist row}[;;.25]'[prb;mtx]

q)res

1 1 1

1 1 1

2 2 2

3 3 3

Another possible approach:

q)m where"j"$p%min p
1 1 1
1 1 1
2 2 2
3 3 3

Terry

Apologies, ignore my previous response, I misinterpreted the question…

Generating the counts is the trickiest part. To generate the counts based on probability, you need to normalize the probabilities to whole number counts by repeatedly multiplying by 10, and then divide these counts by the greatest common divisor of the counts in order to have the smallest counts possible where the probabilities still apply.

q)m:(1 1 1;2 2 2;3 3 3)
q)p:.5 .25 .25

q)c:“j”${a:x-floor x;$[all 0=a;x;x*10]}/[p] //convert probabilities to whole numbers, .5 .25 .25 -> 50 25 25

q)c:“j”$c%{$[y=0;x;.z.s[y;x mod y]]}/[c] // get gcd of counts, divide counts by gcd to get smallest counts, 50 25 25 -> 2 1 1

q)raze c{x#enlist y}'m

putting it all inside a function:

genMx:{[m;p]

    c:“j”${a:x-floor x;$[all 0=a;x;x*10]}/[p];

    c:“j”$c%{$[y=0;x;.z.s[y;x mod y]]}/[c];

    raze c{x#enlist y}'m

 }

q)genMx[(1 1 1;2 2 2;3 3 3);.5 .25 .25]

1 1 1

1 1 1

2 2 2

3 3 3

q)genMx[(1 1 1;2 2 2;3 3 3);.3 .4 .3]

1 1 1

1 1 1

1 1 1

2 2 2

2 2 2

2 2 2

2 2 2

3 3 3

3 3 3

3 3 3

q)count genMx[(1 1 1;2 2 2;3 3 3);.31 .39 .3]

100