, . x, y, x, (x | y)! , , . i, (x | y) :
x \ y 1 2 3 4
1 #1 #2 #3
2 #4 #5
3 #6
. (1 | 2) ↔ # 1 .. , , . , .
"" , :
x \ y 1 2 3 4
1 (#1) #2 #3 #4
2 (#5) (#6) #7 #8
3 (#9) (#10) (#11) #12
And skip those in parentheses when they are generated. Now mapping a function from index ito is (x | y)much simpler:
i = (x-1) * N + y
x = floor(i/N) + 1
y = i - (x-1)*N + 1
The disadvantage is that we can never be absolutely sure that we have enough samples on the desired side of the diagonal, so we must be prepared for this. However, the probability of this is quite small.
N = 6 % maximal x and y
S = 10 % number of samples to draw
ind = [];
% This loop will most likely run only once,
% but we can not be completely sure
while size(ind, 1) < S
% (*)
% In order to test uniformity of distribution, we can
% generate some repeating data instead of the next line:
% i = ceil(N*N .* rand(3*S, 1));
% We generate 3*S > S samples, because at least 50% will be removed
i = randsample(N*N, min(N*N, 3*S));
x = floor(i/N) + 1;
y = i - x*N + N + 1;
remove = (x >= y);
x(remove, :) = [];
y(remove, :) = [];
ind = [x y];
end
ind = ind(1:S, :);
% verify:
test = accumarray(ind, ones(S,1))
This may cause
ind =
2 6
3 4
1 4
3 6
5 6
2 3
1 6
3 5
4 6
1 5
test =
0 0 0 1 1 1
0 0 1 0 0 1
0 0 0 1 1 1
0 0 0 0 0 1
0 0 0 0 0 1
And a uniformity test for S = 10000:
test =
0 671 716 686 691 664
0 0 644 650 667 664
0 0 0 672 649 654
0 0 0 0 667 655
0 0 0 0 0 650