-
Notifications
You must be signed in to change notification settings - Fork 2
/
allcomb.m
87 lines (80 loc) · 2.56 KB
/
allcomb.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
function A = allcomb(varargin)
% ALLCOMB - All combinations
% B = ALLCOMB(A1,A2,A3,...,AN) returns all combinations of the elements
% in A1, A2, ..., and AN. B is P-by-N matrix is which P is the product
% of the number of elements of the N inputs.
% Empty inputs yields an empty matrix B of size 0-by-N. Note that
% previous versions (1.x) simply ignored empty inputs.
%
% Example:
% allcomb([1 3 5],[-3 8],[0 1]) ;
% 1 -3 0
% 1 -3 1
% 1 8 0
% ...
% 5 -3 1
% 5 8 0
% 5 8 1
%
% ALLCOMB(A1,..AN,'matlab') causes the first column to change fastest.
% This is more consistent with matlab indexing. Example:
% allcomb(1:2,3:4,5:6,'matlab') %->
% 1 3 5
% 2 3 5
% 1 4 5
% ...
% 2 4 6
%
% This functionality is also known as the cartesian product.
%
% See also NCHOOSEK, PERMS,
% and COMBN (Matlab Central FEX)
% for Matlab R13+
% version 2.1 (feb 2011)
% (c) Jos van der Geest
% email: [email protected]
% History
% 1.1 (feb 2006), removed minor bug when entering empty cell arrays;
% added option to let the first input run fastest (suggestion by JD)
% 1.2 (jan 2010), using ii as an index on the left-hand for the multiple
% output by NDGRID. Thanks to Jan Simon, for showing this little trick
% 2.0 (dec 2010). Bruno Luong convinced me that an empty input should
% return an empty output.
% 2.1 (feb 2011). A cell as input argument caused the check on the last
% argument (specifying the order) to crash.
error(nargchk(1,Inf,nargin)) ;
% check for empty inputs
q = ~cellfun('isempty',varargin) ;
if any(~q),
warning('ALLCOMB:EmptyInput','Empty inputs result in an empty output.') ;
A = zeros(0,nargin) ;
else
ni = sum(q) ;
argn = varargin{end} ;
ischar(argn)
if ischar(argn) && (strcmpi(argn,'matlab') || strcmpi(argn,'john')),
% based on a suggestion by JD on the FEX
ni = ni-1 ;
ii = 1:ni ;
q(end) = 0 ;
else
% enter arguments backwards, so last one (AN) is changing fastest
ii = ni:-1:1 ;
end
if ni==0,
A = [] ;
else
args = varargin(q) ;
if ~all(cellfun('isclass',args,'double')),
error('All arguments should be arrays of doubles') ;
end
if ni==1,
A = args{1}(:) ;
else
% flip using ii if last column is changing fastest
[A{ii}] = ndgrid(args{ii}) ;
% concatenate
A = reshape(cat(ni+1,A{:}),[],ni) ;
end
end
end