-
Notifications
You must be signed in to change notification settings - Fork 1
/
randomize.m
148 lines (120 loc) · 3.62 KB
/
randomize.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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
function [M,I] = randomize(M, varargin )
%RANDOMIZE randomize a matrix
%
% m=RANDOMIZE(m) randomize the values in matrix m along the first
% dimension.
%
% m=RANDOMIZE(m,dim) randomize along the specified dimension(s). If a
% vector of dimensions is given, the matrix is randomized along each
% of these dimensions.
%
% m=RANDOMIZE(m,dim,groupdim) dimensions listed in the vector groupdim
% are randomized together along the specified dimension(s) dim.
%
% m=RANDOMIZE(m,...,param1,val1,...) specifies optional parameters.
% method - shake/cycle randomizes by cycling or shaking along a
% given dimension. Only one dimension dim is allowed for the
% cycle method.
% adjust - none/mean/max adjust the mean/max of grouped dimensions.
% seed - seed for randomization
%
% [m,i]=RANDOMIZE(...) also returns the (linear) indexes of the
% randomized matrix into the original matrix.
%
% Examples
% m = [1 5
% 3 2
% 6 4];
% randomize(m) %randomize along the row dimension, possible
% %output: [3 5
% % 6 4
% % 1 2]
% randomize(m,2) %randomize along the column dimension, possible
% %output: [5 1
% % 2 3
% % 4 6]
% randomize(m,1,2) %randomize along the row dimension, but keeping
% %values together in the column dimension, possible
% %output: [6 4
% % 1 5
% % 3 2]
%
% Copyright 2007-2008 Fabian Kloosterman
options = struct( 'method', 'shake', 'adjust', 'none', 'seed', []);
[options,other]=parseArgs(varargin,options);
if nargin<1
help(mfilename)
return
end
dim = 1;
groupdim = [];
if ~isempty(other)
nargs = numel(other);
if nargs>0 && ~isempty(other{1})
dim = other{1};
end
if nargs>1
groupdim = other{2};
end
end
if strcmp( options.method, 'cycle' ) && numel(dim)>1
error('randomize:invalidArgument', ['Cycle method only supports one ' ...
'randomization dimension'])
end
oldseed = [];
if ~isempty(options.seed)
oldseed = rand('seed'); %#ok
rand('seed',options.seed); %#ok
end
try
N = numel(M);
nd = ndims(M);
otherdim = setdiff( 1:nd, [dim groupdim] );
if ~all(ismember( dim, 1:nd )) || ~all(ismember( groupdim, 1:nd )) || ...
~isempty( intersect( dim, groupdim ) )
error( 'randomize:invalidArgument', 'Invalid dim or groupdim arguments')
end
sz = size( M );
I = reshape( 1:N, sz );
dx = prod(sz(dim));
dy = prod(sz(otherdim));
dz = prod(sz(groupdim));
I = reshape( permute( I, [dim otherdim groupdim] ), [dx dy dz] );
if numel(groupdim)>=1
switch options.adjust
case 'mean'
adjust_factor = nanmean( M(I),3 );
case 'max'
adjust_factor = nanmax( M(I),[],3 );
end
end
[row_i, col_i, plane_i] = ndgrid( 1:dx, 1:dy, 1:dz );
switch options.method
case 'cycle'
row_i = randcycle( row_i(:,:,1) );
otherwise
[row_i,row_i] = sort(rand([dx dy]),1);
end
row_i = repmat( row_i, [1 1 dz] );
I = I( sub2ind( [dx dy dz], row_i, col_i, plane_i ) );
if numel(groupdim)>=1
switch options.adjust
case 'mean'
adjust_factor = adjust_factor./nanmean( M(I),3 );
M(I) = bsxfun(@times, M(I), adjust_factor );
case 'max'
adjust_factor = adjust_factor./nanmax( M(I),[],3 );
M(I) = bsxfun(@times, M(I), adjust_factor );
end
end
I = ipermute( reshape( I, sz([dim otherdim groupdim]) ), [dim otherdim groupdim] );
M = M(I);
if ~isempty(oldseed)
rand('seed', oldseed); %#ok
end
catch ME
if ~isempty(oldseed)
rand('seed', oldseed); %#ok
end
rethrow(ME);
end