-
Notifications
You must be signed in to change notification settings - Fork 3
/
randmask.m
66 lines (57 loc) · 2.14 KB
/
randmask.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
function [I J kk] = randmask(m, n, k, fencemax)
% FUNCTION [I J KK] = RANDMASK(M, N, K, FENCEMAX)
%
% This code is used only to generate random problem instances, not to solve
% problems.
%
% Random mask: we randomly select K entries in an M-by-N matrix and return
% their indices (row indices in I, column indices in J) in uint32 class.
% The code is based on the assumption that K << MN, that an MN vector does
% not fit in memory and that it is complicated to uniformly generate a
% single integer in the range 1:MN. The code will usually select K entries,
% but it sometimes abandons with slightly less than K. The number of
% selected entries is returned in KK.
%
% FENCEMAX is the maximum number of tries (a higher number increases the
% chance that we will get the correct number of samples in the mask, but
% increases computation time too).
%
% Nicolas Boumal, UCLouvain, Sept. 6, 2011.
% http://perso.uclouvain.be/nicolas.boumal/RTRMC/
if nargin < 4 || isempty(fencemax)
fencemax = 5;
end
% If m*n is unmanageable, do the random picking dance
if m*n > 1e7
pos = zeros(0, 2, 'uint32');
kk = 0;
fence = 1;
while kk < k
if fence > fencemax
warning('RTRMC:randmask', ...
['Could not select exactly k = %d entries; ' ...
'selected %d instead.\n'], k, kk);
break;
end
rows = randi(m, k-kk, 1, 'uint32');
cols = randi(n, k-kk, 1, 'uint32');
pos((kk+1):k, 1:2) = [rows, cols];
pos = unique(pos, 'rows');
kk = size(pos, 1);
fence = fence + 1;
end
I = pos(:, 1);
J = pos(:, 2);
% Otherwise, generate it explicitly
else
idx = uint32(randsample(m*n, k));
[I J] = ind2sub([m n], idx);
kk = length(I);
end
% Order the indices I and J properly (which weridly requires switching
% back to doubles ... Matlab, seriously, typing much?
M = sparse(double(I), double(J), ones(kk, 1), m, n, kk);
[I J] = find(M);
I = uint32(I);
J = uint32(J);
end