1function p = uperm(a) 2% Return all unique permutations of possibly-repeating array elements 3% ========================================================================= 4% Copyright (C) 2014 Bruno Luong <brunoluong@yahoo.com> 5% Copyright (C) 2020 Dynare Team 6% 7% This file is part of Dynare. 8% 9% Dynare is free software: you can redistribute it and/or modify 10% it under the terms of the GNU General Public License as published by 11% the Free Software Foundation, either version 3 of the License, or 12% (at your option) any later version. 13% 14% Dynare is distributed in the hope that it will be useful, 15% but WITHOUT ANY WARRANTY; without even the implied warranty of 16% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17% GNU General Public License for more details. 18% 19% You should have received a copy of the GNU General Public License 20% along with Dynare. If not, see <http://www.gnu.org/licenses/>. 21% ========================================================================= 22% Original author: Bruno Luong <brunoluong@yahoo.com>, April 20, 2014 23% https://groups.google.com/d/msg/comp.soft-sys.matlab/yQKVPTYrv6Q/gw1MzNd9sYkJ 24% https://stackoverflow.com/a/42810388 25 26[u, ~, J] = unique(a); 27p = u(up(J, length(a))); 28 29function p = up(J, n) 30ktab = histc(J,1:max(J)); 31l = n; 32p = zeros(1, n); 33s = 1; 34for i=1:length(ktab) 35 k = ktab(i); 36 c = nchoosek(1:l, k); 37 m = size(c,1); 38 [t, ~] = find(~p.'); 39 t = reshape(t, [], s); 40 c = t(c,:)'; 41 s = s*m; 42 r = repmat((1:s)',[1 k]); 43 q = accumarray([r(:) c(:)], i, [s n]); 44 p = repmat(p, [m 1]) + q; 45 l = l - k; 46end 47end 48 49end % uperm